Open-source project
django-components/django-components avatar
django-components/django-components

django-components for reusable Django UI components

Create simple reusable template components in Django.

1,515 stars97 forksPythonMIT

At a glance

What is it?
django-components brings component-style HTML, CSS, JavaScript, and Python logic to Django templates. It fits teams that want reusable UI units without leaving Django, but its component API adds conventions that projects must adopt consistently.
Who is it for?
Adopt django-components when a Django project needs reusable UI units with colocated templates, styles, scripts, and Python data preparation. Do not choose it for a project that only needs ordinary Django template includes or has no appetite for component registration and data-flow conventions.
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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Django components with Python, templates, and browser assets

django-components addresses a specific problem in Django applications: repeated interface elements tend to spread across templates, views, static files, and JavaScript code. A product card, calendar, navigation area, or form control may need its markup, styling, browser behavior, and server-side data preparation kept in one place. The package gives those pieces a component abstraction while retaining Django templates and Python classes.

The intended audience is developers building small or large Django applications who want reusable UI elements without adopting a separate frontend framework. The README describes the project as a modular and extensible UI framework for Django. It also states that components can include their own HTML, CSS, and JavaScript, or load additional third-party JavaScript and CSS. That combination is the central design choice. The package does not replace Django templates. It adds a component boundary around them.

This approach is most useful when the same interface is used from several templates and when its browser behavior belongs with its visual structure. A plain Django include can share markup, but it does not by itself provide the same component-level organization for class data, JavaScript variables, CSS variables, registration, or media handling. The value depends on how consistently a project uses that boundary. A small site with few repeated UI patterns may gain more from direct template reuse than from introducing a component layer.

How a component processes template, JavaScript, and CSS data

The README's product card example defines a class that inherits from `Component` and registers the name `product_card` with `@register`. The class points to three files through `template_file`, `js_file`, and `css_file`. Its `Kwargs` class declares `product_id`, `show_price`, and `theme`, including the default values `True` and `"light"`.

Rendering follows separate preparation paths. `get_template_data` retrieves a `Product`, then returns template values such as `product`, `show_price`, and `is_in_stock`. `get_js_data` returns a smaller payload for browser behavior, including `product_id`, `price`, and `api_endpoint`. `get_css_data` chooses theme variables from a dictionary. These callbacks make the data boundary visible in code rather than requiring one shared context to serve every layer.

The HTML template consumes the template data. The JavaScript file receives its data through the `$onComponent` callback, while the CSS file consumes CSS custom properties such as `--card_bg` and `--text_color`. This means the rendered component can derive markup, behavior, and styling from the same component class without requiring every layer to expose identical data. It also creates a design constraint. Developers must understand which data belongs in `get_template_data`, `get_js_data`, or `get_css_data`, and should avoid fetching the same database object independently in more than one callback unless that duplication is intentional.

Registering and rendering a product card

The README presents a first use through a Django template tag. The component receives a product identifier, theme, and price visibility flag, then closes with `{% endcomponent %}`. The following example is copied from the quickstart and uses the component as a normal part of a Django template.

django
{% component "product_card"
  product_id=123
  theme="dark"
  show_price=True
%}
{% endcomponent %}

Before this template can render, the component class must exist and the referenced template, JavaScript, and CSS files must be available at the paths declared by the class. The example places the component files under `components/product_card/` and the Django template under `templates/product_card/product_card.html`. The README does not document an installation command in its quickstart, so there is no command to reproduce here. The package is identified as the PyPI project `django-components`, and its documentation and sample project are linked from the README.

The rendered result shown in the README contains the product image, name, price, and an add-to-cart button when the product is in stock. It also includes a `data-product-id` attribute and a generated `data-djc-css-a1b2c3` attribute. The latter is part of the README's example output, not a configuration value that should be copied into application code.

The component class as a small application boundary

The package supports both file-backed and inline definitions. In the README's calendar example, `template`, `css`, and `js` are assigned strings on the class. The JavaScript adds a click listener to `.calendar`, and the template renders `{{ date }}`. The example also defines a `Media` class with an external htmx script and a Bootstrap stylesheet.

That flexibility affects code organization. File-backed components are easier to navigate when templates and browser assets are substantial. Inline definitions can keep a small component in one Python file. The choice also affects review and tooling. A project needs a consistent convention so a maintainer can predict whether to look in Python, a template file, a static asset directory, or all three.

The component name is supplied through `@register`, and templates select it through the `component` template tag. This registration mechanism makes the component addressable from Django templates, but it also means names and import paths become part of the application's wiring. The README does not specify a namespace, discovery policy, or deployment command for automatically finding components. Those details should be confirmed in the full documentation before adopting the package in a project with strict naming rules.

Installation constraints and upgrade responsibilities

The `pyproject.toml` identifies the distribution as `django_components`, version `0.152.0`, and requires Python `>=3.10, <4.0`. It depends on `Django>=5.2`, `djc-core>=1.3.1`, and `typing-extensions>=4.12.2`. The project classifiers list Django 5.2 and Django 6.0, along with Python 3.10 through Python 3.14.

The repository is not archived. Its last push was on 2026-10-13, shortly before the repository facts were recorded. Recent releases include `0.152.0` on 2026-08-22, `0.151.1` on 2026-06-25, and `0.151.0` on 2026-06-03. These dates show recent release activity, but they do not establish compatibility with every Django project. The package metadata is the first compatibility checkpoint to inspect, especially because the minimum Django version is `5.2` and Python must be at least `3.10`.

The MIT license permits use and modification under its terms, subject to the license text. Teams still need to review dependency licenses and their own distribution obligations. The README does not provide a project-specific migration or rollback procedure. Upgrade planning should therefore include checking the changelog and documentation for changes to template tags, component registration, data callbacks, and media handling.

Where django-components differs from ordinary Django includes

A Django template include is a simpler alternative when the requirement is only to reuse markup. It can render another template with the surrounding context and does not require a component class, JavaScript callback, CSS data callback, or registration decorator. For a static partial with little behavior, that simplicity can be preferable.

`django-components` adds a different approach. It gives a named interface a Python class, declared keyword arguments, separate template, JavaScript, and CSS data hooks, and optional external media. Its purpose is closer to organizing an interface unit than to merely including a partial. The README positions the project between Django's templating system and the modularity associated with frontend frameworks such as Vue and React, while keeping the implementation in the Django ecosystem.

The trade-off is that the additional structure has a cost. A team must decide where data preparation belongs, keep callbacks and files synchronized, and follow the package's template syntax and media conventions. If those conventions are already used across a large application, the abstraction can remove duplication. If the application has only a few templates, adopting it may add more coordination than it removes.

Practical limits of the documented component model

The quickstart example retrieves a `Product` independently in both `get_template_data` and `get_js_data`. That makes the example clear, but it also illustrates a possible inefficiency: one render can issue more than one database lookup when both callbacks need the product. The README does not provide a caching helper or explain how the framework coordinates repeated queries. Projects should account for this when components become data-heavy.

The example also assumes application-specific objects and APIs, including `Product.objects`, `Product.image_url`, `Product.price`, `Product.stock_count`, and an endpoint shaped as `/api/products/{product_id}/`. Those pieces are not supplied by `django-components`. A missing model, media file, JavaScript file, or endpoint will affect the rendered result or browser behavior independently of the component framework.

The README does not document rollback, production asset collection, component caching, database query behavior, or a complete troubleshooting workflow. Those omissions are not proof that the features or operational guidance are absent from the full documentation. They are concrete questions to resolve before adopting the package in a production application.

Editorial conclusion

Adopt django-components when a Django project needs reusable UI units with colocated templates, styles, scripts, and Python data preparation. Do not choose it for a project that only needs ordinary Django template includes or has no appetite for component registration and data-flow conventions. Verify Python and Django compatibility first, then confirm that your team accepts the component and media model.

Frequently asked questions

How do I install django-components in a Django project?

The repository identifies `django-components` as a PyPI package and documents installation through its documentation and sample project. The README does not include an installation command, so this article does not reproduce one.

What versions of Python and Django does django-components support?

The `pyproject.toml` requires Python `>=3.10, <4.0` and `Django>=5.2`. Its classifiers list Django 5.2 and Django 6.0 and Python versions from 3.10 through 3.14.

Can a django-components component include its own HTML, CSS, and JavaScript?

Yes. The README defines a component with `template_file`, `js_file`, and `css_file`, and also shows inline `template`, `js`, and `css` values. Components can additionally declare third-party files through `Media`.

Official sources

  1. django-components/django-components on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/django-components-django-components.svg)](https://hysenlabs.com/projects/django-components-django-components)

Was this useful?