Skip to content

Introducing HMR - An Engine, a Tool, an Ecosystem.

HMR provides a pythonic, flexible, progressive-yet-intuitive reactive programming engine/framework, and on top of that, a fine-grained, on-demand hot-reload tool.

  • The reactive engine implements high-performance push-pull reactivity12, letting you elegantly do reactive programming in Python
  • The hot-reloading tools are drop-in replacements for python CLI, uvicorn, and mcp / fastmcp integration, boosting your development with or without frameworks

Tip

Most features are usable independently. Any user can use one or more of the features above to improve development efficiency (not exaggerating, this library improved my debugging efficiency by 10x-100x)

This project supports Python 3.12+, and is compatible with alternative Python runtimes like Pyodide, GraalPy, and RustPython. It supports both asyncio and trio, and is well-tested in 3.12-3.14.

Why Python 3.12+?

The project requires at least Python 3.12 because the I values static typing, and 3.12 started supporting some convenient new features in static typing. If you don't mind these, you can easily support down to 3.10 or even 3.8 with minor changes.


For the same reason, PyPy is not supported as for now latest PyPy only supports up to Python 3.11.

Comparisons

A good way to understand a project is through comparisons with similar projects to learn what it's "not". Since this project has both a reactive engine and hot-reload tool, the comparisons below will be made separately with related projects.

Hot-reload Tools

tach is relatively modern and attempts to build real dependency relationships, except for this project:

  • not only track Python modules but also track any opened files during runtime
  • has more Python ecosystem integration that works out-of-the-box, while tach only has a single blog post example for implementing hot reloading.

The other tools do not track transitive dependencies (they only reload directly modified code, which leaves dependent code out of sync), — maybe useful in tiny demos but fragile for real projects. Additionally, many of them rely on hacky monkey patching.

In contrast, this project avoids monkey-patching: it leverages Python's sys.meta_path hooks and a custom ModuleType to track dependencies.

Besides these two aspects, here are some individual comparisons:

  • Unlike python-hmr, this project supports reloading any variable within a module (not just classes and functions)
  • jurigged implements loop statement reloading in a very magical way, but that's a rare use case, and in these cases you can move the loop code to a module and install hmr-daemon to achieve the same result
  • importlib.reload in Python module mechanism, %autoreload in IPython and reloadium etc. all apply to the two points above
  • Cold-reload CLI tools like watchfiles and watchdog purely restart the entire process when encountering changes, their compatibility is similar to HMR but sacrifices performance (the projects above sacrifice compatibility for performance, while this project has both). The difference between hot and cold reload is similar to the difference between bun's --hot and --watch

Performance

Because of the technology choices it made, HMR's flexibility typically does NOT lead to higher overhead; rather, it becomes the best of both worlds.

Reactive Programming Engines

  • TUI library textual, Web app framework py-shiny both come with simple, framework-specific reactive systems34, but their reactions are all async. HMR natively supports both sync and async reactivity. It is framework-agnostic and can be easily integrated with different UI frameworks
  • The interactive notebook marimo and the jupyter kernel ipyflow both use static analysis for reactivity, which has the same disadvantages mentioned above for tach
  • RxPY is closer to an opinionated event-driven framework rather than a fine-grained reactivity engine (despite "reactive" being in its name)

HMR also supports isolated reactivity Contexts, which enables separated reactivity and a higher level of flexibility (docs still under construction), allowing developers to build their own powerful tools/frameworks on top of this engine without interfering with one another

Comparable JavaScript Projects

  • HMR aims to reach the usability and flexibility of libraries like alien-signals.
  • The reactivity models of Svelte, SolidJS, Vue gave this project inspiration and some reference
  • One of the initial objectives of this project is to create Vite and Vitest in the Python ecosystem.

Thanks

This project stands on the shoulders of earlier ones, inspired by their ideas and design choices.

Some of the wording here may sound exaggerated, but they are all facts. If you find exceptions, feel free to open an Issue

This project also welcomes anyone to discuss future features!


  1. There is an article about reactivity concepts (in JavaScript) at dev.to 

  2. Another article: Wikipedia 

  3. Textual Docs: textual.textualize.io 

  4. Shiny for Python Docs: shiny.posit.co