Package and project manager for MicroPython and CircuitPython
Project description
Minny
Package and project manager for MicroPython and CircuitPython
What is Minny?
Minny is like uv or Poetry for MicroPython and CircuitPython projects—it enables managing your project's development and runtime environment in a declarative way.
Note: Minny's main features are useful only if you keep your project in a local folder on your development machine. You don't need it when you edit files directly on the device, but keep reading—maybe you'll start liking the local-first workflow!
Declarative
Uploading your files with mpremote or installing dependencies with Circup is straightforward, but it may become tedious if you need to reproduce the same setup on another board (or on the same board after upgrading its firmware).
With Minny, you write down your dependencies and deployment rules in pyproject.toml once, and let the tool take care of setting up the device.
Here is a sample configuration for a MicroPython app:
[tool.minny.dependencies]
mip = [
"logging",
"github:jimmo/micropython-mlx90640",
"-e ../pfx-330-c" # an editable local project
]
[[tool.minny.deploy.files]]
source = "src"
destination = "/flash"
include = ["**/*.py", "configuration.json"]
compile = "auto" # compiles all .py files on the fly except main.py and boot.py
# no need to mention deploying dependencies—these will be copied over by default
Here's another example for a CircuitPython app:
[tool.minny.dependencies]
pip = [
"adafruit-circuitpython-charlcd~=2.2.0",
"adafruit-circuitpython-logging",
"-e ../my-shared-circuitpython-library",
]
circup = ["multi_keypad"]
# [[tool.minny.deploy.files]] block not needed because of useful defaults,
# but we want to skip some transitive dependencies that are not required at runtime:
[[tool.minny.deploy.packages]]
exclude = ["adafruit-circuitpython-typing", "typing-extensions"]
Note: If you are creating a MicroPython or CircuitPython package (not an app), then you may not even need
tool.minnysettings—Minny will pick up your package dependencies fromproject.dependenciesor fromdepsin MicroPython's package.json'.
Development environment
Local copies of dependencies
When your project has dependencies, you want your IDE and type-checker to know about them so you can get full support for code completion and type checking. Minny helps by making dependencies available locally.
Once you have your dependencies declared in pyproject.toml, you would run:
> minny sync
This makes Minny download and install all dependencies into the lib subfolder of your project (just like uv sync creates or updates the .venv folder).
Now you have a folder of .py files, which you can feed to your type-checker or IDE's language server. For example, if you're using Basedpyright, you would configure it like this:
[tool.basedpyright]
...
extraPaths = ["lib"]
...
Besides code completion and type-checking, your IDE should now allow you to Ctrl-click or Command-click from a library function call to its implementation so you can investigate the source code when the documentation is lacking.
Note: If you choose to keep the lib folder under version control, you'll have solid dependency locking in place. If you don't need this, feel free to add the folder to .gitignore and let Minny create and populate it each time someone clones the project and starts working on it.
Type stubs
Type stubs are another way to support your IDE or type checker. See the documentation for more information.
Minny supports making type stubs and custom typesheds easily available for type-checkers and language servers. Here's an example pyproject.toml that makes minny sync download and install a custom typeshed to the project's "typeshed" folder and Pimoroni Pico MicroPython Stubs to the "typings" folder, and configures Basedpyright to consult these folders:
...
[dependency-groups]
typeshed = ["micropython-typeshed~=0.1.*"]
typings = ["pimoroni-pico-stubs==1.21.0"]
[tool.basedpyright]
typeshedPath = "typeshed"
stubPath = "typings" # this is actually the default value, so I could have omitted this line
...
Note: Just like with the "lib" folder, you don't need to keep the "typeshed" and "typings" folders under version control—Minny has enough information to recreate them when required.
More about type stubs
TODO: move this to documentation
These are *.pyi files containing typing information for modules lacking embedded typing annotations (for example, modules in the MicroPython and CircuitPython standard libraries).
Type stubs for MicroPython and CircuitPython are usually published at Python Package Index as pip-compatible distribution packages. See https://micropython-stubs.readthedocs.io/en/main/ and https://pypi.org/project/circuitpython-stubs/
If your type-checker or language server picks up type stubs automatically from .venv, you may want to skip Minny's support and add stub packages to the "dev" dependency group and sync your .venv with uv sync.
Editable dependencies
For local development, you often need to work with packages that are not yet published or are under active development. Minny supports editable dependencies using the same -e syntax as pip's requirements.txt files:
[tool.minny.dependencies]
pip = [
"published-package>=1.0.0",
"-e ../my-local-library", # Relative path
"-e /absolute/path/to/package" # Absolute path
]
mip = [
# You can specify a "public name" to your local package.
# This allows overriding a transitive dependency with the same name.
"-e github:mphacker75/pfx-330-c@../pfx-330-c"
]
When you run minny sync, editable dependencies are represented in lib by metadata and special marker files, which point to the location of the modules under their project directory.
Editable dependencies are particularly useful when:
- Developing multiple related packages simultaneously
- Contributing to open-source libraries used by your project
- Working with experimental or unreleased versions of dependencies
Note: The current package (in case your project represents a package (not an app) always gets installed to lib in editable mode.
Runtime environment
Once you're ready to test your code, plug in a device and execute something like this:
minny --port COM4 deploy
Under the hood, this command performs the following steps:
- Perform a
minny syncto make sure the lib folder is in sync with your project specification. - Transfer all dependencies to your device's
libfolder. By default, Minny compiles .py files to .mpy files on the fly. - If the project represents a package, build it and transfer the files to the
libfolder, just like the dependencies. - Copy the main files (e.g., main.py, code.py, boot.py, and helper modules) to the device's main folder, according to the deploy rules specified in pyproject.toml.
Now you can press Ctrl-D on your device and test your program. If you're not satisfied, edit some files and invoke the same command again—this time it will be faster as only changed files need to be updated on the device.
Alternatively, you can execute following command:
minny --port COM4 run my-test.py
This would be like deploy followed by sending the contents of my-test.py to the REPL, except that main.py would not be updated on the board.
Lower-level commands
If you prefer to manage your dependencies manually, you can use Minny's lower-level commands for installing, uninstalling, and listing. Some examples:
minny --port COM4 mip install loggingminny --port /dev/ttyACM0 pip install micropython-loggingminny --mount G:\lib pip install adafruit-circuitpython-ssd1306minny --dir my_project/dependencies circup install multi_keypadminny --port COM5 pip uninstall micropython-logging micropython-oledminny --port COM5 mip list --outdated
Note: Minny does not use vanilla pip, mip, or circup. See the documentation for more information.
Minny and Thonny
Minny powers MicroPython and CircuitPython support in Thonny since version 5.0, so if you click the run button while having selected a Minny back-end, Thonny will invoke minny run behind the scenes.
Project Status
Current Version: 0.1.0a1 (Alpha)
Status: Core functionality implemented, active development
Contributing
Contributions are welcome. See CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file minny-0.0.1a1.tar.gz.
File metadata
- Download URL: minny-0.0.1a1.tar.gz
- Upload date:
- Size: 56.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9614520ae97601c1c6f3931477f31dd62dfcd22ce49e1561632b95f48700e381
|
|
| MD5 |
1ee04c6d896251b11689af96466785ec
|
|
| BLAKE2b-256 |
2525a18de650d3cc3446d4c0cde0d502a19aa3cb21fc382f2b8bf38943d09ec8
|
File details
Details for the file minny-0.0.1a1-py3-none-any.whl.
File metadata
- Download URL: minny-0.0.1a1-py3-none-any.whl
- Upload date:
- Size: 64.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b07fbdc9386e47c033a1c1d473ee2602da1a149cc5e0fc3e356707fbd4875269
|
|
| MD5 |
01388e0cba2fa9d232d0a4d040a89126
|
|
| BLAKE2b-256 |
cfadff7c25e026e8d4a1a56c813f8d52d34a94b3410fb5d0e8c3c4440413629a
|