Library / SDK
adafruit/Adafruit_CircuitPython_Bundle avatar
adafruit/Adafruit_CircuitPython_Bundle

Adafruit CircuitPython Bundle: one zip that fills a board's lib folder

A bundle of useful CircuitPython libraries ready to use from the filesystem.

1,008 stars204 forksShellMIT

At a glance

What is it?
Adafruit's CircuitPython Bundle is a packaging pipeline, not a library: it assembles many driver and helper modules into a single downloadable zip that can be dropped onto a microcontroller's filesystem. It works well for board vendors and image builders, and it is explicitly the wrong tool for a Linux Python setup.
Who is it for?
Adopt the bundle if you build factory images for CircuitPython boards or want a known-good driver set on a device, and skip it if you run the libraries under CPython on a Raspberry Pi, where pip3 is the documented path.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A packaging artifact rather than a library

The first thing to clear up is that nothing here is importable as a Python package. Adafruit describes the repository as a bundle that ships "a bunch of useful CircuitPython libraries into an easy to download zip file", and the stated purpose is that CircuitPython boards can ship with the contents of that zip so a lot of libraries are available by default. The deliverable is a file you copy onto hardware, not a dependency resolver.

That distinction drives everything else. There is no setup.py, no console entry point, and nothing to add to a requirements file. The repository itself is mostly shell and packaging glue, with the actual driver code living in submodules under the libraries directory. Its top level also carries a library list and a PyPI statistics file, plus an add_import_names.py helper and a pre-commit configuration, which tells you the interesting work happens before a build, not after one.

Copying lib onto the device root, merged with what is there

Usage is a manual file operation. The README says to download the zip, explicitly not the source zip, from the latest release page, unzip it, and copy the subfolders such as lib over to the root of the CircuitPython device. One detail matters more than the rest: if the target folder already exists on the device, you have to indicate that the copy should be merged with it rather than replacing it.

A CircuitPython device exposes its storage as a mountable filesystem with a small root, and lib is where modules are discovered at import time. Overwriting that folder would discard the modules the board already carries, and merged behaviour is what the instructions ask for. The bundle therefore works as an overlay on a factory image rather than a replacement for one. Note that the README describes no checksum, version marker, or rollback step for that overlay, so an engineer's real upgrade question is answered by what the board image already provides.

Why pip3 on a Raspberry Pi is the documented alternative

The most emphatic rule in the README concerns CPython: do not use this bundle to install libraries on a Linux computer such as a Raspberry Pi running regular Python. The guidance is to use pip3 instead, because it installs dependencies automatically. The example given is a single accelerometer driver.

bash
pip3 install adafruit-circuitpython-lis3dh

The contrast is the whole design in one line. The zip assumes a target with a tiny filesystem and no package index, so it flattens every dependency into one archive and leaves dependency resolution to the board image builder. pip3 does the opposite: it resolves the dependency graph at install time and touches only the site-packages of the host. Using the bundle on a Linux host would mean hand-placing files and losing pip's dependency handling, which is precisely what the README warns against. Treat the zip as a device payload and pip3 as a host workflow.

Submodules pinned to tags, and the script that updates them

The source of truth for the bundle is a set of git submodules. After cloning, the README requires two commands before anything else works.

bash
git submodule init
git submodule update

Library directories are then refreshed with update-submodules.sh, which fetches the latest code and moves each submodule to the newest tag, and the README is emphatic that this is not main. That tag-based behaviour is what makes a bundle build reproducible: a driver cut from a moving branch would change the content of what is called the same release. Individual library work is handled in LIBRARY_DEVELOPMENT.rst.

For finding out what has moved since a release, the README offers a submodule foreach query over the upstream main branch.

bash
git submodule foreach "git log --oneline HEAD...origin/main"

Read that as a triage tool, not an upgrade path. It lists commits that exist upstream but have not been folded into a release, which is what you run to decide whether a new bundle is worth pulling.

The local build depends on circuitpython-build-tools

Building a bundle yourself requires the circuitpython-build-tools package, and the README sets up an isolated virtual environment for it before running the build command. The two activation steps are shown separately in the documentation, with an explicit reminder to make sure you are inside the environment before building.

bash
python3 -m venv .venv
source .venv/bin/activate
pip install circuitpython-build-tools
bash
source .venv/bin/activate

The build itself is a single command with three named parameters: a filename prefix of adafruit-circuitpython-bundle, a library location of libraries, and a library depth of 2. The depth value is what makes the layout work, since the library tree is two levels deep with drivers and helpers as the top split. The repository requirements file also lists Sphinx and sphinx-rtd-theme, which are documentation dependencies rather than build ones.

One constraint deserves attention: this path is for producing a bundle, not for consuming one. A user who only needs the drivers on a device downloads the release zip and stops there, and never needs the toolchain or a checkout at all.

Adding and removing modules under libraries

Contributors add a library by first deciding where it belongs. The README names two destinations, libraries/drivers and libraries/helpers, and asks that the target directory omit CircuitPython specific prefixes such as adafruit-circuitpython so the listing stays readable.

bash
git submodule add <git url> libraries/<target directory>

Removal is gated by a policy rather than a technical one. The README says to remove a library only if you are replacing the module with an equivalent, and gives two commands, deinit followed by a git rm of the target directory.

bash
git submodule deinit libraries/<target directory>
git rm libraries/<target directory>

The replacement requirement has a reason that is visible in the layout: a board image that silently loses a driver it used to ship will fail at import time on hardware, and unlike a host install there is no pip to reinstall it. A bundle is a flattened dependency set, so removing an entry removes the module for every downstream image at once.

Automatic weekly releases and a permissive licence

The recent release history is entirely machine generated. The tags 20261015, 20261010 and 20261003 all carry auto-release labels and timestamps that fall shortly after 05:20 UTC on their respective dates, which points to a scheduled job rather than a hand-cut release. The last push was on 2026-10-19, so the repository is not archived and the work is current rather than a frozen snapshot.

That cadence has a direct consequence for anyone tracking a specific driver. Because the bundle version is a date stamp and not a semantic version, you cannot ask what changed between two bundles by comparing numbers, and the release notes are the only way to see which submodule moves were picked up. The tag-versus-main rule for update-submodules.sh exists to keep that mapping readable.

The repository is MIT licensed, and the README and the library list both carry explicit licence sidecar files. Adafruit's libraries typically ship under permissive terms as well, though each included library keeps its own licensing, so a product team shipping a bundle should check the licence of the individual modules it includes rather than relying on the bundle's MIT designation alone.

Editorial conclusion

Adopt the bundle if you build factory images for CircuitPython boards or want a known-good driver set on a device, and skip it if you run the libraries under CPython on a Raspberry Pi, where pip3 is the documented path. Before relying on it, check the release you download against the release notes for your drivers, and confirm that update-submodules.sh points the submodules at the newest tag rather than the main branch, since the README states it updates to a tag, not to main.

Frequently asked questions

How do I install the Adafruit CircuitPython Bundle on a board?

Download the zip from the latest release page, unzip it, and copy the subfolders such as lib into the root of your CircuitPython device, choosing to merge with the existing folder when one is already there.

Can I install the Adafruit CircuitPython Bundle with pip on a Raspberry Pi?

No. The README says in bold not to use the bundle to install libraries on a Linux computer running regular Python, and to use pip3 instead, for example pip3 install adafruit-circuitpython-lis3dh, since pip handles dependencies automatically.

How do I update the libraries inside the Adafruit CircuitPython Bundle?

Run update-submodules.sh, which fetches the latest code and updates each submodule to the newest tag rather than to main.

What must I do after cloning the Adafruit CircuitPython Bundle repository?

Run git submodule init and then git submodule update, since the library code lives in submodules that are not populated by a plain clone.

How is a bundle built locally?

Install the circuitpython-build-tools package in a virtual environment, activate it, then run circuitpython-build-bundles with the filename prefix, library location and library depth arguments shown in the README.

Official sources

  1. adafruit/Adafruit_CircuitPython_Bundle on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/adafruit-adafruit-circuitpython-bundle.svg)](https://hysenlabs.com/projects/adafruit-adafruit-circuitpython-bundle)

Was this useful?