Design Document: Live Components for django-components
#1366
Replies: 3 comments 12 replies
-
Sounds interesting. Maybe check if Datastar could help which is too new to be well known/considered by AI. If streams should go mainly from server to client it may be a good choice with its SSE foundation. It does the fine-grained DOM diffing already now. |
Beta Was this translation helpful? Give feedback.
-
What's the appeal of this approach? Is it to be able to write UI user event handlers in Python? I'm not fan of this paradigm. To me it feels like the same like how PHP was looked down upon because it was known for mixing UI and server logic. Also because abstracting JS away behind Python inevitably means that you will limit what people can do. And they then have to rely that you will implement the features they're missing. In this sense, I see "No JS" frameworks as false promise
On APIBecause with abstracting JS behind Python, while you gain that you can react to user events in Python, you lose the logic separation.
So with that in mind, that's why when it comes to any sort of features that deal with incoming data (HTTP / websocket, etc), I think they should be scoped in a nested class to show clear separation from the rendering logic. Same thing how I also suggested the Tetra framework integration to have an API like so: from django_components import Component
class Table(Component):
class Tetra:
title = public("")
done = public(False)
@public.watch("title", "done")
@public.debounce(200)
def save(self, value, old_value, attr):
self.todo.title = self.title
self.todo.done = self.done
self.todo.save() ThoughtsBut to each their own, so some thoughts on this:
OtherThere is django-livecomponents. Don't know if the package is publicly available on PyPI. It's based on some old version of django-components, some ~v0.20. They use HTMX and Alpine. I'm actually having a call with their CEO/CTO tomorrow. They'd like to upgrade, but they want to wait for django-components v1. And they might sponsor us to get there. |
Beta Was this translation helpful? Give feedback.
{{title}}
-
One major risk to consider is latency: even on internal corporate networks, you will have at least ~80/100ms of latency for every roundtrip. Something most users won't notice but, if you start to attach mouse-hover/focus events, it will be immediately noted by users and the UX will fill clunky. Additionally, any kind of problem between the user and the application (slow network, server load, ecc ecc) will immediately affect UX. The need of extra dependencies(django-channels & redis) and network roundtrips will increase complexity and make debugging and tracing more complicated. Think about out of order events: handling clicks locally is deterministic, w/ network in the middle it's no more the case (En can be handled before En-1). This will lead to weird bugs very hard to debug. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone! Here's a heavily AI-authored design document for "LiveComponents", a new extension for DJC. Thoughts?
Executive Summary
django-components
today is a powerful way to encapsulate HTML, templates, and logic into reusable components inside Django projects. However, its execution model is still page/request-based: the browser reloads or re-renders on every action.This proposal introduces Live Components: server-owned, stateful components that render themselves as normal Django templates, but can update their DOM in place over a WebSocket (or HTTP fallback). Developers continue to write plain HTML templates and Python classes, but user interactions (clicks, submits, navigation) are automatically routed back to the server, where the component updates its state and returns fresh HTML fragments.
The goal: rich, reactive UI without writing JavaScript or custom HTML DSLs. The design is deliberately similar to Phoenix LiveView or Laravel Livewire, but built on the foundations of
django-components
.Goals
button
,form
,a href
,input
). Nodata-*
attributes required.Component
,self.id
(unique render ID), and fragment rendering for patches.Architecture
Server Side
1. LiveComponent Mixin
Extends
django_components.Component
:state
(dict or dataclass).assign(**kwargs)
→ updates state, re-renders fragment, returns{component_id, html}
patch.def save(self, evt): …
) that correspond to standard HTML intents (button/form names).2. Routing Events
Incoming payloads (from client) look like:
Dispatcher finds the right
LiveComponent
instance, invokesinc(evt)
, and returns a patch.3. Rendering Fragments
Use djc’s existing fragment rendering (
deps_strategy="fragment"
) so only inner HTML and missing JS/CSS assets are sent. Dependencies are handled automatically.4. Transport Layer
/live
).Component.View
(public=True
) for environments without WS.{component_id, html}
(and optionallytarget_id
) to patch.Client Side
1. Event Delegation
A global script attaches listeners for:
click
(buttons, inputs, links)submit
(forms)change
/input
(inputs, selects, checkboxes, radios)2. Component Root Resolution
Every component instance already has a unique
id
(self.id
, e.g.,c1A2b3
).On event, runtime finds nearest ancestor with
id^="c"
and uses that ascomponent_id
.3. Intent Derivation (no DSL)
name
(preferred), elsevalue
, else text fallback.evt.submitter.name
.navigate(href)
; if link hasname
/value
→ action click.change
produces{field, value}
payload.4. Sending & Receiving
{component_id, html}
.document.getElementById(component_id).innerHTML = html
.5. Progressive Enhancement
Example Flow
Template (unchanged Django):
Component (Python):
User clicks “+”:
c1A2b3
→ payload{type:"click", intent:"inc"}
.inc()
, updates state, re-renders fragment.{component_id:"c1A2b3", html:"<p>Count: 1</p>…"}
.Implementation Plan
Prototype (
djc_ext_live
)LiveComponentMixin
withstate
,assign()
, anddispatch_intent()
./live
.Integrate with djc
self.id
and fragment rendering.Component.View
for HTTP fallback.Patching Strategies
innerHTML
replacement.Security & Scaling
request.user
into component methods.Developer Experience
name
(ambiguous intents).Non-Goals (for v1)
Risks & Mitigations
name
. Mitigate via dev-mode console warnings.navigate()
enhances UX but isn’t required.Conclusion
By adding a small Live extension,
django-components
can leap from “static component rendering” to a reactive component model without requiring users to learn React, Vue, or a custom DSL. Templates stay plain HTML, logic stays Python, and the client runtime remains minimal. This design respects Django’s philosophy (HTML-first, server-driven, progressive enhancement) while delivering the interactivity expected from modern web apps.Beta Was this translation helpful? Give feedback.
All reactions