Before you upgrade, read the upgrade guide.
Welcome to djust 1.3. These notes summarize the 1.3.0rc1 through
1.3.0rc9 changelog entries. For an existing application, follow
Upgrading to djust 1.3 before deploying 1.3.0.
Three themes run through this release:
- Explicit contracts for interactive applications. Components can own
events and typed bindings (ADR-034);
ModelFormMixinfollows Django's form and object lifecycle (ADR-035); typed event parameters are available behind an opt-in strict policy (ADR-036); and system checks compare template bindings with handlers (ADR-037). - Declared state and accounts.
exposure_policy = "explicit"lets a view declare its template context, persistence and browser-visible state while legacy exposure remains the default (ADR-038, Explicit exposure). Account pages can use Django, django-allauth or an application backend (ADR-039, Accounts). - More ways to build and operate a LiveView app. Lazy and batched views have independent lifecycles on a connection (Multiple views); process-local room clocks are opt-in, with distributed ownership deferred (ADR-042); and the CLI, checks and MCP tools can discover UI capabilities (ADR-043, AI discovery). Free-threaded Python workers and multi-loop serving are opt-in (Scaling across cores).
What's new in djust 1.3
Components, forms and event contracts
Interactive components can bind typed inputs to their own instances and send semantic outputs to their parent view. Repeated stateful components use keys; repeated rows can delegate actions without creating one component per row. The first implementation includes the interactive dropdown. Read Interactive components and ADR-034 for the ownership rule and examples.
ModelFormMixin loads and authorizes the object named by an edit URL and
uses Django form construction hooks. The older _model_instance pattern
still works; Forms and
ADR-035 show how
to adopt the new lifecycle. An opt-in strict event-parameter policy reads
Python handler annotations as the contract for values sent by the browser.
Legacy parameter handling stays the default. See
Events and
ADR-036.
The new djust.T019–T022 checks compare event bindings in templates with
handlers and report wrong ownership, missing handlers and parameter
mismatches. They replace the retired djust.V007 advice to accept **kwargs
everywhere. The check's static analysis has limits; the
event-contract ADR
records those limits and its executable documentation tests.
State, accounts and rooms
With exposure_policy = "explicit", a view's ordinary Python attributes stay
on the server unless it declares context, persistence or browser exposure.
Legacy remains the default, so this is a view-by-view migration. The
explicit-exposure guide and
ADR-038 describe its
declarations and supported transports. The proposed broader compliance
profile in ADR-041 has not shipped.
Account flows use the selected djust.auth.accounts backend: the bundled
Django backend, django-allauth, or an application implementation. The
allauth backend requires djust[auth-allauth]; checks djust.A100–A107
report setup problems. See Accounts and
ADR-039.
The opt-in djust.clocks RoomClock and SharedPoll provide process-local
shared ticks for a tenant-scoped room. They include presence-bound start and
idle stop, pause/resume and bounded late-beat handling. Cross-process
ownership and fencing are deferred; do not use a process-local clock as a
distributed coordinator. See
ADR-042.
Serving and discovery
Eager, lazy and batched LiveViews mounted on one WebSocket each have their own state, authorization, event routing and teardown. The SSE transport also hosts views beside the page view. A refused lazy view fails in its own container rather than navigating the page. See Multiple views for the supported paths and remaining limits.
For free-threaded Python, LIVEVIEW_CONFIG["worker_threads"],
PooledHTTP, scoped server push and djust serve ... --loops N are opt-in
ways to divide work. Multi-loop mode requires a free-threaded build and a
loop-safe channel layer. Configuration and setup are in
Scaling across cores. No change to
serving mode is required for an existing app.
djust ai inventory, suggest and manifest expose installed capabilities,
component uses and project context. MCP exposes component discovery too.
djust_audit --ast adds X101–X105 UI findings, and manage.py check adds
I001–I003 information messages. The AI discovery guide
and ADR-043 describe their scope
and opt-outs. The themed djust new scaffold now starts with components and
an {% app_shell %} base; --bare creates a core-only starter.
Asset provenance
Shipped third-party browser assets are local files with integrity metadata and a CycloneDX SBOM in the wheel. This covers the vendored highlight.js, xterm and admin stylesheet in place of their former CDN loads. See Vendored assets and ADR-040.
What changes for a 1.2 application
Most 1.2 views keep their legacy state and event-parameter policies. The
changes most likely to need work are new djust.T019–T022 template-binding
warnings, djust.I001–I003 information messages in pipelines that fail on
INFO, and new UI findings from djust_audit --ast --strict. A view using
PresenceMixin after LiveView now raises TypeError at import. Six unused
configuration keys are ignored and reported by djust.C018. Redis channel
layers with a short socket timeout get djust.C023.
Some changes affect specific integrations: HTTP-fallback events queue in
order; a custom HTTP client must accept an empty patch list; component or
child dj-paste handlers now own their events; raw channel-layer messages to
a connection with several mounted views must name the group. The djust theme
preset has new text colours. Cross-origin static hosts must allow CORS for
vendored admin CSS and highlight.js with Subresource Integrity. See the
upgrade guide for detection and code changes.
Security
The 1.3 candidates harden live mount authorization, object permissions, per-handler rate limits, tenant state and snapshots, admin queryset access, MCP filesystem access, URL schemes and proxy trust. They also prevent unsafe client rendering in the debug panel and theme editor. Third-party browser assets are vendored, verified and listed in an SBOM (ADR-040, Vendored assets). Explicit-exposure views receive additional redaction, authorization and persistence protections (ADR-038).
If you serve with daphne, upgrade Twisted. The djust[daphne] extra still
allows Twisted 26.4.0, which is open to HTTP request smuggling in the HTTP
parser daphne uses (CVE-2026-115877). Install twisted[tls]>=26.10.0rc1, or
serve with uvicorn as the rest of these docs do.
Already in 1.2.5: the release/1.2.5 changelog records the Python 3.14
live-auth classifier fix in 1.2.5; the admin, mount authorization, MCP path,
rate-limit and theming URL fixes in 1.2.4; and the tenant-state, reauthorization,
debug-panel, service-worker and PWA-sync fixes in 1.2.3. Those protections are
not new to an application already on 1.2.5. The 1.3 line additionally includes
its explicit-exposure protections, vendored browser assets, the theme-editor
escaping, the post-login snapshot rebinding (#3248), the fix that stops
rendered user HTML from downgrading a strict handler, and the rc9 AI
inventory and proxy-count hardening. Compare the
1.3 changelog with the maintenance sections in the
1.2 branch's changelog for the full fix-by-fix history.
Upgrading from 1.2
- Install
djust==1.3.0and collect static files so the client matches the server.djust.C013reports an older collected client. - Follow Upgrading to djust 1.3, run
manage.py checkandmanage.py djust_audit --ast, then exercise your application's templates and event transports. - Deploy the matching server and static assets together, particularly if you
use lazy views or the new
view_refusedframe.
ADR-041 is Proposed; its state-protection and compliance profile is not part of this release.
All changes in 1.3.0
The CHANGELOG.md entry for djust 1.3.0. Most of the changes are recorded under its 17 pre-releases: 1.3.0rc1, 1.3.0rc2, 1.3.0rc3, 1.3.0rc4, 1.3.0rc5, 1.3.0rc6, 1.3.0rc7, 1.3.0rc8, 1.3.0rc9, 1.3.0rc10, 1.3.0rc11, 1.3.0rc12, 1.3.0rc13, 1.3.0rc14, 1.3.0rc15, 1.3.0rc16, 1.3.0rc17.
Security
- GHSA-gg2v-v5mp-jx42 (Low): a model held in a container was written in full by
pprintandjson_script, and its mapping was iterable from a template. Published for the fix shipped in 1.3.0rc17 (the "A model held in a container prints as its text…" and "A model is not a mapping to a template" entries in that section). Affected: >= 1.3.0rc1, < 1.3.0rc17. Upgrade to 1.3.0rc17 or later; the fix is in the compiled extension.