Skip to content
Back to skills

Alpinejs Django

ASecurity

Use when adding, changing, or debugging Alpine.js behavior in Django-rendered templates, especially when Alpine.js coexists with HTMX partial updates.

  • 3 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 12, 2026
ai-agentsjavascriptrustgojavareactexpressdjangodebugginggitfrontend

Works with

  • cli

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add thedixitjain/the-mega-skill-library --skill alpinejs-django --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Alpinejs Django?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Alpinejs Django
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/thedixitjain-alpinejs-django/badge)](https://www.skillsdirectory.com/skills/thedixitjain-alpinejs-django)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: alpinejs-django
description: "Use when adding, changing, or debugging Alpine.js behavior in Django-rendered templates, especially when Alpine.js coexists with HTMX partial updates."
category: engineering-core
source_repo: hashgraph-online/awesome-codex-plugins
source_path: "plugins/LVTD-LLC/skills/skills/alpinejs-django/SKILL.md"
source_url: https://github.com/hashgraph-online/awesome-codex-plugins/blob/HEAD/plugins/LVTD-LLC/skills/skills/alpinejs-django/SKILL.md
---


# Alpine.js with Django

Use this skill for local browser state in Django-rendered templates: dropdowns,
modals, tabs, disclosures, inline filters, disabled/loading states, small
preview interactions, and client-only toggles. Use Django views/forms/models as
the source of truth for durable state. Use HTMX when the server needs to return
fresh HTML.

## Setup checks

- Identify how the project loads Alpine. Prefer the existing static asset or
  bundling pipeline as the source of truth.
- Find the base template, layout, or bundled entrypoint that loads HTMX,
  Alpine, and app JavaScript. Preserve the current ordering unless changing
  initialization deliberately.
- Determine whether the loaded Alpine file is self-starting or module-based. Do
  not call `Alpine.start()` when the project already loads a self-starting
  Alpine build. If using a module build, register components and start Alpine
  from the owning entrypoint.
- Simple Alpine behavior should usually live inline in the Django template with
  `x-data`.
- If a reusable component or store is worth extracting, register it before
  Alpine starts. Check the existing script order before relying on
  `document.addEventListener("alpine:init", ...)` from an app-wide script.
- When reusable Alpine registration is needed, add or reuse a script or
  entrypoint that runs before Alpine starts. Register components and stores
  inside `document.addEventListener("alpine:init", ...)`, include the file
  through the project's normal asset path, and avoid double-starting Alpine.

## Ownership rules

- Django owns persistence, authorization, validation, redirects, and rendered
  HTML.
- HTMX owns server round trips and DOM swaps.
- Alpine owns ephemeral state already present in the browser.
- Plain JavaScript modules or bundled entrypoints own shared DOM behavior that
  is not naturally scoped to one Alpine component.
- Do not duplicate the same behavior in Alpine and a plain JS module.

## Template patterns

Use a small `x-data` object near the markup it controls:

```html
<div
  x-data="{ open: false }"
  @keydown.escape.window="open = false"
  @click.outside="open = false"
>
  <button
    type="button"
    :aria-expanded="open.toString()"
    @click.stop="open = !open"
  >
    Menu
  </button>

  <div x-cloak x-show="open" x-transition>
    ...
  </div>
</div>
```

Prefer Alpine directives over manual DOM manipulation:

- `x-show` for toggling visibility while keeping the element in the DOM.
- `x-if` on a `<template>` when the element should be created and destroyed.
- `x-model` for client-only input state; Django form submission and validation
  still happen on the server.
- `:class`, `:disabled`, `:aria-expanded`, and `:hidden` for state-derived
  attributes.
- `$watch` for one named state transition; `x-effect` only when the dependency
  set is simple and intentional.
- `$dispatch` for browser events between Alpine components or from Alpine to
  HTMX triggers.

Use `x-cloak` for anything hidden by default. Ensure the base CSS includes the
required `[x-cloak] { display: none !important; }` rule.

## Django data

Keep Django interpolation out of complex JavaScript expressions when possible.

For simple values, prefer HTML attributes:

```html
<div
  data-initial-label="{{ object.name }}"
  x-data="{ label: '' }"
  x-init="label = $el.dataset.initialLabel"
>
  <span x-text="label"></span>
</div>
```

For structured values, prefer Django's `json_script` and parse it in `x-init`:

```html
{{ rows|json_script:"rows-data" }}

<div
  x-data="{ rows: [] }"
  x-init="rows = JSON.parse(document.getElementById('rows-data').textContent)"
>
  <template x-for="row in rows" :key="row.id">
    <span x-text="row.name"></span>
  </template>
</div>
```

Avoid `|safe` inside Alpine expressions. If the browser must display text, use
`x-text`. Use `x-html` only for trusted, already-sanitized HTML; most HTML should
be rendered by Django or returned through HTMX.

## Alpine and HTMX

When HTMX swaps a fragment containing `x-data`, Alpine should initialize the new
component automatically. Do not restart Alpine after HTMX swaps.

Keep persistent Alpine state outside HTMX targets that will be replaced:

```html
<section x-data="{ panelOpen: false }">
  <button type="button" @click="panelOpen = !panelOpen">Filters</button>

  <div id="results" hx-get="{% url 'search_results' %}" hx-trigger="change from:#filters">
    ...
  </div>
</section>
```

Use events as the boundary between HTMX responses and Alpine state. From Django,
set an `HX-Trigger` or `HX-Trigger-After-Swap` response header, then listen from
Alpine:

```html
<div x-data="{ open: true }" @profile-saved.window="open = false">
  <form hx-post="{% url 'profile_update' %}" hx-target="#profile-panel" hx-swap="outerHTML">
    ...
  </form>
</div>
```

Listen for HTMX lifecycle events in kebab case from Alpine, such as
`@htmx:after-swap.window`, because HTML attributes are case-insensitive.

If Alpine dispatches an event that HTMX should react to, make the trigger
explicit:

```html
<button type="button" x-data @click="$dispatch('refresh-results')">
  Refresh
</button>

<div hx-get="{% url 'results' %}" hx-trigger="refresh-results from:body">
  ...
</div>
```

## Accessibility

- Keep real buttons as `<button type="button">` unless submitting a form.
- Bind ARIA state from Alpine state, especially `aria-expanded`,
  `aria-controls`, `aria-selected`, and `aria-hidden`.
- Support `@keydown.escape.window` for dismissible overlays.
- Use `@click.outside` for popovers and menus, paired with a visible trigger.
- Preserve focus behavior for modals, menus, and swapped HTMX content. If focus
  trapping is needed, add a focused plain JS module or Alpine plugin deliberately
  instead of hand-rolling a brittle trap in attributes.

## Security and CSP

- Treat all Alpine expressions as JavaScript running in the user's browser.
- Do not put secrets, signed tokens, or privileged data into `x-data`,
  `data-*`, `json_script`, or hidden inputs unless the user is allowed to see
  them.
- If strict Content Security Policy without `unsafe-eval` is required, switch
  deliberately to Alpine's CSP build and retest Alpine expressions. The default
  `alpinejs/dist/cdn.min.js` build is not the CSP build.
- If Alpine code makes `fetch()` requests, include Django CSRF headers or use
  existing HTMX/Django forms instead.

## Validation

- For template-only Alpine changes, run the Django template or view tests that
  cover the page, plus `npm run lint` if JavaScript modules changed.
- For HTMX interactions, test the full page and the partial response path.
- If the project has a frontend build step, run it before relying on static
  output.
- Manually verify stateful controls in light and dark mode when changing visible
  UI behavior.

---

**Source:** [`hashgraph-online/awesome-codex-plugins`](https://github.com/hashgraph-online/awesome-codex-plugins) → `plugins/LVTD-LLC/skills/skills/alpinejs-django/SKILL.md`

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.