---
# GENERATED FILE — do not edit.
# Source: `manage.py docs_generate` (djust 1.3.0rc5).
# Edit the generator in docs_app/generator.py instead.
title: "Configuration reference"
description: "Every LIVEVIEW_CONFIG key with its default and meaning, generated."
level: reference
order: 90
section: reference
generated: true
---
Every key of djust's LiveView configuration, with its default, generated from
the framework's defaults and the comments written beside them.

Set keys in the `LIVEVIEW_CONFIG` dict in your Django settings; anything you
leave out keeps its default. A key placed in `DJUST_CONFIG` instead is also
honoured, but `LIVEVIEW_CONFIG` wins when both set it.

```python
# settings.py
LIVEVIEW_CONFIG = {
    "serialization_max_depth": 4,
    "rate_limit": {"rate": 200, "burst": 40},
}
```

Per-view settings are class attributes instead: see
[Class attributes](/reference/class-attributes/).

**42 keys.**

## `rate_limit`

**Type:** `dict`

Rate limiting for WebSocket events (token bucket).

| Key | Default | Description |
| --- | --- | --- |
| `rate` | `100` |  |
| `burst` | `20` |  |
| `max_warnings` | `3` |  |
| `max_connections_per_ip` | `10` |  |
| `reconnect_cooldown` | `5` |  |
| `upload_rate` | `200` | Dedicated higher-ceiling bucket for binary upload frames (#F17). Legitimate uploads are high-volume (a 10 MB file is ~157 64 KB. chunks); this is sized to let a full single-file upload land as a. burst, while a sustained flood still depletes the bucket and trips. the abuse-disconnect. |
| `upload_burst` | `400` |  |

## `worker_threads`

**Type:** `NoneType` · **Default:** `None`

Pinned session worker pool for WebSocket sync work (#3074). None. (default) = asgiref's one shared thread for every session; True /. "auto" = one thread per available CPU (max 32); an int = that many. threads. Each session stays on one thread. See djust.worker_pool.

## `max_message_size`

**Type:** `int` · **Default:** `65536`

Maximum incoming WebSocket message size in bytes (0 = no limit). 64KB.

## `event_security`

**Type:** `str` · **Default:** `'strict'`

Event security mode: "open", "warn", or "strict". "open" - no decorator check (legacy behavior). "warn" - allow unmarked methods but log deprecation warning. "strict" - only @event_handler decorated methods.

## `event_parameter_policy`

**Type:** `str` · **Default:** `'legacy'`

ADR-036: opt-in predictable signature binding and bounded conversion. Distinct from event_security, which controls callable authorization.

## `use_websocket`

**Type:** `bool` · **Default:** `True`

LiveView transport mode. Set to False to use HTTP polling instead of WebSocket.

## `websocket_compression`

**Type:** `bool` · **Default:** `True`

WebSocket per-message compression advisory flag (v0.6.0). permessage-deflate negotiation actually happens in the ASGI. server — Uvicorn/Daphne both support it by default. This flag. is the declarative "we want compression" signal that. djust_audit / debug-panel introspection surface, and that. application code can branch on (e.g. to skip a manual. JSON.stringify optimization that only helps without the. wire-level compress). Costs ~64 KB of zlib context per open. connection — disable on extreme-connection-density. deployments (100k+/worker). Override via. settings.DJUST_WS_COMPRESSION.

## `debug_vdom`

**Type:** `bool` · **Default:** `False`

Debug settings. Enable detailed VDOM patching debug logs.

## `debug_panel_max_history`

**Type:** `int` · **Default:** `50`

Maximum number of events/patches to keep in debug panel history.

## `debug_auto_open_on_error`

**Type:** `bool` · **Default:** `False`

Auto-open debug panel on first error/warning (DEBUG mode only).

## `hook_namespacing`

**Type:** `str` · **Default:** `'lax'`

Colocated JS hook namespacing (Phoenix 1.1 parity). "lax" - bare hook name, no prefix (default, compat). "strict" - prefix with <view-module>.<view-qualname> so two views. can both define `Chart` without colliding. Per-tag opt-out: {% colocated_hook "X" global %} always emits bare name. This is also readable from settings.DJUST_CONFIG["hook_namespacing"]. via the template tag (kept here for discoverability / system-check tooling).

## `auto_navigate`

**Type:** `bool` · **Default:** `True`

Automatic SPA navigation (#1734, ADR-021). When True, {% djust_client_config %} emits a <meta name="djust-auto-navigate">. flag (and auto-emits the route map, #1733) and the client installs ONE. delegated click listener that SPA-navigates plain <a href> links whose. path resolves in the (auth-filtered, #1758) route map — Turbo-Drive-. style, no djust attributes needed. Default ON as of v1.1 (ADR-021 Stage 3): native dj-navigate is djust's. canonical SPA-navigation model, so it is the zero-config default. It. degrades gracefully — links whose path does NOT resolve in the route. map (external, non-LiveView, etc.) full-reload exactly as before, and. the opt-out matrix still applies (modifier/middle-click, target/. download, hash-only, data-no-navigate). Opt OUT with. `LIVEVIEW_CONFIG["auto_navigate"] = False` (e.g. apps that wire their. own external TurboNav). On 1.0.x this defaulted OFF (opt-in).

## `reauth_on_event`

**Type:** `bool` · **Default:** `False`

Re-check auth on every WS event (#1777, threat model T3, defense-in-depth). Auth normally runs only at mount; with this OFF (default) an. authenticated user who logs out / loses a permission mid-session keeps. dispatching events on the open socket until they reconnect (the. connect-time scope user is cached). When True, handle_event re-resolves. the user from the session (channels.auth.get_user) and re-runs the. view's login_required/permission_required check, closing 4403 on. failure. Default OFF: it costs one session read per event — opt in for. high-security apps that want mid-session deauth enforced on the live path.

## `hot_reload`

**Type:** `bool` · **Default:** `True`

Hot Reload (Development). Enable hot reload in development (requires DEBUG=True).

## `hot_reload_watch_dirs`

**Type:** `NoneType` · **Default:** `None`

Directories to watch (None = auto-detect BASE_DIR).

## `hot_reload_exclude_dirs`

**Type:** `NoneType` · **Default:** `None`

Directories to exclude (None = use defaults).

## `hot_reload_auto_enable`

**Type:** `bool` · **Default:** `True`

Auto-call enable_hot_reload() from DjustConfig.ready() in DEBUG. Set to False if you orchestrate the file watcher externally (e.g. watchfiles wrapping uvicorn) and want full manual control.

## `update_check`

**Type:** `bool` · **Default:** `True`

Once-a-day notice of newer releases / security advisories on the. dev server and in `manage.py check`. Cached, silent on failure, never runs with DEBUG=False. See docs/website/guides/update-check.md.

## `hvr_enabled`

**Type:** `bool` · **Default:** `True`

Hot View Replacement (v0.6.1) — state-preserving Python code. reload in dev. Gated on DEBUG=True AND hot_reload=True.

## `time_travel_enabled`

**Type:** `bool` · **Default:** `False`

Time-travel debugging (v0.6.1) — dev-only. Master switch for. the global default (views still opt in via. `LiveView.time_travel_enabled = True`). `time_travel_max_events`. caps per-view ring buffer size (memory-bound).

## `time_travel_max_events`

**Type:** `int` · **Default:** `100`

## `bug_capture_default_scrub`

**Type:** `list` · **Default:** `[]`

Bug-capture (B7 iter B, #1562) — default scrub field names applied. by the debug panel's "Share" button before it calls. `encode_view_state()`. Empty by default (no default scrub); set. e.g. `LIVEVIEW_CONFIG['bug_capture_default_scrub'] = ["password"]`. to redact known-sensitive top-level state keys on every share. without requiring a per-call `scrub_fields(...)` argument. Only. consulted by the WS "Share" button path. (`LiveViewConsumer.handle_bug_capture_share`) — the programmatic. `encode_view_state()` API always requires an explicit `scrub`. argument from the caller.

## `jit_serialization`

**Type:** `bool` · **Default:** `True`

JIT Serialization (Phase 5). False skips JIT auto-serialization (#2984).

## `jit_debug`

**Type:** `bool` · **Default:** `False`

Debug logging for JIT serialization.

## `serialization_max_depth`

**Type:** `int` · **Default:** `3`

jit_cache_backend / jit_cache_dir / jit_redis_url and. debug_components / component_wrapper_class / component_loading_class. were removed in 1.3 (#2984): nothing read them. djust.C018 warns when. one is still set. Max depth for nested model serialization (e.g., lease.tenant.user = 3 levels).

## `strict_serialization`

**Type:** `bool` · **Default:** `False`

Serialization behavior (issue #292). When False (default): non-serializable values are converted via str() fallback with a warning log. When True: non-serializable values raise TypeError with actionable error message. Always emits warning logs before fallback, even in non-strict mode. Raise TypeError for non-serializable values instead of str() fallback.

## `loop_render_cache_enabled`

**Type:** `bool` · **Default:** `True`

Per-item loop render cache (#1967/#1969/#1970). When True, the Rust. renderer caches each loop item's rendered fragment (and parsed VNode. subtree) by a content hash and reuses them across render_with_diff(). calls, turning a pure reorder of a large keyed list from O(n). re-renders into O(changed). Default ON since #2062 (graduated after. soaking flag-OFF from v1.1.0rc5, with byte-identity ON==OFF proven. across the template matrix and the #2067 cross-loop keyspace fix. landed first). Set False to opt OUT (kill-switch). Only applies to. position-INDEPENDENT loop bodies that read nothing but the loop. variable; bodies using {% if %}/{% cycle %}/nested loops/forloop or. outer-context reads are auto-excluded (correct by construction). A view whose loop items change on almost every render turns the. cache off for itself, for the rest of that view instance's lifetime, after a streak of low-hit renders (#3071; see. RustBridgeMixin._LOOP_CACHE_BYPASS_AFTER).

## `virtual_keyed_ops`

**Type:** `bool` · **Default:** `True`

`[dj-virtual]` keyed splice ops in the VDOM differ (ADR-026, #2017. items 2-4). A windowed list holds off-window rows DETACHED, so the. index-addressed ops the differ normally emits are meaningless for it: index 7 means "the 8th item" to the differ and "the 8th VISIBLE item". to the DOM. These ops address items by KEY instead, so an insert in. the middle, a removal, or an update to an off-window row all land. correctly instead of at the tail. Wired to the process-global Rust switch once at startup by. `DjustConfig.ready()` — it is not per-view state. ADR-026 iteration 3: default ON since 1.1.0. Gated on real browser evidence (ROADMAP), and the A/B that finally. produced it needed BOTH #2185 and #2194 fixed first — until then the. list was intermittently never initialised, so the control arm was as. broken as the test arm and no comparison meant anything. Measured on. a healthy, initialised [dj-virtual] list, same start state, flag the. only variable: OFF ON. insert at position 5 pool index 60 (tail) pool index 5. remove at 3 size unchanged, k3 kept k3 gone, no dupes. reverse not reordered exact reversal. edit a scrolled row correct correct. So OFF is broken for every mid-list structural mutation on a windowed. list, and ON fixes all three without regressing the one case OFF got. right. 0 console errors, no VirtualInsert/Move/Remove warnings. Scope: the ops are emitted ONLY for a container carrying `dj-virtual`. (`emits_virtual_ops` in crates/djust_vdom/src/diff.rs), so a project. that does not use dj-virtual sees no wire change at all. Version skew: a cached PRE-1.1.0 client bundle talking to a 1.1.0+. server receives Virtual* ops its applier does not know. That degrades. to the existing patch-failure path — the client requests recovery HTML. and morphs — rather than breaking. Set this to False to opt out.

## `django_value_repr`

**Type:** `bool` · **Default:** `True`

Django-parity value rendering (#2203). When True (default), a value. interpolated with `{{ }}` renders as Python's `str()` does — which is. what Django does: {{ flag }} -> True (was: true). {{ none }} -> None (was: empty; an ABSENT variable still. renders empty, as Django's. string_if_invalid does). {{ 1.0 }} -> 1.0 (was: 1). {{ [1, 2] }} -> [1, 2] (was: the placeholder [List]). {{ {'a':1} }}-> {'a': 1} (was: the placeholder [Object]). {{ (1, 2) }} -> (1, 2) (was: [List]). This is not only cosmetic: `Display` is the lookup key for. `{% if x in some_dict %}`, so `{% if True in d %}` used to MISS where. Django hits. Set to False if a template interpolates a bool directly into a script. block — `var f = {{ flag }};` renders valid JS today and becomes a. ReferenceError under Django semantics. Django has the same hazard; its. answers are `|yesno:"true,false"` and `{{ data|json_script:"id" }}`, and those work here too.

## `template_auto_call`

**Type:** `bool` · **Default:** `True`

Django-parity template auto-call (ADR-024). When True (default), the Rust engine's sidecar getattr walk invokes callables exactly. like Django's Variable._resolve_lookup ({{ user.get_full_name }}, {{ workspace.memberships.count }}), honoring. do_not_call_in_templates and refusing alters_data. False restores. the pre-ADR plain-getattr behavior — a kill-switch only, not a. feature toggle (candidate for removal at 2.0).

## `sensitive_field_types`

**Type:** `list` · **Default:** `[]`

#1987: TYPE-based serialization floor (defense-in-depth over the. name/method floor). A list of Django field CLASS names (matched. anywhere in a field's MRO) to always exclude from client-bound. serialization — e.g. ["BinaryField", "MyEncryptedField"]. BinaryField. and best-effort encrypted-field types are excluded unconditionally; this adds project-specific types. FileField/ImageField are never. excluded (they serialize a URL).

## `css_framework`

**Type:** `str` · **Default:** `'bootstrap5'`

CSS Framework. Options: 'bootstrap4', 'bootstrap5', 'tailwind', None.

## `bootstrap4`

**Type:** `dict`

Bootstrap 4 classes (NYC Core Framework, gov sites, legacy projects).

| Key | Default | Description |
| --- | --- | --- |
| `field_class` | `'form-control'` |  |
| `field_class_invalid` | `'form-control is-invalid'` |  |
| `select_class` | `'custom-select'` |  |
| `error_class` | `'invalid-feedback'` |  |
| `error_class_block` | `'invalid-feedback d-block'` |  |
| `help_text_class` | `'form-text text-muted'` |  |
| `label_class` | `''` |  |
| `checkbox_class` | `'custom-control-input'` |  |
| `checkbox_label_class` | `'custom-control-label'` |  |
| `checkbox_wrapper_class` | `'custom-control custom-checkbox'` |  |
| `radio_class` | `'custom-control-input'` |  |
| `radio_label_class` | `'custom-control-label'` |  |
| `radio_wrapper_class` | `'custom-control custom-radio'` |  |
| `field_wrapper_class` | `'form-group'` |  |
| `button_primary_class` | `'btn btn-primary'` |  |
| `button_secondary_class` | `'btn btn-secondary'` |  |

## `bootstrap5`

**Type:** `dict`

Bootstrap 5 classes.

| Key | Default | Description |
| --- | --- | --- |
| `field_class` | `'form-control'` |  |
| `field_class_invalid` | `'form-control is-invalid'` |  |
| `select_class` | `'form-select'` |  |
| `error_class` | `'invalid-feedback'` |  |
| `error_class_block` | `'invalid-feedback d-block'` |  |
| `help_text_class` | `'form-text'` |  |
| `label_class` | `'form-label'` |  |
| `checkbox_class` | `'form-check-input'` |  |
| `checkbox_label_class` | `'form-check-label'` |  |
| `checkbox_wrapper_class` | `'form-check'` |  |
| `radio_class` | `'form-check-input'` |  |
| `radio_label_class` | `'form-check-label'` |  |
| `radio_wrapper_class` | `'form-check'` |  |
| `field_wrapper_class` | `'mb-3'` |  |
| `button_primary_class` | `'btn btn-primary'` |  |
| `button_secondary_class` | `'btn btn-secondary'` |  |

## `tailwind`

**Type:** `dict`

Tailwind CSS classes.

| Key | Default | Description |
| --- | --- | --- |
| `field_class` | `'block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm'` |  |
| `field_class_invalid` | `'block w-full rounded-md border-red-300 pr-10 text-red-900 placeholder-red-300 focus:border-red-500 focus:outline-none focus:ring-red-500 sm:text-sm'` |  |
| `error_class` | `'mt-2 text-sm text-red-600'` |  |
| `error_class_block` | `'mt-2 text-sm text-red-600'` |  |
| `label_class` | `'block text-sm font-medium text-gray-700'` |  |
| `checkbox_class` | `'h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500'` |  |
| `checkbox_label_class` | `'ml-2 block text-sm text-gray-900'` |  |
| `checkbox_wrapper_class` | `'flex items-center'` |  |
| `field_wrapper_class` | `'mb-4'` |  |
| `button_primary_class` | `'inline-flex justify-center rounded-md border border-transparent bg-indigo-600 py-2 px-4 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'` |  |
| `button_secondary_class` | `'inline-flex justify-center rounded-md border border-gray-300 bg-white py-2 px-4 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2'` |  |

## `plain`

**Type:** `dict`

Plain HTML (no framework).

| Key | Default | Description |
| --- | --- | --- |
| `field_class` | `''` |  |
| `field_class_invalid` | `'error'` |  |
| `error_class` | `'error-message'` |  |
| `error_class_block` | `'error-message'` |  |
| `label_class` | `''` |  |
| `checkbox_class` | `''` |  |
| `checkbox_label_class` | `''` |  |
| `checkbox_wrapper_class` | `''` |  |
| `field_wrapper_class` | `''` |  |
| `button_primary_class` | `'button primary'` |  |
| `button_secondary_class` | `'button secondary'` |  |

## `render_labels`

**Type:** `bool` · **Default:** `True`

Field rendering options.

## `render_help_text`

**Type:** `bool` · **Default:** `True`

## `render_errors`

**Type:** `bool` · **Default:** `True`

## `auto_validate_on_change`

**Type:** `bool` · **Default:** `True`

## `service_worker`

**Type:** `dict`

Service worker (v0.5.0 P3) — opt-in instant shell + reconnection bridge. These values are informational for tooling / system checks; the. actual runtime knobs live in the client-side registration call. (`djust.registerServiceWorker({...})`) and in the SW itself.

| Key | Default | Description |
| --- | --- | --- |
| `main_selector` | `'main'` | element whose innerHTML is the "main" swap target. |
| `shell_cache_name` | `'djust-shell-v1'` | Cache API bucket key for the cached shell. |
| `reconnect_buffer_cap` | `50` | max buffered WS messages per connection id. |
| `vdom_cache_enabled` | `True` | VDOM patch cache (v0.6.0) — per-URL HTML snapshots served. instantly on popstate, then reconciled against the live. WebSocket mount reply. Top-level setting aliases are. `DJUST_VDOM_CACHE_ENABLED` / `DJUST_VDOM_CACHE_TTL_SECONDS`. / `DJUST_VDOM_CACHE_MAX_ENTRIES`. |
| `vdom_cache_ttl_seconds` | `1800` | 30 minutes. |
| `vdom_cache_max_entries` | `50` |  |
| `state_snapshot_enabled` | `True` | State snapshot (v0.6.0) — opt-in per-view via. `LiveView.enable_state_snapshot = True`. Master switch. also toggled via `DJUST_STATE_SNAPSHOT_ENABLED`. |

## `loading_grouping_classes`

**Type:** `list` · **Default:** `['d-flex', 'btn-group', 'input-group', 'form-group', 'btn-toolbar']`

@loading attribute configuration (Phase 5). Bootstrap flex container. Bootstrap button group. Bootstrap input group. Bootstrap form group. Bootstrap button toolbar.
