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.1.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.1-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

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

Hashes for starlette_hot_reload-0.2.1.tar.gz
Algorithm Hash digest
SHA256 c3bc5505bd673b8fa0298b853bd380bfc8fe87afb66c5bac7cbb4aee2d36697e
MD5 015ca5017dac0049a0f827b5ff16709b
BLAKE2b-256 6b50e767755a15c0163ec9888eaeebd0792f0d08b5887bbb93f5c1bdab8657c7

See more details on using hashes here.

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

Hashes for starlette_hot_reload-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e9eeba03b59e240e553cc059d8d5ed981cc0f62a453812f4cb67ec38dee71ff6
MD5 801013697779c58f54e87dfdb6a694f8
BLAKE2b-256 1f177a661b4068d357856e294ab85d06e3e223380a0f43a22a166aeb82e3996d

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