django-unicorn: reactive Django components without a JavaScript build step
The magical reactive component framework for Django ✨
At a glance
- What is it?
- django-unicorn adds reactive components to Django templates using unicorn: attributes and a Python view class per component. It suits Django teams who want interactivity without a separate frontend framework, and it is a poor fit for offline-first or heavily client-side apps.
- Who is it for?
- Adopt django-unicorn if your team already writes Django templates and wants interactivity without a JavaScript build pipeline or a second templating language. Skip it if your UI must work offline, if most state lives in the browser, or if you need a client-side router.
- 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 131 days 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 September 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What django-unicorn solves, and for whom
Django renders HTML on the server. That model breaks down the moment a page needs a live search box, an inline form that validates as you type, or a list you can add to without a full page reload. The usual answers are to add a JavaScript framework and duplicate your data model in the browser, or to hand-write fetch calls and DOM updates.
django-unicorn takes a third path. It lets you keep Django templates and Python classes and still get reactive behaviour. The README describes it as adding "modern reactive component functionality to your Django templates without having to learn a new templating language or fight with complicated JavaScript frameworks." A component is a pair of files: a Django HTML template and a Python view class holding the backend code. If you can write a Django view and a template, you already know most of the model.
The intended reader is a Django developer on a server-rendered app who needs pockets of interactivity, not a single-page application. It is less interesting if your team already has a React or Vue codebase and a build pipeline, because you would be adding a second way of doing the same job.
How a unicorn component actually works
A component is rendered by the {% unicorn 'COMPONENT_NAME' %} template tag. The tag emits HTML plus the unicorn: attributes you wrote on the elements inside it. Those attributes bind an element to a field on the component's Python class and can trigger methods on events such as click, input and keydown.
When a bound event fires, the browser sends an AJAX request to the endpoint registered by django_unicorn.urls. The server calls the matching method on the component class, re-renders the component template, and returns the new HTML. The client swaps the DOM. The README's three-step description of this is: the initial render is a normal Django view, unicorn binds to the elements you specify and makes AJAX calls when needed, and it updates the DOM when the HTML changes.
Two details matter in practice. First, the initial page is server-rendered, so search engines see real HTML. Second, the component's Python class holds the state that the round trip mutates, which is why form validation and redirects can live on the server side. The framework ships a JavaScript bundle built with rollup (package.json defines build, test and watch:test scripts), but you do not author against it.
Installing django-unicorn and building a first component
Install the package with the manager you already use. The README lists uv, pip and poetry as options; the pip form is below.
pip install django-unicornAdd the app to INSTALLED_APPS. The README shows the entry as a string in the tuple, with a comment marking where your other apps go.
# settings.py
INSTALLED_APPS = (
# other apps
"django_unicorn",
)Register the URLs. The include path is your choice; the README uses "unicorn/".
# urls.py
import django_unicorn
urlpatterns = (
# other urls
path("unicorn/", include("django_unicorn.urls")),
)Load the template tag library and render the scripts tag in the head. The README's example also places {% csrf_token %} in the body, which the AJAX requests need.
<!-- template.html -->
{% load unicorn %}
<html>
<head>
{% unicorn_scripts %}
</head>
<body>
{% csrf_token %}
</body>
</html>Scaffold a component with the management command. It creates two files: myapp/templates/unicorn/COMPONENT_NAME.html and myapp/components/COMPONENT_NAME.py.
python manage.py startunicorn myapp COMPONENT_NAMEThen place the component in a template with {% unicorn 'COMPONENT_NAME' %}. The README's todo example shows the binding style: unicorn:submit.prevent="add" on a form, unicorn:model.defer="task" on the input, and unicorn:keyup.escape="task=''" to clear the field. The Python side subclasses UnicornView and can declare form_class with a Django Form, which is how is_valid() becomes available inside the component's methods. If everything is wired correctly, submitting the form appends to the tasks list and re-renders the list without a page reload.
Where django-unicorn is the wrong tool
Every interaction is a network round trip. A component method runs on the server, so a keystroke bound with unicorn:model without .defer will produce a request per keystroke. The README's own example uses unicorn:model.defer on the task input, which is the mitigation, but the underlying constraint stands: this is not a client-side state machine.
That rules out a few cases. If your users are on flaky connections or need the app to keep working offline, a server round trip per interaction is the wrong architecture. If a screen is dominated by client-side state, such as a canvas editor or a drag-heavy board, you will spend your time fighting the model. And if you need a client-side router with deep links into client state, django-unicorn does not provide one; it enhances server-rendered pages.
There is also a version caveat worth reading carefully. pyproject.toml declares dependencies as django>=2.2 with the comment that the project is "Deliberately loose on dependencies even though only newer Django versions are officially tested/supported." A loose lower bound is not a compatibility promise. Check the tested matrix before pinning an old Django.
django-unicorn compared with htmx
The most common comparison is htmx, and the difference is where the component boundary lives. With htmx you annotate plain HTML with attributes that tell the browser which URL to request and which part of the page to replace; the server returns an HTML fragment. There is no component class, no per-component Python file, and no framework-specific template tag. The unit of reuse is whatever fragment your view returns.
django-unicorn adds a Python class per component. That class holds typed fields, can declare a Django Form via form_class, and exposes methods that events call by name. In exchange for that structure you get server-side validation wired into the component, and a naming convention that makes a component a single addressable thing across templates. The trade is more framework surface: a management command, a URL include, a template tag library, and a JavaScript bundle that the project builds and ships. htmx leaves all of that to you.
If your team wants the smallest possible dependency and is comfortable writing fragment views by hand, htmx is the lighter choice. If you want the component to be a first-class Python object with validation and a generated file layout, django-unicorn gives you that.
Maintenance, upgrade cost and the MIT licence
The repository is not archived. The last push was on 2026-05-22, roughly four months before this writing, and the most recent release listed is 0.67.0 on 2026-03-07, following 0.66.1 and 0.66.0 earlier that month. That is a project with recent activity, but the version number is still 0.x, which in practice means the maintainers have not promised API stability.
Upgrade cost has two halves. The Python package is on PyPI and installs with pip, uv or poetry, so bumping it is a one-line change. The JavaScript side is bundled and shipped with the package, so you do not rebuild it yourself unless you are working on the framework; the justfile in the repository exposes js-build, js-install and a set of pytest targets for contributors, not for consumers. That is a real advantage over frameworks that ask you to run a Node toolchain in your own deployment.
The licence is MIT, declared in pyproject.toml with the classifier "License :: OSI Approved :: MIT License" and a LICENSE file at the repository root. MIT is permissive and imposes no copyleft obligation on your application, but this is a description of what the repository states, not legal advice; read the LICENSE file and your own counsel's guidance if the distinction matters to you.
Editorial conclusion
Adopt django-unicorn if your team already writes Django templates and wants interactivity without a JavaScript build pipeline or a second templating language. Skip it if your UI must work offline, if most state lives in the browser, or if you need a client-side router. Before committing, verify three things: that your Django version is one the project tests against (pyproject.toml declares django>=2.2 but notes only newer versions are officially tested), that your deployment can serve the django_unicorn.urls endpoint at the path you choose, and that your templates can include the {% csrf_token %} tag, since the README's setup example places it in the base template.
Frequently asked questions
What is django-unicorn used for?
It adds reactive component behaviour to Django templates so you can build interactive UI, such as a todo list that updates without a page reload, while keeping server-rendered HTML and Python view classes. The README describes it as a way to add rich front-end interactions without learning a new templating language.
How do I install django-unicorn?
Install the package with pip, uv or poetry, add "django_unicorn" to INSTALLED_APPS, and include django_unicorn.urls in your URL configuration. You then load the unicorn template tag library and render {% unicorn_scripts %} in your base template.
How is django-unicorn different from htmx?
django-unicorn gives each component a Python class that holds fields and methods, plus a management command that scaffolds a template and a view file. htmx works on plain HTML attributes and server-returned fragments with no component class, so it has less framework surface but no built-in component object.
What licence does django-unicorn use?
MIT. pyproject.toml declares license = { text = "MIT" } and the OSI Approved :: MIT License classifier, and the repository root contains a LICENSE file.
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/django-commons-django-unicorn)