# Arc > Arc is a React component and block library designed for AI-assisted frontend development. It provides copy-paste components, complete interface blocks, machine-readable registry metadata, AI skills, and MCP compatibility. Components and blocks share design tokens, CSS modules, and Motion. Free items install with the shadcn CLI from a public registry; Pro items are licensed and install from the token-gated @uiarc-pro registry. ## Install Arc items are shadcn-compatible registry items. Each one pulls in `arc-foundation` (design and motion tokens) and any Arc components it builds on. ```bash npx shadcn@latest add https://uiarc.dev/r/button.json ``` Or register the namespace once in `components.json` and install by name: ```json { "registries": { "@uiarc": "https://uiarc.dev/r/{name}.json" } } ``` ```bash npx shadcn@latest add @uiarc/button @uiarc/dialog ``` After the first install, import the tokens once in the root layout: `import "@/registry/foundation.css";`. Files install at the project root (`registry/…`, `lib/motion-tokens.ts`) and import each other through the `@/*` alias, so map `@/*` to `./*` in `tsconfig.json` (for a `src/` project add `"@/registry/*": ["./registry/*"]` and `"@/lib/motion-tokens": ["./lib/motion-tokens.ts"]`). Components use CSS modules and CSS variables, not Tailwind classes. Dark mode: `data-theme="dark"` on ``. Accent: `data-accent` = neutral, violet, blue, green, amber, orange, coral, or rose. ### Pro items Pro components, blocks, and templates install from the token-gated `@uiarc-pro` registry. A Pro member creates a token (`arc_pro_…`) at https://uiarc.dev/account#pro-access, sets `ARC_PRO_TOKEN` in the environment or `.env.local` (never committed), and adds the registry to `components.json`: ```json { "registries": { "@uiarc": "https://uiarc.dev/r/{name}.json", "@uiarc-pro": { "url": "https://uiarc.dev/r/pro/{name}.json", "headers": { "Authorization": "Bearer ${ARC_PRO_TOKEN}" } } } } ``` ```bash npx shadcn@latest add @uiarc-pro/dock ``` The MCP server accepts the same token as `Authorization: Bearer …`: `get_component` then returns Pro source and `get_install_command` returns `@uiarc-pro` commands. Without a token, never reconstruct a Pro item; offer a free alternative or https://uiarc.dev/pricing. Setup: https://uiarc.dev/docs/ai#pro-access ## Rules for agents - Prefer an existing Arc component or block over writing a new one; compose blocks from Arc components. - Read the component's markdown before using it; use only documented props. - Keep semantic HTML, keyboard behavior, and a reduced-motion branch for every animation. - Use the semantic tokens (`--background`, `--surface`, `--foreground`, `--text-secondary`, `--border`, `--accent`, `--success`, `--warning`, `--danger`) instead of raw colors, and check light and dark themes. - Use motion presets from `lib/motion-tokens.ts` (`snappy` for presses, `smooth` for panels, `morph` for shared highlights). Motion should explain cause and effect. - Sentence case copy, regular and medium weights only, no eyebrow labels, no em dashes, no focus rings, no decorative gradients or glows. - Pro items are licensed: never reconstruct their source; point people to the pricing page. ## Skills Install every free skill file with `npx shadcn@latest add https://uiarc.dev/r/arc-skill.json`, or read them directly: - [SKILL.md](https://uiarc.dev/r/skills/arc/SKILL.md): Entry point: workflow, principles, never-do list, and quick decisions - [INSTRUCTIONS.md](https://uiarc.dev/r/skills/arc/INSTRUCTIONS.md): Short always-on rules for AGENTS.md, CLAUDE.md, or Cursor rules - [checklist.md](https://uiarc.dev/r/skills/arc/checklist.md): The review loop to run before finishing, with grep sweeps - [components.md](https://uiarc.dev/r/skills/arc/components.md): Choosing the right component or block by job, with ids - [composition.md](https://uiarc.dev/r/skills/arc/composition.md): Page containers, dashboards, marketing sections, states, React correctness - [copy.md](https://uiarc.dev/r/skills/arc/copy.md): Sentence case, no eyebrows or em dashes, verbs on buttons, honest claims - [design.md](https://uiarc.dev/r/skills/arc/design.md): Color, type, surfaces, concentric radii, spacing, and icons - [motion.md](https://uiarc.dev/r/skills/arc/motion.md): Motion tokens, spring choice, patterns with code, reduced motion - [accessibility.md](https://uiarc.dev/r/skills/arc/accessibility.md): Focus without rings, semantics, keyboard, and announcements - [responsive.md](https://uiarc.dev/r/skills/arc/responsive.md): Widths to check, overflow, tables, and touch targets - [example-settings.md](https://uiarc.dev/r/skills/arc/example-settings.md): A worked account settings page - [example-pricing.md](https://uiarc.dev/r/skills/arc/example-pricing.md): A worked pricing section with plans, comparison, and FAQ - [example-dashboard.md](https://uiarc.dev/r/skills/arc/example-dashboard.md): A worked analytics overview with KPIs, chart, and table Pro skills (Arc Pro, served to signed-in Pro members at https://uiarc.dev/api/skills): - Arc Pro skill: Entry point: picks the right Pro workflow and sets up Pro access - Full-page generation: Brief, plan, build, and verify a whole page against the checklist - Page composition: Plan a page region by region with the right blocks and every state - Design system generation: A brand theme on Arc tokens with contrast checked in both themes - Refactor to Arc: Migrate custom, shadcn/ui, MUI, or Chakra UI to Arc with parity checks - Motion audit: Inventory every animation, assign tokens, cut motion that explains nothing - Responsive audit: Measure five widths, fix overflow, layout, and touch, then re-measure - Accessibility audit: A ranked audit of structure, keyboard, contrast, and motion with patches ## Guides - [All guides](https://uiarc.dev/guides): Step-by-step builds with Arc components and blocks - [SaaS dashboard in React](https://uiarc.dev/guides/saas-dashboard-react): Shell, metrics, tables, and states for a product dashboard - [React motion: springs and reduced motion](https://uiarc.dev/guides/react-motion-springs-reduced-motion): Choosing springs and writing a reduced-motion branch - [shadcn registry for AI coding tools](https://uiarc.dev/guides/shadcn-registry-ai-coding-tools): Installing Arc through the registry, MCP, and llms.txt - [React settings page](https://uiarc.dev/guides/react-settings-page): Forms, switches, and destructive actions on one settings screen - [Onboarding flows](https://uiarc.dev/guides/onboarding-flows): Multi-step setup with progress and in-place confirmation - [React command menu](https://uiarc.dev/guides/react-command-menu): A keyboard-first command palette for global search and actions ## Templates - [Templates](https://uiarc.dev/templates) (Pro): Complete starter apps built from Arc blocks - Arc SaaS (Pro): A complete SaaS starter - Arc AI (Pro): A complete AI application - Arc Startup (Pro): A complete marketing site # Components and blocks ## Button > A clear, responsive action with quiet secondary states. - Type: Component (actions) - Access: Free, open source - Page: https://uiarc.dev/components/button - Markdown: https://uiarc.dev/components/button/markdown - Registry item: https://uiarc.dev/r/button.json - Source file: `registry/components/button/button.tsx` - Dependencies: motion - Keywords: action, control, react button, animated button, loading button, button with spinner, button press animation, morphing button label, primary button ### When to use - Any single action on a page, form, or dialog, such as Save, Continue, or Cancel. - Actions whose label changes in place, like Save to Saved, where the width should spring instead of jump. - Short async work where a spinner on the button is enough feedback, via loading. ### When not to use - Use action-button when the button itself should show pending and success states after an async commit. - Use split-button when one default action has two to five close variants. - Use hold-to-confirm for destructive actions that need more than a single click. ### Installation #### CLI Run one of these in a project set up with `shadcn init`: ```bash npx shadcn@latest add @uiarc/button pnpm dlx shadcn@latest add @uiarc/button yarn dlx shadcn@latest add @uiarc/button bunx --bun shadcn@latest add @uiarc/button ``` The `@uiarc` name needs `"registries": { "@uiarc": "https://uiarc.dev/r/{name}.json" }` in `components.json`. Without it, use the full URL: ```bash npx shadcn@latest add https://uiarc.dev/r/button.json ``` #### Manual 1. Install the dependencies: ```bash npm install motion ``` 2. Copy the source into your project. Main file: `registry/components/button/button.tsx` The source is in the registry item: https://uiarc.dev/r/button.json 3. Arc imports use the `@/` alias for `registry/` and `lib/`. Keep the same folders or update the import paths. ### Usage ```tsx import { Button } from "@/registry/components/button/button"; export function SaveBar() { return ( ); } ``` ### Examples #### Label that morphs after saving ```tsx ``` ### API reference #### Button A native button with press feedback and a label that morphs its width when the content changes. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `variant` | `"primary" \| "secondary" \| "ghost" \| "danger"` | `"primary"` | Visual weight. Use one primary action per surface. | | `size` | `"sm" \| "md" \| "lg"` | `"md"` | Height and padding. | | `loading` | `boolean` | `false` | Shows a spinner, sets aria-busy, and swallows clicks while keeping focus. | | `...props` | `ButtonHTMLAttributes` | – | Forwarded to the underlying button, including ref, disabled, type, and onClick. | ### Keyboard interactions | Keys | Action | | --- | --- | | Enter / Space | Activates the button. | ### Accessibility - Renders a native button, so role and focus come for free. - Loading uses aria-busy and aria-disabled instead of disabled, so keyboard focus is not lost mid-action. - Icon-only buttons need an aria-label. ### Motion - Presses scale to about 0.97 on a snappy spring; icon-sized buttons press slightly deeper. - A new label crossfades with a short blur while the width springs to fit. - Reduced motion drops the press scale and swaps labels with a plain fade. ### Responsive behavior - Size is fixed by the size prop; the button never changes layout by breakpoint, so pick lg for primary touch targets. - Hover styles apply only on hover-capable fine pointers, so taps on touch screens do not stick in a hover state. ### Performance - A ResizeObserver measures the label so the width can spring; one per button is cheap, but avoid hundreds in a long list. - Label changes animate opacity, transform, and a small blur only, with no layout thrash beyond the width spring. ### Notes for AI - Default choice for any single action. Use action-button for dense icon toolbars and split-button when one action has close alternatives. - Pass a changing label (Save → Saved) as children to get the width morph for free. - Wrap in a Radix trigger with asChild; the press scale turns off automatically for popup anchors. ### Related - [Action button](https://uiarc.dev/components/action-button/markdown): A compact button for frequent toolbar actions. - [Split button](https://uiarc.dev/components/split-button/markdown): A primary action with a menu of nearby alternatives. - [Copy button](https://uiarc.dev/components/copy-button/markdown): Copy a value with immediate confirmation. - [Hold to confirm](https://uiarc.dev/components/hold-to-confirm/markdown): Confirm a destructive action by holding, not tapping. ### Also in buttons - [Confirm morph](https://uiarc.dev/components/confirm-morph/markdown): A destructive button that morphs into an inline confirmation, a spinner, and a result with undo. ### Guidance for AI tools Button: A clear, responsive action with quiet secondary states. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it. Full library index: https://uiarc.dev/llms.txt --- ## Action button > A compact button for frequent toolbar actions. - Type: Component (actions) - Access: Free, open source - Page: https://uiarc.dev/components/action-button - Markdown: https://uiarc.dev/components/action-button/markdown - Registry item: https://uiarc.dev/r/action-button.json - Source file: `registry/components/action-button/action-button.tsx` - Dependencies: motion, lucide-react - Keywords: action, toolbar, react action button, async button, submit button with success state, save button animation, loading to success button, cta button with arrow, publish button ### When to use - A single async commit such as Save, Publish, or Submit where the result should appear on the button. - Call-to-action buttons where a trailing arrow invites the next step. - Flows where the button should reset to idle on its own after success, via resetAfterMs. ### When not to use - Use button with loading for plain form submits that do not need a success state. - Use action-swap when the control toggles between lasting states. - Use hold-to-confirm when the action is destructive and needs a deliberate press. ### Installation #### CLI Run one of these in a project set up with `shadcn init`: ```bash npx shadcn@latest add @uiarc/action-button pnpm dlx shadcn@latest add @uiarc/action-button yarn dlx shadcn@latest add @uiarc/action-button bunx --bun shadcn@latest add @uiarc/action-button ``` The `@uiarc` name needs `"registries": { "@uiarc": "https://uiarc.dev/r/{name}.json" }` in `components.json`. Without it, use the full URL: ```bash npx shadcn@latest add https://uiarc.dev/r/action-button.json ``` #### Manual 1. Install the dependencies: ```bash npm install motion lucide-react ``` 2. Copy the source into your project. Main file: `registry/components/action-button/action-button.tsx` The source is in the registry item: https://uiarc.dev/r/action-button.json 3. Arc imports use the `@/` alias for `registry/` and `lib/`. Keep the same folders or update the import paths. ### Usage ```tsx import { ActionButton } from "@/registry/components/action-button/action-button"; export function PublishButton() { return ( toast.error(String(error))} /> ); } ``` ### API reference #### ActionButton A call-to-action button with a trailing arrow that runs an async action and morphs through pending and success. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `label` (required) | `string` | – | Idle label and accessible name. | | `onAction` (required) | `() => void \| Promise` | – | Runs on press. The pending state lasts until the promise settles. | | `pendingLabel` | `string` | `"Saving"` | Label while onAction runs. | | `successLabel` | `string` | `"Saved"` | Label after onAction resolves. | | `resetAfterMs` | `number` | `2400` | Delay before returning to idle after success. 0 keeps the success state. | | `onActionError` | `(error: unknown) => void` | – | Called when onAction rejects; the button returns to idle. | | `...props` | `ButtonHTMLAttributes` | – | Forwarded to the button, except onClick. | ### Keyboard interactions | Keys | Action | | --- | --- | | Enter / Space | Runs the action. | ### Accessibility - Native button; the visible label is aria-hidden and a visually hidden copy of label names it. - Pending sets aria-busy and aria-disabled instead of disabled, so keyboard focus stays through the save. - A role="status" region announces the pending and success labels. ### Motion - Changed letters rise from a soft blur while the width springs to fit; the arrow leaves forward and a check draws itself in. - Presses scale to about 0.97 on a snappy spring. - Reduced motion drops the press scale, width spring, and stroke draw, and swaps with an instant fade. ### Responsive behavior - Width springs to fit pending and success labels, so keep them close in length inside tight toolbars. - Hover shadow applies only on hover-capable fine pointers; touch gets the press scale. ### Performance - Every letter is a motion span with layout position animation plus a small blur; fine for a few buttons, not for dense tables. - A ResizeObserver drives the width spring. ### Notes for AI - Use for a single async commit (save, publish, submit) where the result should show on the button itself. - Prefer button with loading for plain forms, and action-swap when the control toggles between lasting states. - Return the real promise from onAction; handle errors in onActionError since the button just resets. ### Related - [Button](https://uiarc.dev/components/button/markdown): A clear, responsive action with quiet secondary states. - [Hold to confirm](https://uiarc.dev/components/hold-to-confirm/markdown): Confirm a destructive action by holding, not tapping. - [Toast](https://uiarc.dev/components/toast/markdown): Brief confirmation for a completed background action. ### Also in buttons - [Split button](https://uiarc.dev/components/split-button/markdown): A primary action with a menu of nearby alternatives. - [Copy button](https://uiarc.dev/components/copy-button/markdown): Copy a value with immediate confirmation. - [Confirm morph](https://uiarc.dev/components/confirm-morph/markdown): A destructive button that morphs into an inline confirmation, a spinner, and a result with undo. ### Guidance for AI tools Action button: A compact button for frequent toolbar actions. Follow the declared prop types and do not invent props. Keep keyboard access, reduced motion support, and both light and dark themes intact when adapting it. Full library index: https://uiarc.dev/llms.txt --- ## Split button > A primary action with a menu of nearby alternatives. - Type: Component (actions) - Access: Free, open source - Page: https://uiarc.dev/components/split-button - Markdown: https://uiarc.dev/components/split-button/markdown - Registry item: https://uiarc.dev/r/split-button.json - Source file: `registry/components/split-button/split-button.tsx` - Dependencies: @radix-ui/react-dropdown-menu, motion, lucide-react - Keywords: action, menu, react split button, button with dropdown, split button menu, merge button, dropdown button, primary action with options ### When to use - One default action with a few close variants, like Merge with Squash and Rebase. - Export or share actions where one format is the usual pick and others sit behind the chevron. - Copy actions that swap the label to Copied in place while offering alternatives. ### When not to use - Use dropdown-menu when there is no default action and every option is equal. - Use button when there are no alternatives. - Use context-menu for actions tied to a piece of content rather than a toolbar. ### Installation #### CLI Run one of these in a project set up with `shadcn init`: ```bash npx shadcn@latest add @uiarc/split-button pnpm dlx shadcn@latest add @uiarc/split-button yarn dlx shadcn@latest add @uiarc/split-button bunx --bun shadcn@latest add @uiarc/split-button ``` The `@uiarc` name needs `"registries": { "@uiarc": "https://uiarc.dev/r/{name}.json" }` in `components.json`. Without it, use the full URL: ```bash npx shadcn@latest add https://uiarc.dev/r/split-button.json ``` #### Manual 1. Install the dependencies: ```bash npm install @radix-ui/react-dropdown-menu motion lucide-react ``` 2. Copy the source into your project. Main file: `registry/components/split-button/split-button.tsx` The source is in the registry item: https://uiarc.dev/r/split-button.json 3. Arc imports use the `@/` alias for `registry/` and `lib/`. Keep the same folders or update the import paths. ### Usage ```tsx import { SplitButton } from "@/registry/components/split-button/split-button"; export function MergeButton() { return ( ); } ``` ### API reference #### SplitButton A primary action joined to a chevron that opens a Radix dropdown of related actions. | Prop | Type | Default | Description | | --- | --- | --- | --- | | `label` (required) | `string` | – | Main action label. Changes morph letter by letter. | | `actions` (required) | `SplitButtonAction[]` | – | Menu items: { label, onSelect?, disabled?, destructive?, icon? }. | | `onClick` | `() => void` | – | Runs the main action. | | `icon` | `ReactNode` | – | Leading icon on the main half. A different icon element crossfades in. | | `variant` | `"primary" \| "secondary"` | `"primary"` | Visual weight of both halves. | | `disabled` | `boolean` | – | Disables both the main action and the menu trigger. | ### Keyboard interactions | Keys | Action | | --- | --- | | Enter / Space | Runs the main action, or opens the menu from the chevron. | | ArrowDown / ArrowUp | Moves between menu items, looping at the ends. | | Escape | Closes the menu and returns focus to the chevron. | ### Accessibility - Two native buttons; the chevron is labelled "