Skip to main content

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.

Demo

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

starlette_hot_reload-0.2.0.tar.gz (8.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

starlette_hot_reload-0.2.0-py3-none-any.whl (11.1 kB view details)

Uploaded Python 3

File details

Details for the file starlette_hot_reload-0.2.0.tar.gz.

File metadata

  • Download URL: starlette_hot_reload-0.2.0.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

Hashes for starlette_hot_reload-0.2.0.tar.gz
Algorithm Hash digest
SHA256 5381ccf0f9457c613d755e69a0a936f76d819a878d4831b2006d16b1c13207bc
MD5 0e98ccbb50619feb1b082b5fb8061a72
BLAKE2b-256 8a155213cdde28a03a34793394408161b5200b83716868df612e91d01575ba83

See more details on using hashes here.

File details

Details for the file starlette_hot_reload-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: starlette_hot_reload-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 11.1 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

Hashes for starlette_hot_reload-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 99f92078248ef9930a5a9a565e34e2770144e7371e0340ed3273073ff396e515
MD5 c65599926a8dc508e15669b5887ec90e
BLAKE2b-256 53ec40c45a5d8d42784752bb55165db414c9de0c3181cdefb532e02523dda179

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page