Picolet
Compile a Python program into a small self-contained native executable. Like PyInstaller, but the binary is hundreds of kilobytes rather than tens of megabytes, starts in milliseconds, and has no runtime Python dependency on the host.
The shape of it
A Picolet binary is one file. Inside:
- A trimmed MicroPython interpreter (~410–650 KB depending on renderer).
- Your application's
.pycode, compiled to bytecode and frozen into the binary. - Optional bundled assets (HTML, fonts, images, schemas) as a read-only ROM filesystem appended to the executable.
- Optionally: a GUI renderer (system webview or native LVGL) for HTML/JS or native UIs.
The result runs on any matching-OS/arch machine without installing Python.
Three ways to use it
1. Bundle a single CLI script
The simplest case:
picolet build hello.py
./hello # Linux ≈ 647 KB
./hello.exe # Windows ≈ 409 KB
hello.py becomes a self-contained executable. Sub-second startup. No python interpreter needed on the host machine. Roughly 20–50× smaller than the equivalent PyInstaller bundle, with no first-launch unpacking delay.
2. Manifest-driven build
For multi-module apps, drive the build from a MicroPython manifest.py:
# manifest.py
require("argparse") # frozen micropython-lib module
require("typing")
freeze("./src", "main.py") # your entry
freeze("./src/lib", "utils.py") # additional modules
freeze("./src/lib", "data_model.py")
picolet build --manifest manifest.py
The manifest is the canonical MicroPython mechanism for declaring what's frozen into a build. Picolet uses it directly — everything declared is included.
Medium-term: romfs contents (HTML, fonts, etc.) declared in the same manifest, per upstream evolution.
3. GUI application
Add a picolet.toml to pick a renderer and bundle UI assets:
[app]
name = "my-app"
entry = "src/main.py"
[ui]
renderer = "webview" # or "lvgl" for native
root = "ui"
[window]
title = "My App"
size = [900, 600]
[romfs]
include = ["ui", "assets"]
picolet build
For Vue or other JS framework frontends:
[ui.frontend]
framework = "vue" # builds Vite output into romfs automatically
The IPC bridge is set up automatically:
// JS side
await window.picolet.invoke('list_items', { filter: 'active' });
window.picolet.on('progress', e => bar.update(e.pct));
# Python side
@picolet.command
async def list_items(args):
return [...]
Four worked examples under examples/ (pydfu, notes, config-editor, dashboard) demonstrate the patterns end-to-end, each with a distinct visual aesthetic.
Caveats
Read these before adopting.
-
MicroPython, not CPython. The standard library subset is smaller. Pure-Python code using
os,sys,json,re,time,asyncio,struct,ioetc. typically works. Code that depends on C extensions (numpy, pandas, Pillow, lxml, etc.) does not. Picolet cannot make a CPython library "just work" — it would have to be ported or replaced with a MicroPython equivalent. -
micropython-libfills most stdlib gaps. Modules likeargparse,pathlib,dataclasses,typing,unittestare available via micropython-lib and are declared withrequire("name")in the manifest. -
Custom C modules are straightforward. A Picolet binary is a MicroPython build under the hood, so any C module written against the standard MicroPython API works. Drop a directory under
user_c_modules/and reference it in the manifest. Once upstream PR #18229 lands in the fork,c_module("./path/to/mymodule")can declare it directly in the manifest. -
Python C-API extensions (CPython
.so/.pyd) do NOT work. MicroPython's runtime is binary-incompatible with CPython. Write a MicroPython C module instead. -
Async semantics differ slightly. MicroPython's
asynciois a subset of CPython's. Coroutines, tasks, queues, locks,gather,wait_forwork;asyncio.runwith policies, debug mode, theloop.add_signal_handlerinterface, and some niche APIs don't. Most app code is unaffected. -
First-class platform support is Linux x64 and Windows x64. macOS (Intel + Apple Silicon) is source-complete but requires GitHub Actions CI for native builds — local cross-compile from Linux is not supported. ARM Linux and mobile platforms are on the backlog.
See docs/caveats.md for a full catalogue.
Toolchain expectations
- The
picoletCLI runs on Linux, macOS, or Windows (host). - Building Windows binaries from Linux uses
dockcross; Docker is required for that path. - Building macOS binaries uses GitHub Actions runners (
macos-13Intel,macos-14Apple Silicon). - Node.js + npm are required only when building Vue/React frontends.
Getting started
Install the CLI. uv tool install is the recommended path (no separate
package manager needed if you already use uv); pipx is the fallback
for environments without uv. Plain pip install is deliberately not
listed — most modern distros (PEP 668) block it system-wide.
uv tool install picolet-cli # recommended
# or:
pipx install picolet-cli # fallback
picolet init my-app --template hello-cli # see --list-templates for the full set
cd my-app
picolet dev # live rebuild on file changes
picolet build # produce target/<os-arch>/my-app[.exe]
Templates: hello-cli, hello-webview, hello-lvgl, hello-vue, pydfu, notes, config-editor, dashboard.
Examples gallery
See docs/examples.md for a longer tour of each.
Renderers
| Renderer | Backed by | Use case | Binary size (typical) |
|---|---|---|---|
| (none) | — | CLI tool, no UI | ~647 KB Linux / ~409 KB Windows |
webview |
WebKitGTK 4.1 (Linux), WebView2 (Windows), WKWebView (macOS) | HTML/CSS/JS frontend | ~710 KB Linux / ~525 KB Windows |
lvgl |
lv_binding_micropython + SDL2 |
Native widgets, zero system UI deps | ~1.84 MB Linux / ~2.05 MB Windows |
Repository layout
picolet/
├── packages/
│ ├── picolet-cli/ # picolet init|dev|build|run|test
│ ├── picolet-runtime/ # the MicroPython runtime + variants + user_c_modules
│ ├── picolet-bridge-js/ # JS shim: window.picolet.invoke(...)
│ ├── picolet-templates/ # `picolet init --template <name>` starter packs
│ └── picolet-testing/ # AppHarness for autonomous test/screenshot
├── examples/ # four worked example apps
├── tests/ # per-phase test suites
└── docs/ # architecture, caveats, examples, CLI reference
More
- Getting started — step-by-step tutorial
manifest.pyguide — declaring frozen modules +require()frommicropython-liband community packages- Architecture — design decisions
- Caveats — MicroPython compatibility reference
- Examples tour — what each example app demonstrates
- CLI reference — every
picoletsubcommand - SBOM — supply-chain documentation
- History — phase artefacts and version-specific specs/plans/audits
License
MIT throughout. See LICENSE.
Metadata
Release files for picolet 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| picolet-0.0.1.tar.gz | 1.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| picolet-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 3.3 MB
Release files / picolet-0.0.1.tar.gz
| Download URL | picolet-0.0.1.tar.gz |
|---|---|
| Size | 1.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7af4876738ec31f38ae6959e34530dfe09ad1ae793a444d08ec1d7965833ea7d
|
|
BLAKE2b-256 checksum How to use checksums |
100accbd82af553ac9c33f5b40941f012f9c6f845aafd24d2873bc4180b25ccd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency logRelease files / picolet-0.0.1-py3-none-any.whl
| Download URL | picolet-0.0.1-py3-none-any.whl |
|---|---|
| Size | 1.7 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6e1eeaa982bd4f36de7c8c313b390323d42dcab6a39c2b5959d06f724956fe67
|
|
BLAKE2b-256 checksum How to use checksums |
33ce28f3b21d368240a7f4d0f07f0f141ac774fdd89c0ae5ce50b04190011c01
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jun 2, 2026.
Transparency log