Skip to main content

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 .py code, 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, io etc. 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-lib fills most stdlib gaps. Modules like argparse, pathlib, dataclasses, typing, unittest are available via micropython-lib and are declared with require("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 asyncio is a subset of CPython's. Coroutines, tasks, queues, locks, gather, wait_for work; asyncio.run with policies, debug mode, the loop.add_signal_handler interface, 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 picolet CLI 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-13 Intel, macos-14 Apple 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

pydfu screenshot
pydfu
DFU firmware flasher (industrial control-panel aesthetic)
notes screenshot
notes
Markdown notes (editorial / refined)
config-editor screenshot
config-editor
Schema-driven TOML/YAML/JSON editor (brutalist terminal)
dashboard screenshot
dashboard
Live system metrics (data-dense)

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

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)

Source distribution for picolet 0.0.1
File Size Uploaded
picolet-0.0.1.tar.gz 1.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for picolet 0.0.1
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page