Hot reload for Starlette app with smart asset updates and HTML injection
Project description
Starlette Hot Reload
starlette-hot-reload is a lightweight hot reload utility for
Starlette that provides fast in-browser reloads for
templates and static files.
It integrates directly with your Starlette app and provides:
- Automatic HTML injection via middleware.
- Server-Sent Events (SSE) based live reload (no WebSocket dependencies).
- Smart updates, CSS changes reload without a full page refresh.
- Automatic reconnection with exponential backoff.
- Fully typed, following Starlette patterns.
- Zero additional dependencies beyond Starlette.
- Explicit lifespan composition, matching Starlette's application model.
Installation
uv add starlette-hot-reload
# or
pip install starlette-hot-reload
Example
from contextlib import asynccontextmanager
from starlette.applications import Starlette
from starlette.routing import Route
from starlette_hot_reload import hot_reload
routes = [
# your routes
]
@asynccontextmanager
async def lifespan(app: Starlette):
async with hot_reload(app=app, watch_dirs=["templates", "static"]):
yield
app = Starlette(
debug=True,
routes=routes,
lifespan=lifespan,
)
Run the application using uvicorn:
$ uvicorn main:app
How it works
starlette-hot-reload updates the browser without restarting the server.
It integrates into your app using middleware and a Server-Sent Events (SSE) endpoint.
- HTML responses are automatically modified to include a small client script.
- The client connects to an SSE stream exposed by the app.
- File changes trigger reload events:
- CSS changes update stylesheets in-place.
- Other changes trigger a full page reload.
- The client automatically reconnects if the connection is lost.
It complements:
- ASGI server reload (
uvicorn --reload) - Frontend build tools (Vite, Webpack, etc.)
Usage
Hot reload is only active when debug=True.
app = Starlette(debug=True)
You can control which directories are watched:
@asynccontextmanager
async def lifespan(app: Starlette):
async with hot_reload(app=app, watch_dirs=["templates", "static", "assets"]):
yield
You can customize the SSE endpoint path (default is /__starlette_hot_reload):
async with hot_reload(
app=app,
watch_dirs=["templates", "static"],
events_path="/custom-events-path",
):
...
You can also tune how often the watcher scans for changes. Lower values make reloads feel faster, at the cost of a bit more filesystem polling:
async with hot_reload(
app=app,
watch_dirs=["templates", "static"],
poll_interval=0.25,
):
...
If you compose hot reload with other lifespan-managed resources, use
contextlib.AsyncExitStack:
from contextlib import AsyncExitStack, asynccontextmanager
@asynccontextmanager
async def lifespan(app: Starlette):
async with AsyncExitStack() as stack:
await stack.enter_async_context(hot_reload(app=app, watch_dirs=["templates", "static"]))
yield
Debug Logging
To enable debug logging, configure Python's logging module:
import logging
import sys
logging.basicConfig(
level=logging.DEBUG,
# ...
)
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file starlette_hot_reload-0.2.1.tar.gz.
File metadata
- Download URL: starlette_hot_reload-0.2.1.tar.gz
- Upload date:
- Size: 8.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c3bc5505bd673b8fa0298b853bd380bfc8fe87afb66c5bac7cbb4aee2d36697e
|
|
| MD5 |
015ca5017dac0049a0f827b5ff16709b
|
|
| BLAKE2b-256 |
6b50e767755a15c0163ec9888eaeebd0792f0d08b5887bbb93f5c1bdab8657c7
|
File details
Details for the file starlette_hot_reload-0.2.1-py3-none-any.whl.
File metadata
- Download URL: starlette_hot_reload-0.2.1-py3-none-any.whl
- Upload date:
- Size: 11.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e9eeba03b59e240e553cc059d8d5ed981cc0f62a453812f4cb67ec38dee71ff6
|
|
| MD5 |
801013697779c58f54e87dfdb6a694f8
|
|
| BLAKE2b-256 |
1f177a661b4068d357856e294ab85d06e3e223380a0f43a22a166aeb82e3996d
|