m0
Preview. Write a web application in Mojo on the mojo-http framework: an HTTP/1.1 server, a router and views, HTML fragments for htmx and Datastar, Server-Sent Events, SQLite and PostgreSQL bindings that open their library at run time, and a host that runs the lot as one binary with no interpreter in it.
This wheel carries the framework's source and a small CLI that builds against it. It is pure Python and installs anywhere; the toolchain it drives runs on macOS arm64 and glibc Linux (x86-64, aarch64).
uvx m0 new shop # writes ./shop; needs no toolchain and no network
cd shop && uv sync # the pair it pinned: m0, and the one exact mojo it is gated on
uv run m0 build # src/server.mojo -> bin/server, about ten seconds
uv run m0 test # mojo run over test/test_*.mojo, two to four seconds a file
uv run m0 dev -- --port 8080 # build, serve, rebuild on save; the old server serves until a build succeeds
uv run m0 doctor # the toolchain checks, then bin/server's own --doctor
uv run m0 image # docker build of deploy/Dockerfile, then the image's about.json
uv run m0 include # where the framework's source is: read it
| command | what it does |
|---|---|
m0 new NAME [--template views|live|auth] |
Writes an application into ./NAME: src/, test/, a pyproject.toml pinning mojo and m0 exactly, AGENTS.md, smoke.sh, deploy/. views (the default) is a server-rendered list swapped by htmx 4; live is a producer pushing state to every tab over SSE, with Datastar; auth is the views list behind a login — a signed session and a CSRF token on every write — and refuses to start without APP_KEY, APP_PASSWORD and APP_SECURE, whose export it prints (APP_SECURE=0 for http://localhost; its deploy/fly.toml states 1). Exit 2 for a name that is not lowercase letters, digits and hyphens, a letter first and a letter or digit last, or a target that is not empty. |
m0 build [--release] [--target-cpu CPU] |
Compiles src/server.mojo and renames the result onto bin/server, so a running server is never written over. One build of a project at a time: a second waits for the first, saying so. --release compiles for the platform's baseline CPU, relocates the binary and bundles the Mojo runtime beside it in dist/ — the directory an image's runtime stage copies. |
m0 test [FILE...] |
mojo run per file, serial, output untouched. Needs no C compiler. A run with no test files is refused, not passed. |
m0 doctor [--json] [-- HOST_ARGS] |
Every check, then bin/server HOST_ARGS --doctor with your environment. Exits with the first failed check's code, else the application's. A binary that cannot be run, or has not answered within 30 s, is exit 1, and everything it started is ended. Last, it names the files m0 new wrote that differ from what this m0 writes: reported, never failed, never rewritten. |
m0 dev [-- HOST_ARGS] |
Builds and serves bin/server HOST_ARGS, then polls src/ and pyproject.toml (stdlib, no watcher). On a change it builds WHILE the old server serves; a failed build leaves it serving; a good one sends it SIGTERM, waits for the pid to exit (6 s, then SIGKILL, named), and starts the new binary. Ctrl-C stops the server and exits 0; a second Ctrl-C while it drains ends it with SIGKILL, named. |
m0 image [--tag T] [--target-cpu CPU] [-- DOCKER_ARGS] |
docker build -f deploy/Dockerfile -t T DOCKER_ARGS . from the project root (T defaults to the directory's name), then the image's /app/about.json as the last line of stdout. Needs docker and no toolchain. Docker missing or failing is exit 1, its output untouched. It does not deploy. |
m0 include |
Prints the include root. |
Exit codes are a closed set: 0; 1 the tool m0 ran failed; 2 the command
line cannot be accepted; 78 m0 refused before running anything, with one
m0: detail (fix) line on stderr.
m0 runs the mojo installed in its own environment — never the one on
PATH — and refuses a version it was not gated on, naming the pin to add.
There is no override: every gate in the repository ran on that one compiler.
MAX is optional and held the same way: max-core, if installed, must be
the version the host was gated beside (m0 doctor's max-gated).
Upgrading. uv add --dev 'm0==X', then uv run m0 doctor: its
mojo-gated line names the one uv add that moves mojo — and max-core,
when installed, since it pins its compiler exactly — to the pair X was
gated on, and its scaffold line names the files m0 new wrote that X
writes differently. m0 never rewrites a project's files; uv run m0 new /tmp/NAME writes X's to compare.
m0 is versioned apart from the repository it is cut from, and stays 0.x
until an application outside that repository has soaked on it.
m0/_build_info.json records the tree.
MIT. The lightbug_http fork inside is MIT too; both licences are in
m0/licenses/.
Metadata
Release files for m0 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| m0-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / m0-0.4.0-py3-none-any.whl
| Download URL | m0-0.4.0-py3-none-any.whl |
|---|---|
| Size | 641.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
938e8cfd622afc6bc684de78ecb699659ae8727716ce8c6250d185ec2c605d62
|
|
BLAKE2b-256 checksum How to use checksums |
2cd03e8f9ba3d6e04169b9737d42f5bfbec700ddc92dc62b0fe35e527d5f0e54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 30, 2026.
Transparency log