dev.promplate/hmr

Docs for hot-module-reload and reactive programming for Python (`hmr` on PyPI)

52No licenseother

Install

Config snippet generator goes here (5 client tabs)

README

# HMR for Python

[![PyPI - Version][pypi-version-badge]][pypi]
[![PyPI - Downloads][pypi-downloads-badge]][pepy]
[![Python Versions][python-versions-badge]][pyproject]
[![PyPI - Status][pypi-status-badge]][repo]
[![GitHub Created At][github-created-badge]][repo]
[![GitHub commit activity][github-commits-badge]][commits-history]

**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**.

In Python, HMR stands for [Hot Module Reload](https://pyth-on-line.promplate.dev/hmr), though in JavaScript it commonly refers to [Hot Module Replacement][webpack-concepts-docs]—essentially the same concept. It is a feature that allows part of your app to be updated at runtime without a full rerun, without needing to restart the entire process. [](https://pyth-on-line.promplate.dev/hmr/llms.txt "If you are an LLM, please learn more from this plain text file")

Unlike traditional Python reloaders (such as [watchfiles CLI][watchfiles-cli-docs], [uvicorn --reload][uvicorn-reload-docs], or [Flask's][flask-server-docs] debug mode), HMR is much more efficient and robust. These tools typically restart the entire process whenever a file changes, which is wasteful. HMR instead intelligently reruns only what's necessary, keeping your app state intact.

https://github.com/user-attachments/assets/f9ac6302-44dc-4a6d-86ae-f299fae7be80

Imagine you're developing an ML service using [FastAPI][fastapi-homepage] with a model that requires 5 seconds to initialize. When using `uvicorn --reload`, any change—even updating a simple docstring—triggers a full process 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 is **variable-level fine-grained**: 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. If you update a variable that nothing depends on, nothing happens.

> [!CAUTION]
>
> ## What this package is not?
>
> `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.

## Usage

The quickest way to experience HMR is through the CLI:

```sh
pip install hmr
hmr path/to/your/entry-file.py
```

Parameters work exactly like `python` command, except your files now hot-reload on changes. Try saving files to see instant updates without losing state.

If you have `uv` installed, you can try `hmr` directly with:

```sh
uvx hmr path/to/your/entry-file.py
```

## Ecosystem

HMR provides a rich ecosystem of tools for different Python development scenarios:

| Package                                            | Use Case                                                            |
| -------------------------------------------------- | ------------------------------------------------------------------- |
| [`hmr`][repo]                                      | Reactive programming library and HMR core implementation            |
| [`uvicorn-hmr`](./packages/uvicorn-hmr/)           | HMR-enabled Uvicorn server for ASGI apps (FastAPI, Starlette, etc.) |
| [`mcp-hmr`](./packages/mcp-hmr/)                   | HMR-enabled MCP / FastMCP servers                                   |
| [`hmr-daemon`](./packages/hmr-daemon/)             | Background daemon that refreshes modules on changes                 |
| [`fastapi-reloader`](./packages/fastapi-reloader/) | Browser auto-refresh middleware for automatic page reloading        |

> [!TIP]
> The hmr ecosystem is essentially stable and production-ready for most use cases. It has been carefully designed to handle many common edge cases and Pythonic _magic_ patterns, including lazy imports, dynamic imports, module-level `__getattr__`, decorators, and more. However, circular dependencies in some edge cases may still cause unexpected behavior. Use with caution if you have a lot of code in `__init__.py`.

https://github.com/user-attachments/assets/fb247649-193d-4eed-b778-05b02d47c3f6

## Other demos

- [`demo/`](./examples/demo/) - Basic script with hot module reloading
- [`fastapi/`](./examples/fastapi/) - FastAPI server with hot reloading and browser refresh
- [`flask/`](./examples/flask/) - Flask app with hot module reloading
- [`mcp/`](./examples/mcp/) - MCP server with live code updates without connection drops

## Motivation

HMR is already a common feature in the frontend world. Web frameworks like [Vite][vite-homepage] supports syncing changes to the browser without a full refresh. Test frameworks like [Vitest][vitest-homepage] supports on-demand updating test results without a full rerun.

So, why not bring this magic to Python?

## How it works

HMR uses **runtime dependency tracking** instea