shadcn-htmx

shadcn-style UI components for htmx v4 + Tailwind v4 — 82 web-standards components in 5 flavours (Hono JSX, Jinja2, Go, Phoenix, raw HTML), WAI-ARIA accessible, with a flavour-aware CLI.

14
2
14
Markdown
public
shadcn-htmx — shadcn-style components for htmx v4 + Tailwind v4

shadcn-htmx

shadcn-style UI components for htmx v4 + Tailwind CSS v4 — built on web standards, not hacks.

License: MIT
Components: 82
Flavours: 5
htmx v4
Tailwind CSS v4
a11y: WAI-ARIA APG

📖 Documentation & live previews → shadcn-htmx.productdevbook.com

One design. 82 components. Five backends — Hono JSX, Jinja2, Go templates, Phoenix, and raw HTML — generated from a single source of truth. Copy what you need, ship it in any stack.


Why

Most component libraries assume React. shadcn-htmx assumes the platform: a real
<button>, a real <dialog>, real aria-*, real <input type="date">. Behaviour
the browser already ships is never re-implemented in JavaScript — the only script is
a tiny, shared keyboard layer for the composite ARIA widgets the platform doesn’t
cover (menus, listboxes, trees…).

  • Web standards first. Every component is justified against the WAI-ARIA APG, MDN, the htmx v4 source, and the Tailwind v4 source before it ships. No polyfills, no emulation, no “browsers will support this eventually.”
  • Five flavours, one design. Each component exists as a typed Hono JSX component, a Jinja2 macro, a Go html/template, a Phoenix function component, and a copy-paste HTML snippet — all rendering identical, accessible markup.
  • Server-rendered + htmx-native. Components are built for server rendering and wired for the htmx v4 attribute set (live search, infinite scroll, inline edit, optimistic toggles…).
  • Accessible by construction. Keyboard interaction, focus management, and ARIA roles are checked against the spec — and against an axe-core + APG keyboard test suite.
  • Your code, your repo. Copy a component in and it’s yours. No runtime dependency, no version lock-in.

Flavours

Flavour Language / engine What you copy
Hono JSX TypeScript (.tsx) A typed component you import
Jinja2 Python templates (.html) A {% macro %} you call
Go html/template (.tmpl) A {{ define }} template
Phoenix Elixir (.ex) A ~H function component
HTML Raw markup (.html) A copy-paste snippet

The Hono JSX file is the canonical source; the other four mirror its semantics exactly — same elements, roles, ARIA, and Tailwind classes. Only the templating syntax differs.

Quick start

The fastest path is the flavour-aware CLI. Pick your stack once, then add components — only your framework’s file lands in your project.

npx shadcn-htmx init --flavour jinja        # jsx | jinja | go | phoenix | html
npx shadcn-htmx add button dialog combobox  # writes only the Jinja2 files
npx shadcn-htmx list                         # browse every component

init writes a shadcn-htmx.json so later commands need no flags — it’s
pre-pointed at the hosted registry (https://shadcn-htmx.productdevbook.com/r);
override it with the registry field or --registry to self-host.

Other ways to install

shadcn CLI — the registry follows the shadcn registry-item schema, so the
stock CLI works too (but it copies all five flavours’ files; delete the ones you
don’t need):

npx shadcn@latest add https://shadcn-htmx.productdevbook.com/r/button.json

curl — pull a raw flavour file straight into your project:

curl -o templates/components/button.html \
  https://raw.githubusercontent.com/productdevbook/shadcn-htmx/main/registry/jinja2/button.html

Copy-paste — open the component’s docs page, switch the framework selector to
your stack, and copy the source.

Components

82 components across six categories — every interactive one mapped to its
WAI-ARIA APG pattern, every other to a native HTML element, Web API, or modern CSS
feature.

Category Components
Forms Button · Input · Textarea · Label · Checkbox · Combobox · Switch · Radio Group · Select · Slider · Number Input · Range Slider · Listbox · Form Field · File Upload · Date Time Picker · Active Search · Edit In Place · Output · Segmented Control · Rating · Color Picker · Autosize Textarea · Cascading Select · Autocomplete
Layout Card · Table · Collapsible · Toolbar · Grid · Treegrid · Splitter · Landmarks · Aspect Ratio · Auto Grid · Scroll Area · Snap List · Container Card · Sticky Header · Exclusive Accordion
Display Avatar · Badge · Separator · Carousel · Copy Button · Kbd · Highlight · Relative Time · Figure · Responsive Image · Media Player · Selectable Table · Delete Row
Feedback Alert · Progress · Skeleton · Toast · Meter · Feed · Status · Lazy Load · Optimistic Toggle · Scroll Progress
Overlays Dialog · Dropdown Menu · Popover · Tooltip · Alert Dialog · Sheet · Hover Card
Navigation Accordion · Pagination · Tabs · Breadcrumb · Link · Menubar · Tree · Skip Link · Theme Toggle · Split Button · Sidebar · Load More

Accessibility

Interactive components implement the matching WAI-ARIA Authoring Practices
pattern — keyboard interaction, focus management, and ARIA roles checked against the
spec. The repo ships a Playwright suite that enforces it: axe-core on every page,
APG keyboard contracts, overlay geometry, an interaction smoke sweep, and a
console-error sweep.

How it works

registry.json is the manifest — one entry per component, listing its five flavour
files. scripts/build-registry.ts reads it and emits public/r/<name>.json (the
shadcn registry-item schema, with each file’s contents inlined) plus an
index.json. The docs app serves /r/*, so the CLI — or any HTTP consumer — pulls
items straight over the wire. The shadcn-htmx CLI reads that same JSON and writes
only the file for your chosen flavour.

Local development

The repository is the docs site — a Hono + JSX app rendered
on Bun.

bun install
bun dev                  # docs at http://localhost:3000 (server + Tailwind watcher)
bun run typecheck        # tsc --noEmit
bun run build            # build:registry (public/r/*.json) + build:css (minified)
bun run build:registry   # regenerate the registry JSON from registry.json
bun run build:css        # compile app/styles/input.css -> public/styles.css

Tests

End-to-end tests run on Playwright (Chromium). The config does not start the
server — run the app on port 3010 in one terminal and the tests in another:

PORT=3010 bun run app/server.tsx     # terminal 1
bun run test:e2e                     # terminal 2 — all browser suites
bun run test:a11y                    # axe-core accessibility checks
bun run test:kbd                     # APG keyboard contracts
bun run test:geom                    # overlay positioning
bun run test:cli                     # the flavour-aware CLI (bun test)

Project structure

registry/
  ui/            *.tsx     Hono JSX — canonical source of truth
  jinja2/        *.html    Jinja2 macros
  go-templates/  *.tmpl    Go html/template
  phoenix/       *.ex      Phoenix function components
  html/          *.html    raw HTML snippets
  lib/           cn.ts     class-name joiner
app/             Hono docs site (routes, layout, shared components, demo endpoints)
tests/           Playwright e2e (a11y, keyboard, geometry, smoke, console)
scripts/         build-registry.ts · cli.mjs (the shadcn-htmx CLI) · sync-repos.sh
public/r/        generated registry JSON (served at /r/*)
repos/           vendored upstream sources, read-only — see AGENTS.md

Philosophy

This project ships only what the web platform supports natively today. The sources
it’s measured against — the WAI-ARIA APG, MDN, the htmx v4 source, and the Tailwind
v4 source — are vendored under repos/ so contributors (human or agent) read
current ground truth instead of recalling from memory. The full rules live in
AGENTS.md. Vendored sources are refreshed with ./scripts/sync-repos.sh.

Contributing & sponsoring

Issues and PRs are welcome. If shadcn-htmx saves you time, you can sponsor ongoing
maintenance and new components at
github.com/sponsors/productdevbook.

License

MIT © productdevbook

v0.3.3[beta]