A public, shadcn-compatible component registry for React 19 and Tailwind CSS v4. It includes foundational controls, composed blocks, agent/chat primitives and a design-token theme, served from swagui.rohoswagger.com.
swagui replaces shadcn/ui rather than layering on top of it — the components are vendored and restyled, so upstream changes are not inherited.
- Tailwind CSS v4
- React 19
- A shadcn-compatible project with
components.json
If shadcn is not configured yet, initialize it from the root of your app:
bunx shadcn@latest initChoose the bundle that matches your project:
| Bundle | Includes | Install command |
|---|---|---|
| Core | Foundational controls and utilities | bunx shadcn@latest add https://swagui.rohoswagger.com/r/core.json |
| Agent/chat | The complete agent and chat interface set | bunx shadcn@latest add https://swagui.rohoswagger.com/r/agent.json |
| All | Every component, block and agent primitive | bunx shadcn@latest add https://swagui.rohoswagger.com/r/all.json |
Copy-paste versions:
# Core UI
bunx shadcn@latest add https://swagui.rohoswagger.com/r/core.json
# Chat and agent UI
bunx shadcn@latest add https://swagui.rohoswagger.com/r/agent.json
# The entire registry
bunx shadcn@latest add https://swagui.rohoswagger.com/r/all.jsonThe CLI shows the files it will write and asks before replacing conflicting files. swagui components are vendored into your project, so you own and can edit the installed source.
Every registry item is independently installable. Use the component's name in the hosted URL:
bunx shadcn@latest add https://swagui.rohoswagger.com/r/button.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/dialog.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/form.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/table.jsonAgent and chat primitives work the same way:
bunx shadcn@latest add https://swagui.rohoswagger.com/r/message.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/prompt-input.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/reasoning.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/tool-call.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/tasks.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/artifact.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/input-request.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/subagent.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/chat-header.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/conversation-sidebar.jsonComposed site blocks are also registry items:
bunx shadcn@latest add https://swagui.rohoswagger.com/r/hero-centered.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/feature-showcase.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/pricing-tiers.json
bunx shadcn@latest add https://swagui.rohoswagger.com/r/site-footer.jsonRegister the namespace once to use shorter commands in that project:
bunx shadcn@latest registry add \
@swagui=https://swagui.rohoswagger.com/r/{name}.json
bunx shadcn@latest add @swagui/button
bunx shadcn@latest add @swagui/input-request
bunx shadcn@latest add @swagui/agentAfter registration, any item can be installed as @swagui/{name}:
bunx shadcn@latest add @swagui/core
bunx shadcn@latest add @swagui/agent
bunx shadcn@latest add @swagui/all
bunx shadcn@latest add @swagui/artifact
bunx shadcn@latest add @swagui/site-footerEvery component declares the theme as a registry dependency, so the first install
writes the whole token layer straight into your globals.css. There is no file to
import and no manual step.
| Resource | URL |
|---|---|
| Documentation and showcase | https://swagui.rohoswagger.com |
| Registry catalog | https://swagui.rohoswagger.com/r/registry.json |
| Individual item | https://swagui.rohoswagger.com/r/{name}.json |
| Source | https://github.com/rohoswagger/swagui |
There are no presets. Every value is a knob; a project sets the ones it cares about and inherits the rest. The permutation is the theme.
:root {
/* Type — wire these to real faces (next/font, @font-face, …). */
--font-display: var(--font-my-display);
--font-body: var(--font-my-body);
--font-mono-face: var(--font-my-mono);
--display-tracking: -0.03em;
/* Geometry. 1 gives stock Tailwind corners. */
--squircle-factor: 1.4;
/* The one hot colour. Deliberately withheld from buttons and component
surfaces — it appears on links, focus rings, status dots and glows. */
--brand: oklch(0.58 0.16 250);
--brand-content: oklch(0.5 0.16 250);
/* Base colour — untinted by default; pick a temperature with data-base. */
--background: oklch(0.991 0 0);
--foreground: oklch(0.18 0 0);
}Six tinted neutrals, not colours. The hue sits at 0.007 chroma in the ground and 0.020–0.028 in the ink, so it reads as a temperature rather than a tint. Hues are spread around the wheel on purpose — defaulting warm is how every design system ends up looking like every other one.
Every pair is verified by scripts/check-contrast.mjs. Worst case is 5.83:1 in
light and 7.15:1 in dark, against a 4.5:1 requirement.
Three attribute scopes compose on any wrapper element.
| Attribute | Values | Effect |
|---|---|---|
data-base |
ash, slate, clay, sage, mauve, olive |
Tints the whole neutral ramp |
data-surface |
elevation, bevel, glass |
Swaps the shadow tokens, so every component follows |
data-density |
comfortable, compact |
Retunes --spacing, radius and line-height |
data-density="compact" is the app-interior register: it overrides --spacing,
which every Tailwind spacing utility derives from, so padding, margins, gaps,
control heights and icon sizes all tighten at once. Colour is untouched.
<div data-density="compact">
<DataTable />
</div>Dark mode is class-driven — put dark on <html> or any wrapper.
Composed marketing sections, installed the same way:
bunx shadcn@latest add https://swagui.rohoswagger.com/r/hero-centered.jsonsection, reveal, hero-centered, feature-showcase, logo-marquee, cta-band.
Blocks may depend on motion; components never do, so app bundles stay lean.
The agent bundle includes AgentWorkspace and ComputerFrame. On desktop,
AgentWorkspace places a compact conversation on the left and the computer
on the right, with a keyboard-accessible resize handle. On mobile it provides
Computer and Conversation tabs. The host supplies navigation, header, computer
content, and conversation content; the component does not open remote sessions.
ComputerFrame exports toolbar, address, content, and footer slots. A runnable
composition is available as agent-workspace-demo in the registry.
Wrap a shared layout in AgentWorkingMarkProvider defaultVariant="tesseract"
to choose the working mark once. Direct marks and conversation-sidebar items
inherit it, while explicit variant or workingMark props take precedence.
Without a provider the default remains Möbius.
Want to add a component, improve the showcase or publish a release? See CONTRIBUTING.md for the local setup, registry workflow, verification requirements and Cloudflare deployment process.
MIT © 2026 rohoswagger.