Autoreload¶
This page covers how the development server watches the filesystem and rebuilds the route set without a restart.
Overview¶
The autoreload pipeline runs only when runserver boots with autoreload enabled.
It collects watch specs from every subsystem, registers them with Django, and reacts to filesystem events.
Pipeline¶
flowchart TB
Boot[runserver boots] --> Collect[iter_all_autoreload_watch_specs]
Collect --> Specs[Watch specs]
Specs --> WatchReady[(watch_specs_ready)]
Specs --> Watcher[Django autoreload]
Watcher -- python module change --> ProcessRestart[Django reloader restarts process]
Watcher -- tick --> Diff[NextStatReloader diffs route set]
Diff -- changed --> Notify[notify_file_changed]
Notify --> ProcessRestart
Startup Integration¶
The pipeline is wired by next.apps.autoreload.install(), which NextFrameworkConfig.ready calls at application startup.
install performs two actions:
Replaces
django.utils.autoreload.StatReloaderwithNextStatReloader. The swap is idempotent: subsequent calls are no-ops ifStatReloaderis already aNextStatReloadersubclass.Connects
_watch_next_filesystemto Django’sautoreload_startedsignal so the watch specs are registered the moment the dev server starts.
Note
If another library has already replaced autoreload.StatReloader with a class that is not a StatReloader subclass, the swap is skipped and a warning is logged.
In that case the route-set diff is inactive.
To restore the original reloader in tests, call next.apps.autoreload.uninstall().
Modules¶
Installer¶
next.apps.autoreload.install()swapsStatReloaderand connects the watch signal.uninstall()restores the previous reloader. Test suites that callAppConfig.readymultiple times use it to avoid double-patching.
Runtime¶
next.server.autoreload.NextStatReloaderextends the Django stat reloader and also restarts the process when the discovered route set changes.next.server.watcher.iter_all_autoreload_watch_specsreturns the deduplicated list of built-in specs plus pairs registered throughregister_autoreload_watch_spec.FilesystemWatchContributoris a runtime-checkable protocol exported for type annotations only and is not iterated at runtime.next.server.roots.get_framework_filesystem_roots_for_linkingreturns the canonical page and component directory roots for build tooling.next.server.signals.watch_specs_readyfires once afteriter_all_autoreload_watch_specsfinishes building the spec list.
Watch Specs¶
A watch spec is a tuple of a root path and one glob pattern.
_iter_default_autoreload_watch_specs is an internal helper of next.server.watcher that builds the built-in set.
User code calls iter_all_autoreload_watch_specs instead, which wraps the built-in set with the registered extra specs.
Each page root contributes a
**/page.pyspec.Each page root paired with its components folder name contributes a
**/_components/**/component.pyspec.Each extra component root from
DEFAULT_COMPONENT_BACKENDScontributes a**/component.pyspec.
Only Python entrypoints are watched.
.djx templates and co-located assets are deliberately omitted from the specs.
iter_all_autoreload_watch_specs appends the specs registered through register_autoreload_watch_spec.
It deduplicates the combined list by resolved path and glob, then emits watch_specs_ready with the final list.
Reload Decisions¶
Two kinds of changes trigger a reload.
- Python module change.
Django’s reloader restarts the process. The framework re-imports every page and component at boot.
- Route set change.
NextStatReloaderdiffs the discovered route set on every tick. A new or removed page directory callsnotify_file_changedso Django restarts the process even when no watched file mtime changed.
The route set diff is taken by NextStatReloader from the configured page roots.
A custom router that builds routes from another source rebuilds them through router_manager.reload, which is the public API covered in Reload Routes From Code.
A .djx edit triggers neither path.
Templates are re-read on render and their cached compilation is invalidated by source mtime inside the page and component layers.
A saved edit shows up on the next request without a process restart.
Signals¶
The autoreload pipeline fires watch_specs_ready after the watch-spec aggregation completes.
The sender is the iter_all_autoreload_watch_specs function itself, so a receiver connected with sender=iter_all_autoreload_watch_specs fires only for that aggregation.
Custom routers subscribe to watch_specs_ready to register additional patterns.
Extension Points¶
Register extra
(path, glob)pairs fromAppConfig.readythroughregister_autoreload_watch_spec.Subscribe to
router_reloadedfor in process cache refresh.Subscribe to
watch_specs_readyfor diagnostic logging during development.
Registering extra watch directories¶
Packages that generate templates or routes outside the usual page trees can register additional (path, glob) pairs without forking the framework.
Call register_autoreload_watch_spec from next.server inside AppConfig.ready.
from pathlib import Path
from django.apps import AppConfig
from next.server import register_autoreload_watch_spec
class MyAppConfig(AppConfig):
name = "myapp"
def ready(self) -> None:
register_autoreload_watch_spec(Path("/var/cache/myapp/templates"), "**/*.djx")
Pairs merge into the list returned by iter_all_autoreload_watch_specs and receive the same deduplication pass as built-in specs.
Subscribe to watch_specs_ready if you need to assert on the effective list during development.
See Also¶
See also
File Router for the hot reload semantics.
Reload Routes From Code for the public API.
Apps Reference for next.apps.autoreload.install and startup wiring.