shadcn-htmx
v0.0.2
Published
shadcn-style UI components for htmx v4 + Tailwind v4 — 82 web-standards components in five flavours, with a flavour-aware CLI.
Maintainers
Readme
shadcn-htmx
shadcn-style UI components for htmx v4 + Tailwind CSS v4 — built on web standards, not hacks.
📖 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 componentinit 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.
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.jsoncurl — 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.htmlCopy-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.cssTests
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.mdPhilosophy
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.
