@webjsdev/ui
An AI-first component library with two-tier composition: pure class-helper
functions (buttonClass, cardClass, inputClass) for
visual primitives, plus a small set of stateful custom elements
(<ui-dialog>, <ui-tabs>, <ui-dropdown-menu>, etc.)
where state matters. Source-copied into your project so you own the code and edit it freely.
Variant names, sizes, and data attributes mirror shadcn so existing shadcn knowledge maps
directly. Works in any project with Tailwind v4 and the small @webjsdev/core
runtime: webjs, Next, Astro, Vite, SvelteKit, Lit, vanilla HTML.
For WebJs users
Nothing to install. @webjsdev/ui is a hard dependency of @webjsdev/cli, so a global
WebJs install already includes it, and webjs ui add resolves the kit from there. A
scaffolded app does NOT pin @webjsdev/ui: webjs ui add copies the component
source into components/ui/ (those files import @webjsdev/core, not the kit).
webjs ui init webjs ui add button card dialog input label
For everyone else (Next, Astro, Vite, SvelteKit, Lit, vanilla, …)
Two npm installs (the CLI and the runtime base class), then run the CLI:
npm install -D @webjsdev/ui npm install @webjsdev/core npx webjsui init npx webjsui add button card dialog
The webjsui binary is standalone. It does NOT require @webjsdev/cli.
It auto-detects your project type (Next / Astro / Vite / Lit / plain) and picks sensible defaults.
Commands
| Command | What it does |
|---|---|
init | Writes components.json, copies lib/utils.ts, installs the theme tokens (exits non-zero if they cannot be written) |
add <names...> | Copy components in, install needed deps, self-heal the theme tokens (Tier-1 files keep the helpers plus a pointer, not the worked example) |
list | List all components in the registry |
view <name> | Print a component's projected view (helpers plus the paste-ready example) and full source |
diff [name] | Show differences between your local copy and the live registry |
info | Project diagnostics |
Resolution is local-first: init / add / list / view
read the registry that ships inside the installed @webjsdev/ui package, so they need no
network. A Tier-1 component's worked structural example is served on demand by
webjsui view <name> (and the read-only MCP ui tool), not copied into your file.
Usage
Every component is a standards-compliant custom element. Tag convention: single ui- prefix, sub-components hyphenated.
<ui-card>
<ui-card-header>
<ui-card-title>Hello</ui-card-title>
<ui-card-description>A web component card.</ui-card-description>
</ui-card-header>
<ui-card-content>
<ui-input placeholder="Type here..." />
</ui-card-content>
<ui-card-footer>
<ui-button variant="default">Save</ui-button>
</ui-card-footer>
</ui-card>
Migrating from shadcn-react
Translation is mechanical: <Button> → <ui-button>, <DialogContent> → <ui-dialog-content>. Variant and size props match exactly. Components project children via DOM nesting. There is no asChild / Radix Slot pattern, so wrap an element directly instead.
What's in the registry?
~55 components matching shadcn's new-york-v4 style:
accordion, alert, alert-dialog, aspect-ratio, avatar, badge, breadcrumb, button, button-group, calendar, card, carousel, chart, checkbox, collapsible, combobox, command, context-menu, dialog, direction, drawer, dropdown-menu, empty, field, form, hover-card, input, input-group, input-otp, item, kbd, label, menubar, native-select, navigation-menu, pagination, popover, progress, radio-group, resizable, scroll-area, select, separator, sheet, sidebar, skeleton, slider, sonner, spinner, switch, table, tabs, textarea, toggle, toggle-group, tooltip.
Why web components?
Standards. Custom elements work in every framework that supports them: webjs, Next.js, Astro, Vite, Remix, SvelteKit, Nuxt, SolidStart, Lit projects, and plain HTML. One library, every host.
For AI agents
The whole point is rapid scaffolding. Instead of generating 200 lines of Tailwind for a login form,
an agent can call webjs ui add button card input label and compose 15 lines of tag soup.
Visual consistency comes for free; the agent makes zero design decisions.