# 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. Arc has 242 components and 141 blocks. 121 components and 22 blocks are free and open source (MIT); 121 components and 119 blocks are Arc Pro. Arc Pro costs $149 per year or $249 once for lifetime access, and a team plan covers up to 10 people for $799 once or $449 per year. Plans: https://uiarc.dev/pricing. ## Install Arc items are shadcn-compatible registry items. Each one pulls in the motion presets (`arc-motion-tokens`) and any Arc components it builds on. The design tokens (`arc-foundation`, `foundation.css`) install once per app, and no item reinstalls them. ```bash npx shadcn@latest add https://uiarc.dev/r/arc-foundation.json 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 ``` Import the tokens once in the root layout: `import "@/components/arc/foundation.css";`. Files install into an `arc/` folder under the `components` alias from `components.json` (for example `components/arc/button/button.tsx`, or `src/components/arc/…` in a `src/` project or a monorepo package) and import each other with relative paths, so no `tsconfig.json` change is needed. Import them from there: `import { Button } from "@/components/arc/button/button";`. 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 unlocks Pro for a Pro account that signed in through the MCP client (OAuth), or with the same token as `Authorization: Bearer …`: `get_component` then returns Pro source and `get_install_command` returns `@uiarc-pro` commands. Without Pro access, 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 `components/arc/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 on pointer focus (keyboard focus gets the shared :focus-visible ring), 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 region by region with every state, build, and verify a whole page, or stop at the plan - 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 - [Best React component libraries in 2026](https://uiarc.dev/guides/best-react-component-libraries): How shadcn/ui, Magic UI, Aceternity UI, React Bits, HeroUI, Mantine, MUI and Arc differ, and when to pick each - [Best UI library for AI coding agents](https://uiarc.dev/guides/best-ui-library-for-ai-coding-agents): What makes a library agent-friendly: registry, MCP server, llms.txt, per-component markdown ## Comparisons - [Compare Arc](https://uiarc.dev/compare): Fact tables against other React UI libraries, with the date each fact was checked - [Arc vs Magic UI](https://uiarc.dev/compare/magic-ui): Stack, license, free and paid items, install method and AI support - [Arc vs Aceternity UI](https://uiarc.dev/compare/aceternity-ui): Stack, license, free and paid items, install method and AI support - [21st.dev alternative](https://uiarc.dev/compare/21st-dev): Arc compared with the 21st.dev community registry ## Templates - [Templates](https://uiarc.dev/templates) (Pro): Complete starter apps built from Arc blocks - [Arc CRM](https://uiarc.dev/templates/arc-crm) (Pro): Relay, a clean CRM for sales teams: companies, company records, people, a deals pipeline and a linked inbox # 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 "@/components/arc/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. - Disabled primary buttons fade as a whole. Disabled secondary and danger buttons keep their border and take a muted fill and label, and disabled ghost buttons take a muted label, so an unavailable action still reads as a button. ### 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 - [Button group](https://uiarc.dev/components/button-group/markdown): Related actions joined into one surface with hairline dividers: a hover highlight glides between segments, the pressed one answers in place, and an attached menu can close the row. - [Floating button group](https://uiarc.dev/components/floating-button-group/markdown): Separate soft buttons in a quiet tray, with one shared highlight that morphs from button to button as you move, and a pressed state that settles in place. - [Expanding button group](https://uiarc.dev/components/expanding-button-group/markdown): Icon buttons in a compact group: the one you point at or focus grows to reveal its label while its neighbours slide aside, and an action confirms in place. - [Action swap](https://uiarc.dev/components/action-swap/markdown): Swap an action label while preserving its place and intent. - [Icon morph](https://uiarc.dev/components/icon-morph/markdown): Icons that morph between states: menu to close, play to pause, copy to check, and more. - [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 "@/components/arc/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. - [Action swap](https://uiarc.dev/components/action-swap/markdown): Swap an action label while preserving its place and intent. - [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. - [Button group](https://uiarc.dev/components/button-group/markdown): Related actions joined into one surface with hairline dividers: a hover highlight glides between segments, the pressed one answers in place, and an attached menu can close the row. - [Floating button group](https://uiarc.dev/components/floating-button-group/markdown): Separate soft buttons in a quiet tray, with one shared highlight that morphs from button to button as you move, and a pressed state that settles in place. - [Expanding button group](https://uiarc.dev/components/expanding-button-group/markdown): Icon buttons in a compact group: the one you point at or focus grows to reveal its label while its neighbours slide aside, and an action confirms in place. - [Copy button](https://uiarc.dev/components/copy-button/markdown): Copy a value with immediate confirmation. - [Icon morph](https://uiarc.dev/components/icon-morph/markdown): Icons that morph between states: menu to close, play to pause, copy to check, and more. - [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 "@/components/arc/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 "