Home Features Security Examples Quick Start
v0.1.0 Alpha Release

Client-Side Behavior.
Server-Side Code.

Build reactive, real-time applications with Django and Python. No JavaScript required. Powered by a high-performance Rust VDOM engine.

Install Package
$ pip install djust

State Management Primitives

Complex client-side behavior, declared in Python. djust provides a suite of decorators that handle the hard parts of frontend development for you.

@debounce

Delay server requests until the user stops typing. Perfect for search inputs.

@debounce(wait=0.5)
def search(self, query):
  self.results = ...
@optimistic

Update the UI instantly, validate on the server later. Zero latency feel.

@optimistic
def like(self):
  self.liked = True
@cache

Cache responses client-side. Instant results for repeated queries.

@cache(ttl=300)
def get_cities(self):
  return Cities.all()
@client_state

Sync multiple components instantly without a server roundtrip.

@client_state(keys=['tab'])
def switch_tab(self, tab):
  self.tab = tab
shadcn/ui for Django

Copy. Paste. Own.

Stop fighting with npm packages. djust uses a component-as-code philosophy. Copy our components into your project and customize them to your heart's content.

  • Framework Agnostic Switch between Bootstrap 5 and Tailwind CSS with a single config setting.
  • Two-Tier Architecture Use lightweight Component for static UI and powerful LiveComponent for interactive widgets.
Browse Component Library
components/navbar.py
class Navbar(Component):
    def render(self):
        framework = config.get('css_framework')

        if framework == 'bootstrap5':
        elif framework == 'tailwind':
            return self._render_tailwind()

        return self._render_plain()
Performance Magic

The End of N+1 Queries.

The #1 performance killer in Django apps is the N+1 query problem. djust solves it automatically.

Our compiler analyzes your templates to see exactly which fields you use (e.g., {{ book.author.name }}). It then automatically injects the optimal select_related calls into your QuerySet.

See How It Works
Without djust
With djust
Template:
{% for book in books %}
  {{ book.author.name }}
{% endfor %}
SQL Queries:
SELECT * FROM books
SELECT * FROM authors WHERE id=1
SELECT * FROM authors WHERE id=2
... (100 more)
Template:
{% for book in books %}
  {{ book.author.name }}
{% endfor %}
SQL Queries:
SELECT * FROM books
JOIN authors ON ...
// 1 Query Total