djust brings Phoenix LiveView-style reactivity to Django with a Rust core
Phoenix LiveView-style reactive server-side rendering for Django with Rust-powered performance
At a glance
- What is it?
- djust is a Django library that adds reactive server-side rendering over WebSockets, using a Rust-powered virtual DOM. It targets teams that want LiveView behavior without writing JavaScript, but it carries real constraints around template syntax and deployment.
- Who is it for?
- Adopt djust if you are a Django team that wants reactive UI without a JavaScript build step, and you can accept WebSocket infrastructure and a strict template syntax. Skip it if your templates rely heavily on one-sided conditionals inside attributes, or if you need a mature ecosystem with many community components.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.
Star history
- djust-org/djust101 ★ · +11
| Repository | 2026-08-27 | 2026-10-21 |
|---|---|---|
| djust-org/djust | 90 | 101 |
11 Stars in the last 55 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The problem djust solves
Django's classic request-response cycle forces a full page reload for every state change. That is fine for admin panels and content sites, but it is painful for interactive UIs like counters, dashboards, or collaborative forms. The usual escape is to add a JavaScript framework, which brings a bundler, a build step, and a second language to maintain. djust attacks that problem directly: you write server-side Python, and the client updates automatically over a WebSocket. The intended user is a Django developer who wants LiveView-style interactivity without leaving Python. The README is explicit that there is no JavaScript to write and no bundler. This is a narrow but real niche, and djust fills it with a familiar Django API.
How the Rust-powered VDOM works
The core mechanism is a virtual DOM written in Rust. When a LiveView renders, djust produces HTML, and the client receives it. On a state change, the server re-renders the component, diffs the new HTML against the old, and sends only the changed patches over a WebSocket. The template engine and the parsing are also in Rust, which is where the performance claim comes from. The README says djust is roughly 7 to 11 times faster than Django on variable- and filter-heavy templates, and no faster on static markup. That distinction matters: the speedup is not universal. The reactive boundary is marked with a dj-root attribute, and only the HTML inside that boundary is diffed. Static content outside it is never touched by VDOM patching, which limits the diffing cost. The client runtime is about 58 KB gzipped, and djust auto-injects it into every LiveView response via the djust_client_config template tag. That is a clever way to avoid a manual script tag, but it also means every LiveView page carries that payload unless you configure otherwise.
Getting started: real commands and config
Installation is straightforward: pip install djust django-channels. Then you add 'channels' and 'djust' to INSTALLED_APPS, set ASGI_APPLICATION, and configure a channel layer. The README shows an in-memory layer for development, which is fine for a single process but not for a multi-worker deployment. The asgi.py file must be replaced with a ProtocolTypeRouter that routes HTTP to Django and WebSocket to the LiveViewConsumer at a path like ws/live/. The view class inherits from LiveView, defines a mount method to initialize state, and uses the event_handler decorator to mark methods that respond to client events. Templates need three markers: djust_client_config in the head, dj-view on the body to identify the WebSocket session, and dj-root on the reactive container. The counter example is small but complete, and it shows the intended workflow: define a view, write a template, and the reactivity appears without any client-side code.
Template constraints: the one-sided if pitfall
The most concrete limitation documented is the one-sided if inside an attribute value. If you write something like class="card {% if active %}active{% endif %}", djust's VDOM patching can misalign because of its branch-aware div-depth counting. The README gives two correct alternatives: use a full if/else, or move the conditional outside the tag. This is a real constraint that will bite anyone porting an existing Django template that uses conditional classes. The README says this applies only to attribute values, and that if blocks in element content work fine. But it is a sign that djust's template parser is stricter than Django's own. Teams with large legacy templates should expect to audit every attribute that contains a conditional. The documentation points to a VDOM Architecture guide and a Template Cheat Sheet for full details, which suggests more such rules exist beyond what the README shows.
Stable list identity and patch efficiency
For lists that reorder or have items inserted or deleted, djust supports a data-key or dj-key attribute on each item. With a key, the diffing emits MoveChild patches instead of remove-then-insert pairs. That preserves DOM state like focus, scroll position, and animations. Without a key, djust diffs by position, which is correct but produces more DOM mutations for reorders. This is a practical detail that matters for chat feeds, sortable tables, or any list where the user is interacting with an element that could move. The README does not say what happens if keys are duplicated or missing on some items, so that is a gap to verify. The feature shows that djust is not just a toy: it handles the hard part of list reconciliation, which is what separates a usable reactive framework from a simple re-render loop.
Limitations: WebSocket dependency and fallback
djust's reactivity depends on a WebSocket connection. The README mentions an HTTP fallback for real-time DOM patches, but it does not explain how that works or when it triggers. That is a significant unknown. If a client cannot open a WebSocket, the fallback might mean full page reloads, or it might mean polling. The documentation is silent on the details. Another limitation is the need for ASGI. Django's traditional WSGI deployment will not work for the WebSocket consumer, so teams on Apache or gunicorn with WSGI must switch to an ASGI server like Daphne or Uvicorn. The in-memory channel layer in the quick start is not suitable for production with multiple processes, because events would not propagate across workers. The README does not mention Redis or a database-backed layer, but Channels supports those, and you would need one for a real deployment. None of this is a dealbreaker, but it is a deployment cost that the README glosses over.
Alternatives and ecosystem comparison
The closest alternative is Phoenix LiveView itself, which runs on Elixir and the Erlang VM. The difference is the language: LiveView requires you to move to Elixir, while djust lets you stay in Python and Django. That is the main appeal. On the Python side, the comparable project is Unicorn, which also does server-side reactive rendering for Django. Unicorn uses a different mechanism: it does not use a Rust VDOM, and its diffing is less sophisticated. Unicorn also has a smaller feature set, but it has been around longer and has a simpler setup (no ASGI required, it works over HTTP with a small JavaScript library). The trade-off is performance: Unicorn sends full component HTML on each update, while djust sends minimal patches. If you need the performance and you can handle the Rust dependency, djust is the stronger choice. If you want a simpler deployment without WebSockets, Unicorn is the pragmatic alternative. The README also mentions TurboNav compatibility, which suggests djust is designed to work with Turbo-style navigation, but that is an integration detail, not a full alternative.
Maintenance and license implications
djust is under the MIT license, which is permissive and allows commercial use, modification, and redistribution. The repository has recent activity: the last push was August 2026, with a v1.1.0 release on the same day, and release candidates in July. That suggests active development, but the project is young, and the version number is still 1.x. The maintenance cost for adopters is tied to the Rust core: you need a toolchain that can compile the Rust extension, or you rely on prebuilt wheels. The README does not mention wheel availability, so that is a risk. Upgrades may introduce changes to the template parsing rules or the VDOM algorithm, which could break existing templates. The documentation mentions a debug panel and VDOM inspection, which is a good sign for troubleshooting, but it is not a substitute for a stable API. Before adopting, check whether the project has a migration guide for version 1.1.0 and whether the Rust build is reproducible on your target platforms.
Editorial conclusion
Adopt djust if you are a Django team that wants reactive UI without a JavaScript build step, and you can accept WebSocket infrastructure and a strict template syntax. Skip it if your templates rely heavily on one-sided conditionals inside attributes, or if you need a mature ecosystem with many community components. Before committing, verify that your deployment supports ASGI and Channels, test the 7-11x performance claim against your own variable-heavy templates, and review the VDOM architecture guide for the full list of template constraints.
Frequently asked questions
How do I install djust in an existing Django project?
Add channels and djust to INSTALLED_APPS, set ASGI_APPLICATION, configure CHANNEL_LAYERS, then route ws/live/ to LiveViewConsumer.as_asgi() through AuthMiddlewareStack inside a ProtocolTypeRouter. A view subclasses LiveView, a URL uses CounterView.as_view(), and the template loads live_tags and puts djust_client_config in the head.
Does djust need a JavaScript build step?
No. The client runtime, about 70 KB gzipped, is injected automatically into every LiveView response, so you never add a script tag and there is no bundler. The repository does contain JavaScript with its own vitest and eslint setup, but that is for developing the runtime rather than for building your project.
Can I use the djust template backend without LiveView?
Yes. Point a TEMPLATES entry at djust.template_backend.DjustTemplateBackend and your existing TemplateView classes, render() calls and includes go through Rust with no WebSocket and no client runtime. Django's own backend stays in the list because admin and contrib templates still need it.
How compatible is the djust template backend with the Django template language?
1032 of the 1,047 cells in Django's own template_tests suite pass unmodified, which is 98.57%, measured by scripts/run-django-template-suite.py against the Django tag matching the installed version. The remaining cells are itemised in docs/TEMPLATE_BACKEND.md.
Is djust a stable release, and which Django versions does it support?
The newest tag is v1.3.0rc6, published on 2026-09-28, and the package classifier still reads Development Status :: 3 - Alpha. Python 3.10 or newer is required, and the classifiers list Django 4.2 through 5.2, with free-threading support marked beta.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/djust-org-djust)Star history chart for your README
[](https://hysenlabs.com/projects/djust-org-djust)