{"id":24582675,"url":"https://github.com/django-components/django-components","last_synced_at":"2026-02-02T12:53:33.409Z","repository":{"id":33623054,"uuid":"37275310","full_name":"django-components/django-components","owner":"django-components","description":"Create simple reusable template components in Django.","archived":false,"fork":false,"pushed_at":"2025-05-13T09:53:37.000Z","size":25580,"stargazers_count":1343,"open_issues_count":52,"forks_count":94,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-05-13T13:12:06.962Z","etag":null,"topics":["components","django","django-templates","pypi-package","reusable-components"],"latest_commit_sha":null,"homepage":"https://django-components.github.io/django-components","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/django-components.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["EmilStenstrom"]}},"created_at":"2015-06-11T17:23:48.000Z","updated_at":"2025-05-13T09:53:41.000Z","dependencies_parsed_at":"2023-02-15T11:15:31.740Z","dependency_job_id":"693b50c1-0a58-4334-b50b-23f1e957b6d6","html_url":"https://github.com/django-components/django-components","commit_stats":{"total_commits":367,"total_committers":23,"mean_commits":"15.956521739130435","dds":0.673024523160763,"last_synced_commit":"69660e31c5d82e82fb50c52e9ea793c3ae5b7d61"},"previous_names":["django-components/django-components"],"tags_count":104,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/django-components%2Fdjango-components","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/django-components%2Fdjango-components/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/django-components%2Fdjango-components/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/django-components%2Fdjango-components/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/django-components","download_url":"https://codeload.github.com/django-components/django-components/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254020660,"owners_count":22000757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["components","django","django-templates","pypi-package","reusable-components"],"created_at":"2025-01-24T03:26:30.723Z","updated_at":"2026-02-02T12:53:33.403Z","avatar_url":"https://github.com/django-components.png","language":"Python","readme":"# \u003cimg src=\"https://raw.githubusercontent.com/django-components/django-components/master/assets/logo/logo-black-on-white.svg\" alt=\"django-components\" style=\"max-width: 100%; background: white; color: black;\"\u003e\n\n[![PyPI - Version](https://img.shields.io/pypi/v/django-components)](https://pypi.org/project/django-components/) [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/django-components)](https://pypi.org/project/django-components/) [![PyPI - License](https://img.shields.io/pypi/l/django-components)](https://github.com/django-components/django-components/blob/master/LICENSE/) [![PyPI - Downloads](https://img.shields.io/pypi/dm/django-components)](https://pypistats.org/packages/django-components) [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/django-components/django-components/tests.yml)](https://github.com/django-components/django-components/actions/workflows/tests.yml) [![asv](https://img.shields.io/badge/benchmarked%20by-asv-blue.svg?style=flat)](https://django-components.github.io/django-components/latest/benchmarks/)[![Discord](https://img.shields.io/badge/Discord-%235865F2.svg?logo=discord\u0026logoColor=white)](https://discord.gg/NaQ8QPyHtD)\n\n### \u003ctable\u003e\u003ctd\u003e[Read the full documentation](https://django-components.github.io/django-components/latest/)\u003c/td\u003e\u003c/table\u003e\n\n### \u003ctable\u003e\u003ctd\u003e[See Roadmap for v1](https://github.com/orgs/django-components/projects/1/views/1?sliceBy%5Bvalue%5D=milestone--v1)\u003c/td\u003e\u003c/table\u003e\n\n`django-components` is a modular and extensible UI framework for Django.\n\nIt combines Django's templating system with the modularity seen\nin modern frontend frameworks like Vue or React.\n\nWith `django-components` you can support Django projects small and large without leaving the Django ecosystem.\n\n`django-components` is tested across all major browsers - Chromium, Firefox, WebKit ✅.\n\n## Sponsors\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.ohne-makler.net/?ref=django-components\" target=\"_blank\"\n  title=\"Ohne-makler: Sell and rent real estate without an agent\"\u003e\u003cimg\n  src=\"https://raw.githubusercontent.com/django-components/django-components/master/assets/sponsors/sponsor-ohne-makler.png\" height=\"120\"\n  /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Quickstart\n\nA component in django-components consists of HTML, JavaScript, and CSS:\n\n```python\n# components/product_card/product_card.py\nfrom django_components import Component, register\n\n@register(\"product_card\")\nclass ProductCard(Component):\n    template_file = \"product_card.html\"\n    js_file = \"product_card.js\"\n    css_file = \"product_card.css\"\n\n    class Kwargs:\n        product_id: int\n        show_price: bool = True\n        theme: str = \"light\"\n\n    def get_template_data(self, args, kwargs: Kwargs, slots, context):\n        product = Product.objects.get(id=kwargs.product_id)\n        return {\n            \"product\": product,\n            \"show_price\": kwargs.show_price,\n            \"is_in_stock\": product.stock_count \u003e 0,\n        }\n\n    def get_js_data(self, args, kwargs: Kwargs, slots, context):\n        product = Product.objects.get(id=kwargs.product_id)\n        return {\n            \"product_id\": kwargs.product_id,\n            \"price\": float(product.price),\n            \"api_endpoint\": f\"/api/products/{kwargs.product_id}/\",\n        }\n\n    def get_css_data(self, args, kwargs: Kwargs, slots, context):\n        themes = {\n            \"light\": {\n                \"card_bg\": \"#ffffff\",\n                \"text_color\": \"#333333\",\n                \"price_color\": \"#e63946\",\n            },\n            \"dark\": {\n                \"card_bg\": \"#242424\",\n                \"text_color\": \"#f1f1f1\",\n                \"price_color\": \"#ff6b6b\",\n            },\n        }\n        theme_vars = themes.get(kwargs.theme, themes[\"light\"])\n        return theme_vars\n```\n\nIn your template:\n\n```htmldjango\n{# templates/product_card/product_card.html #}\n\u003cdiv class=\"product-card\" data-product-id=\"{{ product.id }}\"\u003e\n    \u003cimg src=\"{{ product.image_url }}\" alt=\"{{ product.name }}\"\u003e\n    \u003ch3\u003e{{ product.name }}\u003c/h3\u003e\n\n    {% if show_price %}\n        \u003cp class=\"price\"\u003e${{ product.price }}\u003c/p\u003e\n    {% endif %}\n\n    {% if is_in_stock %}\n        \u003cbutton class=\"add-to-cart\"\u003eAdd to Cart\u003c/button\u003e\n    {% else %}\n        \u003cp class=\"out-of-stock\"\u003eOut of Stock\u003c/p\u003e\n    {% endif %}\n\u003c/div\u003e\n```\n\nJavaScript:\n\n```javascript\n// components/product_card/product_card.js\n// Access component JS variables in $onComponent callback\n$onComponent(({ product_id, price, api_endpoint }, ctx) =\u003e {\n  const containerEl = ctx.els[0];\n  containerEl.querySelector(\".add-to-cart\")\n    .addEventListener(\"click\", () =\u003e {\n      fetch(api_endpoint, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application/json\" },\n        body: JSON.stringify({ action: \"add_to_cart\", price: price }),\n      });\n    });\n});\n```\n\nCSS:\n\n```css\n/* components/product_card/product_card.css */\n/* Access component CSS variables */\n.product-card {\n  background-color: var(--card_bg);\n  color: var(--text_color);\n  border-radius: 8px;\n  padding: 16px;\n  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.price {\n  color: var(--price_color);\n  font-weight: bold;\n}\n```\n\nUse the component like this:\n\n```django\n{% component \"product_card\"\n  product_id=123\n  theme=\"dark\"\n  show_price=True\n%}\n{% endcomponent %}\n```\n\nAnd this is what gets rendered:\n\n```html\n\u003cdiv class=\"product-card\" data-product-id=\"123\" data-djc-css-a1b2c3\u003e\n  \u003cimg src=\"/media/product.jpg\" alt=\"Awesome Product\" /\u003e\n  \u003ch3\u003eAwesome Product\u003c/h3\u003e\n  \u003cp class=\"price\"\u003e$29.99\u003c/p\u003e\n  \u003cbutton class=\"add-to-cart\"\u003eAdd to Cart\u003c/button\u003e\n\u003c/div\u003e\n```\n\nRead on to learn about all the exciting details and configuration possibilities!\n\n(If you instead prefer to jump right into the code, [check out the example project](https://github.com/django-components/django-components/tree/master/sampleproject))\n\n## Features\n\n### Modern and modular UI\n\n- Create self-contained, reusable UI elements.\n- Each component can include its own HTML, CSS, and JS, or additional third-party JS and CSS.\n- HTML, CSS, and JS can be defined on the component class, or loaded from files.\n\n```python\nfrom django_components import Component\n\n@register(\"calendar\")\nclass Calendar(Component):\n    template = \"\"\"\n        \u003cdiv class=\"calendar\"\u003e\n            Today's date is\n            \u003cspan\u003e{{ date }}\u003c/span\u003e\n        \u003c/div\u003e\n    \"\"\"\n\n    css = \"\"\"\n        .calendar {\n            width: 200px;\n            background: pink;\n        }\n    \"\"\"\n\n    js = \"\"\"\n        document.querySelector(\".calendar\")\n            .addEventListener(\"click\", () =\u003e {\n                alert(\"Clicked calendar!\");\n            });\n    \"\"\"\n\n    # Additional JS and CSS\n    class Media:\n        js = [\"https://cdn.jsdelivr.net/npm/htmx.org@2/dist/htmx.min.js\"]\n        css = [\"bootstrap/dist/css/bootstrap.min.css\"]\n\n    # Variables available in the template\n    def get_template_data(self, args, kwargs, slots, context):\n        return {\n            \"date\": kwargs[\"date\"]\n        }\n```\n\n### Extended template tags\n\n`django-components` is designed for flexibility, making working with templates a breeze.\n\nIt extends Django's template tags syntax with:\n\n- [Python expressions](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#python-expressions) `disabled=(not editable)` to evaluate Python code in templates\n- [Literal lists and dictionaries](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#literal-lists-and-dictionaries) `headers=[\"Name\", \"Age\"]` and `data=[{\"name\": \"John\"}]` to pass structured data directly\n- [Self-closing tags](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#self-closing-tags) `{% mytag / %}`\n- [Multi-line template tags](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#multiline-tags)\n- [Spread operator](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#spread-operator) `...` to dynamically pass args or kwargs into the template tag\n- [Nested templates](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#nested-templates) like `\"{{ first_name }} {{ last_name }}\"`\n- [Flat dictionaries](https://django-components.github.io/django-components/latest/concepts/fundamentals/template_tag_syntax#flat-dictionaries) `dict:key=val`\n\n```django\n{% component \"table\"\n    disabled=(not user.is_active)\n    title=\"Friend list for {{ user.name }}\"\n    headers=[\"Name\", \"Age\", \"Email\"]\n    data=[\n        {\n            \"name\": \"Jane\"|upper,\n            \"age\": 25|add:1,\n            \"email\": \"jane@example.com\",\n            \"hobbies\": [\"reading\", \"coding\"],\n        },\n    ],\n    ...default_attrs\n    attrs:class=\"py-4 ma-2 border-2 border-gray-300 rounded-md\"\n/ %}\n```\n\nYou too can define template tags with these features by using\n[`@template_tag()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.template_tag)\nor [`BaseNode`](https://django-components.github.io/django-components/latest/reference/api/#django_components.BaseNode).\n\nRead more on [Custom template tags](https://django-components.github.io/django-components/latest/concepts/advanced/template_tags/).\n\n### Composition with slots\n\n- Render components inside templates with\n  [`{% component %}`](https://django-components.github.io/django-components/latest/reference/template_tags#component) tag.\n- Compose them with [`{% slot %}`](https://django-components.github.io/django-components/latest/reference/template_tags#slot)\n  and [`{% fill %}`](https://django-components.github.io/django-components/latest/reference/template_tags#fill) tags.\n- Vue-like slot system, including [scoped slots](https://django-components.github.io/django-components/latest/concepts/fundamentals/slots/#slot-data).\n\n```django\n{% component \"Layout\"\n    bookmarks=bookmarks\n    breadcrumbs=breadcrumbs\n%}\n    {% fill \"header\" %}\n        \u003cdiv class=\"flex justify-between gap-x-12\"\u003e\n            \u003cdiv class=\"prose\"\u003e\n                \u003ch3\u003e{{ project.name }}\u003c/h3\u003e\n            \u003c/div\u003e\n            \u003cdiv class=\"font-semibold text-gray-500\"\u003e\n                {{ project.start_date }} - {{ project.end_date }}\n            \u003c/div\u003e\n        \u003c/div\u003e\n    {% endfill %}\n\n    {# Access data passed to `{% slot %}` with `data` #}\n    {% fill \"tabs\" data=\"tabs_data\" %}\n        {% component \"TabItem\" header=\"Project Info\" %}\n            {% component \"ProjectInfo\"\n                project=project\n                project_tags=project_tags\n                attrs:class=\"py-5\"\n                attrs:width=tabs_data.width\n            / %}\n        {% endcomponent %}\n    {% endfill %}\n{% endcomponent %}\n```\n\n### Full programmatic access\n\nWhen you render a component, you can access everything about the component:\n\n- Component input: [args, kwargs, slots and context](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-inputs)\n- Component's template, CSS and JS\n- Django's [context processors](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#request-and-context-processors)\n- Unique [render ID](https://django-components.github.io/django-components/latest/concepts/fundamentals/render_api/#component-id)\n\n```python\nclass Table(Component):\n    js_file = \"table.js\"\n    css_file = \"table.css\"\n\n    template = \"\"\"\n        \u003cdiv class=\"table\"\u003e\n            \u003cspan\u003e{{ variable }}\u003c/span\u003e\n        \u003c/div\u003e\n    \"\"\"\n\n    def get_template_data(self, args, kwargs, slots, context):\n        # Access component's ID\n        assert self.id == \"djc1A2b3c\"\n\n        # Access component's inputs and slots\n        assert self.args == [123, \"str\"]\n        assert self.kwargs == {\"variable\": \"test\", \"another\": 1}\n        footer_slot = self.slots[\"footer\"]\n        some_var = self.context[\"some_var\"]\n\n        # Access the request object and Django's context processors, if available\n        assert self.request.GET == {\"query\": \"something\"}\n        assert self.context_processors_data['user'].username == \"admin\"\n\n        return {\n            \"variable\": kwargs[\"variable\"],\n        }\n\n# Access component's HTML / JS / CSS\nTable.template\nTable.js\nTable.css\n\n# Render the component\nrendered = Table.render(\n    kwargs={\"variable\": \"test\", \"another\": 1},\n    args=(123, \"str\"),\n    slots={\"footer\": \"MY_FOOTER\"},\n)\n```\n\n### Granular HTML attributes\n\nUse the [`{% html_attrs %}`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/) template tag to render HTML attributes.\n\nIt supports:\n\n- Defining attributes as whole dictionaries or keyword arguments\n- Merging attributes from multiple sources\n- Boolean attributes\n- Appending attributes\n- Removing attributes\n- Defining default attributes\n\n```django\n\u003cdiv\n    {% html_attrs\n        attrs\n        defaults:class=\"default-class\"\n        class=\"extra-class\"\n    %}\n\u003e\n```\n\n[`{% html_attrs %}`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/) offers a Vue-like granular control for\n[`class`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/#merging-class-attributes)\nand [`style`](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/#merging-style-attributes)\nHTML attributes,\nwhere you can use a dictionary to manage each class name or style property separately.\n\n```django\n{% html_attrs\n    class=\"foo bar\"\n    class={\n        \"baz\": True,\n        \"foo\": False,\n    }\n    class=\"extra\"\n%}\n```\n\n```django\n{% html_attrs\n    style=\"text-align: center; background-color: blue;\"\n    style={\n        \"background-color\": \"green\",\n        \"color\": None,\n        \"width\": False,\n    }\n    style=\"position: absolute; height: 12px;\"\n%}\n```\n\nRead more about [HTML attributes](https://django-components.github.io/django-components/latest/concepts/fundamentals/html_attributes/).\n\n### HTML fragment support\n\n`django-components` makes integration with HTMX, AlpineJS or jQuery easy by allowing components to be rendered as [HTML fragments](https://django-components.github.io/django-components/latest/concepts/advanced/html_fragments/):\n\n- Components's JS and CSS files are loaded automatically when the fragment is inserted into the DOM.\n\n- Components can be [exposed as Django Views](https://django-components.github.io/django-components/latest/concepts/fundamentals/component_views_urls/) with `get()`, `post()`, `put()`, `patch()`, `delete()` methods\n\n- Automatically create an endpoint for a component with [`Component.View.public`](https://django-components.github.io/django-components/latest/concepts/fundamentals/component_views_urls/#register-urls-automatically)\n\n```py\n# components/calendar/calendar.py\n@register(\"calendar\")\nclass Calendar(Component):\n    template_file = \"calendar.html\"\n\n    class View:\n        # Define handlers\n        def get(self, request, *args, **kwargs):\n            page = request.GET.get(\"page\", 1)\n            return Calendar.render_to_response(\n                request=request,\n                kwargs={\n                    \"page\": page,\n                },\n            )\n\n    def get_template_data(self, args, kwargs, slots, context):\n        return {\n            \"page\": kwargs[\"page\"],\n        }\n\n# Get auto-generated URL for the component\nurl = get_component_url(Calendar)\n\n# Or define explicit URL in urls.py\npath(\"calendar/\", Calendar.as_view())\n```\n\n### Provide / Inject\n\n`django-components` supports the provide / inject pattern, similarly to React's [Context Providers](https://react.dev/learn/passing-data-deeply-with-context) or Vue's [provide / inject](https://vuejs.org/guide/components/provide-inject):\n\n- Use the [`{% provide %}`](https://django-components.github.io/django-components/latest/reference/template_tags/#provide) tag to provide data to the component tree\n- Use the [`Component.inject()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.inject) method to inject data into the component\n\nRead more about [Provide / Inject](https://django-components.github.io/django-components/latest/concepts/advanced/provide_inject).\n\n```django\n\u003cbody\u003e\n    {% provide \"theme\" variant=\"light\" %}\n        {% component \"header\" / %}\n    {% endprovide %}\n\u003c/body\u003e\n```\n\n```djc_py\n@register(\"header\")\nclass Header(Component):\n    template = \"...\"\n\n    def get_template_data(self, args, kwargs, slots, context):\n        theme = self.inject(\"theme\").variant\n        return {\n            \"theme\": theme,\n        }\n```\n\n### Input validation and static type hints\n\nAvoid needless errors with [type hints and runtime input validation](https://django-components.github.io/django-components/latest/concepts/fundamentals/typing_and_validation/).\n\nTo opt-in to input validation, define types for component's args, kwargs, slots, and more:\n\n```py\nfrom django.template import Context\nfrom django_components import Component, Slot, SlotInput\n\nclass Button(Component):\n    class Args:\n        size: int\n        text: str\n\n    class Kwargs:\n        variable: str\n        another: int\n        maybe_var: int | None = None  # May be omitted\n\n    class Slots:\n        my_slot: SlotInput | None = None\n        another_slot: SlotInput\n\n    def get_template_data(self, args: Args, kwargs: Kwargs, slots: Slots, context: Context):\n        args.size  # int\n        kwargs.variable  # str\n        slots.my_slot  # Slot[MySlotData]\n```\n\nTo have type hints when calling\n[`Button.render()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.render) or\n[`Button.render_to_response()`](https://django-components.github.io/django-components/latest/reference/api/#django_components.Component.render_to_response),\nwrap the inputs in their respective `Args`, `Kwargs`, and `Slots` classes:\n\n```py\nButton.render(\n    # Error: First arg must be `int`, got `float`\n    args=Button.Args(\n        size=1.25,\n        text=\"abc\",\n    ),\n    # Error: Key \"another\" is missing\n    kwargs=Button.Kwargs(\n        variable=\"text\",\n    ),\n)\n```\n\n### Extensions\n\nDjango-components functionality can be extended with [Extensions](https://django-components.github.io/django-components/latest/concepts/advanced/extensions/).\nExtensions allow for powerful customization and integrations. They can:\n\n- Tap into lifecycle events, such as when a component is created, deleted, or registered\n- Add new attributes and methods to the components\n- Add custom CLI commands\n- Add custom URLs\n\nSome of the extensions include:\n\n- [Component caching](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/cache.py)\n- [Django View integration](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/view.py)\n- [Component defaults](https://github.com/django-components/django-components/blob/master/src/django_components/extensions/defaults.py)\n- [Pydantic integration (input validation)](https://github.com/django-components/djc-ext-pydantic)\n\nSome of the planned extensions include:\n\n- AlpineJS integration\n- Storybook integration\n- Component-level benchmarking with asv\n\n### Caching\n\n- [Components can be cached](https://django-components.github.io/django-components/latest/concepts/advanced/component_caching/) using Django's cache framework.\n- Caching rules can be configured on a per-component basis.\n- Components are cached based on their input. Or you can write custom caching logic.\n\n```py\nfrom django_components import Component\n\nclass MyComponent(Component):\n    class Cache:\n        enabled = True\n        ttl = 60 * 60 * 24  # 1 day\n\n        def hash(self, *args, **kwargs):\n            return hash(f\"{json.dumps(args)}:{json.dumps(kwargs)}\")\n```\n\n### Simple testing\n\n- Write tests for components with [`@djc_test`](https://django-components.github.io/django-components/latest/concepts/advanced/testing/) decorator.\n- The decorator manages global state, ensuring that tests don't leak.\n- If using `pytest`, the decorator allows you to parametrize Django or Components settings.\n- The decorator also serves as a stand-in for Django's [`@override_settings`](https://docs.djangoproject.com/en/5.2/topics/testing/tools/#django.test.override_settings).\n\n```python\nfrom django_components.testing import djc_test\n\nfrom components.my_table import MyTable\n\n@djc_test\ndef test_my_table():\n    rendered = MyTable.render(\n        kwargs={\n            \"title\": \"My table\",\n        },\n    )\n    assert rendered == \"\u003ctable\u003eMy table\u003c/table\u003e\"\n```\n\n### Debugging features\n\n- **Visual component inspection**: Highlight components and slots directly in your browser.\n- **Detailed tracing logs to supply AI-agents with context**: The logs include component and slot names and IDs, and their position in the tree.\n\n\u003cdiv style=\"text-align: center;\"\u003e\n\u003cimg src=\"https://github.com/django-components/django-components/blob/master/docs/images/debug-highlight-slots.png?raw=true\" alt=\"Component debugging visualization showing slot highlighting\" width=\"500\" style=\"margin: auto;\"\u003e\n\u003c/div\u003e\n\n### Sharing components\n\n- Install and use third-party components from PyPI\n- Or publish your own \"component registry\"\n- Highly customizable - Choose how the components are called in the template (and more):\n\n    ```django\n    {% component \"calendar\" date=\"2024-11-06\" %}\n    {% endcomponent %}\n\n    {% calendar date=\"2024-11-06\" %}\n    {% endcalendar %}\n    ```\n\n## Documentation\n\n[Read the full documentation here](https://django-components.github.io/django-components/latest/).\n\n... or jump right into the code, [check out the example project](https://github.com/django-components/django-components/tree/master/sampleproject).\n\n## Performance\n\nOur aim is to be at least as fast as Django templates.\n\nAs of `0.130`, `django-components` is ~4x slower than Django templates.\n\n|                   | Render time |\n| ----------------- | ----------- |\n| django            | 68.9±0.6ms  |\n| django-components | 259±4ms     |\n\nSee the [full performance breakdown](https://django-components.github.io/django-components/latest/benchmarks/) for more information.\n\n## Release notes\n\nRead the [Release Notes](https://github.com/django-components/django-components/tree/master/CHANGELOG.md)\nto see the latest features and fixes.\n\n## Community examples\n\nOne of our goals with `django-components` is to make it easy to share components between projects. If you have a set of components that you think would be useful to others, please open a pull request to add them to the list below.\n\n- [django-htmx-components](https://github.com/iwanalabs/django-htmx-components): A set of components for use with [htmx](https://htmx.org/).\n\n- [djc-heroicons](https://pypi.org/project/djc-heroicons/): A component that renders icons from [Heroicons.com](https://heroicons.com/).\n\n## Contributing and development\n\nGet involved or sponsor this project - [See here](https://django-components.github.io/django-components/dev/community/contributing/)\n\nRunning django-components locally for development - [See here](https://django-components.github.io/django-components/dev/community/development/)\n","funding_links":["https://github.com/sponsors/EmilStenstrom"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjango-components%2Fdjango-components","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjango-components%2Fdjango-components","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjango-components%2Fdjango-components/lists"}