Open-source project
miguelgrinberg/microdot avatar
miguelgrinberg/microdot

Microdot: the minimal Flask-like web framework for MicroPython and CPython

Mirror of https://code.miguelgrinberg.com/miguelgrinberg/microdot

2,150 stars157 forksPythonMIT

At a glance

What is it?
Microdot is a Python web framework inspired by Flask, built to run on microcontrollers under MicroPython as well as standard CPython. It ships with zero runtime dependencies, and pub/sub and OpenAPI integrations remain on the roadmap.
Who is it for?
Microdot fits when you want Flask-style routing on an embedded MicroPython device or a minimal CPython process where zero pip dependencies matter. Skip it when your application depends on Flask extensions that have no microdot equivalent, or when your project requires OpenAPI documentation, since that integration has not yet shipped.
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 23 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

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

Editorial analysis

What microdot targets: Flask routing patterns for constrained environments

Flask is a practical web framework for CPython, but it is not designed to run on a microcontroller or in an environment where every kilobyte of installed code counts. Microdot solves that problem by taking Flask's decorator-based routing pattern and reimplementing it in a form that runs under MicroPython on embedded devices as well as under standard CPython.

One detail that appears when you read both the README and pyproject.toml together: the description field in pyproject.toml calls microdot "The impossibly small web framework for MicroPython", omitting CPython from the description entirely. The README is broader, listing both runtimes as supported targets. Since PyPI takes the description from pyproject.toml, the PyPI listing narrows the stated audience in a way the README does not intend.

For teams choosing between Flask and microdot on a standard server, the zero-dependency constraint is the real differentiator, not microcontroller support. Flask pulls in several runtime packages; microdot pulls in none.

Async-first route handlers and no runtime dependencies

Every route handler in microdot is an async function, and the minimal working example in the README makes that visible from the first line:

python
from microdot import Microdot

app = Microdot()

@app.route('/')
async def index(request):
    return 'Hello, world!'

app.run()

Using async throughout is a deliberate design choice, not an option. On constrained hardware, an event loop handles multiple connections without spawning threads, and threads carry memory overhead that a microcontroller may not tolerate. Flask uses synchronous handlers by default, so this is a real API difference for developers moving from one to the other.

The dependencies section in pyproject.toml is empty, meaning nothing installs alongside microdot at runtime. On a device where pip storage is measured in kilobytes, that constraint matters a great deal. It also simplifies reproducibility, since there is no transitive dependency tree to audit or to break across environments.

Installing from PyPI and writing the first real route

Microdot is published on PyPI under the package name microdot, and pyproject.toml sets requires-python to >=3.8. Any CPython from 3.8 onward meets that floor. The four-line example above is the entry point for a first run: save it to a file, run it with Python, and a browser request to the root path returns the string "Hello, world!". No configuration files are needed and no environment variables are documented for the basic case.

For MicroPython devices, the libs/ directory at the repository root contains the runtime files. The README points to microdot.readthedocs.io for full platform-specific installation steps rather than covering them inline, so device-specific setup lives in the external documentation.

The examples/ directory holds subdirectories for auth, benchmark, cors, csrf, gpio, hello, login, sessions, sse, static, streaming, subapps, templates, tls, uploads, and websocket. The gpio example is the most device-specific, written for MicroPython running on hardware with physical pins. The rest cover server patterns that apply equally to CPython deployments.

Auth, multipart forms, CSRF and type hints as current capabilities

Microdot ships authentication support designed along similar lines to Flask-Login, and the examples/auth/ and examples/login/ directories each demonstrate a working implementation. Forms encoded in multipart/form-data are handled natively, covering the content type that file upload forms produce. CSRF protection is available as an extension, and examples/csrf/ shows its setup. Type hints are now part of the package, so IDE autocompletion and static analysis work without writing stubs by hand.

The roadmap section in the README lists all four of those features alongside a notation marking each as already added, indicating the roadmap doubles as a completed-items record. Two features in the same list carry no such mark: a pub/sub mini-framework and OpenAPI integration. That gap is what separates the current feature set from Flask parity in those two areas.

Flask as the reference: the same decorator pattern, but extension gaps are real

Microdot's routing syntax mirrors Flask closely enough that a developer familiar with Flask can read microdot code without learning a new mental model for route definitions or request objects. The README explicitly describes the project as inspired by Flask, and the roadmap references Flask-Login and APIFairy by name as the inspiration for two of its features.

Where the gap is real is in the extension ecosystem. Flask has years of third-party packages covering everything from SQLAlchemy integration to OAuth flows. Microdot builds its own equivalents from scratch, and those equivalents arrived at different times rather than all at once with the core. A project that already depends on a Flask extension not yet ported to microdot faces a porting cost that may outweigh the benefits of switching.

The async-first design also creates a divergence for existing Flask codebases. Flask added async handlers as an optional feature at a later point; in microdot they are the only kind, so a synchronous Flask codebase cannot be migrated by renaming the import alone.

Pub/sub messaging and OpenAPI support are still in development

Two items on the roadmap carry no completion mark in the README: a pub/sub mini-framework for WebSocket and SSE, and OpenAPI integration similar to the APIFairy extension for Flask.

WebSocket itself is available, and examples/websocket/ demonstrates it. The pub/sub layer is a higher-level pattern built on top of WebSocket and SSE, providing named channels and subscriber management. Without it, teams that need broadcast messaging must build that layer themselves.

OpenAPI documentation is a standard requirement for any API that external consumers will call. The roadmap references APIFairy as the model for that integration, but no timeline is given in the README. Teams using microdot for a documented REST service have to write the OpenAPI specification by hand or with a separate tool until that integration ships.

Where the canonical repository lives and the migration path for older codebases

The primary repository is at code.miguelgrinberg.com, not on GitHub. The GitHub location is a mirror. Issues and contributions live on the primary host, so anyone used to tracking changes through GitHub needs to follow that site. CHANGES.md is at the repository root.

Microdot 2.7.0 was released on 2026-09-18 under an MIT license, and the repository's last push was on 2026-09-19. The older first major branch has its own documentation archive at microdot.readthedocs.io/en/v1/, and the README provides migration notes at microdot.readthedocs.io/en/latest/implementation/migrating.html for codebases that were written for that branch.

Editorial conclusion

Microdot fits when you want Flask-style routing on an embedded MicroPython device or a minimal CPython process where zero pip dependencies matter. Skip it when your application depends on Flask extensions that have no microdot equivalent, or when your project requires OpenAPI documentation, since that integration has not yet shipped. Check the migration notes at microdot.readthedocs.io before starting any codebase that was written for the older major branch, and confirm that pyproject.toml's zero-dependency list still covers everything your use case requires.

Frequently asked questions

What is Microdot?

Microdot is a minimalistic Python web framework inspired by Flask that runs on both MicroPython and standard CPython. Its small size and zero runtime dependencies let it run on microcontrollers and standard Python environments.

How do I install Microdot?

Microdot is published on PyPI under the package name microdot and requires Python >= 3.8. For MicroPython devices, the documentation at microdot.readthedocs.io covers platform-specific installation steps.

Is Microdot compatible with Flask extensions?

No. Microdot builds its own equivalents, including authentication support and CSRF protection, but OpenAPI integration and a pub/sub framework are listed on the roadmap with no completion date.

Does Microdot support WebSocket?

Yes. An examples/websocket/ directory is in the repository. A higher-level pub/sub framework for WebSocket and SSE is listed as a roadmap item but carries no completion mark in the README.

Is there a migration guide for older Microdot codebases?

The README provides migration notes at microdot.readthedocs.io for codebases written for the older major branch, and a documentation archive for that branch is at microdot.readthedocs.io/en/v1/.

Official sources

  1. License: MIT
  2. miguelgrinberg/microdot on GitHub
  3. Project website
  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/miguelgrinberg-microdot.svg)](https://hysenlabs.com/projects/miguelgrinberg-microdot)