HMR means Hot Module Reload / Hot Module Replacement. It is a feature that allows part of your app to be updated at runtime without a full rerun.
In contrast to the traditional way of reloading Python applications (like watchfiles CLI, uvicorn --reload or Flask's debug mode), HMR is just more efficient.
fastapi.mov
Imagine you're developing an ML service using FastAPI with a model that requires 5 seconds to initialize. When using uvicorn --reload
, any change—even updating a simple docstring—triggers a code restart, forcing you to wait those 5 seconds every time. It's as frustrating as encountering a red light at every intersection.
HMR offers a smoother experience. Changes take effect instantly because HMR intelligently reruns only what's necessary. Your codebase functions like a dependency graph—when you modify a file, HMR only reruns the affected modules from that modified module up to your entry point file, without restarting the whole app.
Caution
hmr
should not be confused with client-side hot reloading that updates browser content when server code changes. This package implements server-side HMR, which only reloads python code upon changes.
pip install hmr
hmr path/to/your/entry-file.py
If you have uv
installed, you can try hmr
directly with:
uvx hmr path/to/your/entry-file.py
Please note that hmr is still in early development. While it works well with simple modules, frameworks like ASGI servers or pytest may require specific integration methods.
demo.mov
HMR is already a common feature in the frontend world. Web frameworks like Vite supports syncing changes to the browser without a full refresh. Test frameworks like Vitest supports on-demand updating test results without a full rerun.
So, why not bring this magic to Python?
Signal
is an alternative of the observer pattern. I implemented a simple signal system to notify changes.- I implemented a custom Module class which tracks every
__getattr__
and__setattr__
calls. When a key is changed, it will notify the modules who used it. This notification is recursive but fine-grained. watchfiles
is used to detect fs changes. If a change's path is a python module that has been imported, it will notify the corresponding ones.
This might just be the first fine-grained HMR framework in the Python ecosystem—and honestly, I think the real magic lies in the ecosystem we build around it.
Pair uvicorn
+ hmr
, and you’ve got yourself a Vite-like development experience. Combine pytest
+ hmr
, and you’re basically running Vitest for Python. The possibilities with other libraries? Endless. Let’s brainstorm together—who knows what fun (or mildly chaotic) things we might create!
Tip
A little backstory: the code for hmr lives in another repo because, truth be told, I wasn’t planning on building an HMR framework. This started as an experiment in bringing reactive programming to Python. Along the way, I realized why not make a module’s globals reactive? And that’s how hmr was born! While it began as a side project, I see tremendous potential in it.
For now, this repo is a humble README and a place to kick off the conversation. If you think hmr has potential, or you just want to throw ideas around, I’d love to hear from you. We believe that the Python community can benefit from a more dynamic development experience, and we’re excited to see where this can take us!
About fine-grained reactivity, I recommend reading SolidJS’s excellent explanation.