Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelogApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip
ARC UIARC Radiant Components
v4.9DocsComponentsTokensSynthesizer
Getting StartedFrameworksServer RenderingDesign TokensThemingTheme SynthesizerTypographyUtilitiesAll ComponentsAccessibilityBrowser SupportChangelogContributingStatsApp ShellAspect GridAuth ShellCenterContainerDashboard GridFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbarAnchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkStepper NavTabsTop BarTree ViewAccordionAspect RatioAvatarAvatar GroupCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSkeletonSpinnerStackVideoVirtual ListActivity HeatmapAnimated NumberBadgeBar ListChartClockComparisonCountdown TimerData GridDescription ListDiffGaugeJSON TreeKanbanLevel MeterListMeterSparklineStatStepperTagTimelineUptimeValue CardWaveformBlockquoteCode BlockCode GroupGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriterButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerField ListFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree SelectAlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuHover CardLoading OverlayNotification PanelPopoverProgressSheetToastTooltip

Getting Started

ARC UI is 169 Lit web components that run natively in the browser, with typed wrappers generated for seven frameworks from the same source. One install, one import, and you are rendering.

Install

One runtime dependency: Lit. The CDN tab needs no build step at all.

Your First Component

  1. Import the tokens and register the components

    The stylesheet carries every design token; the register module defines all169 custom elements.

  2. Load the fonts

    ARC UI ships no font files. base.css names three reference faces (Host Grotesk for text, Tomorrow for labels, JetBrains Mono for code) and loads none of them, so without this step everything quietly renders in system-ui. A font CDN is the quickest way in:

    To self-host, or to use your own typefaces instead, seeLoading the Font Files.

  3. Write the markup

    They are HTML elements. No provider, no wrapper, no client directive.

  4. That is it. This is that markup, live

    Rendered by this page from the snippet above, not a screenshot of it.

    Get Started

Import Patterns

Three ways in, and the one you want depends on whether you are shipping a page or an app. Start at the top and move down when bundle size starts to matter.

@arclux/arc-ui/registerEvery component. Simplest, and the right default while you are exploring.
@arclux/arc-ui/buttonOne component and its dependencies. Tree-shakeable, and what a production app should use.
{ ArcButton } from '@arclux/arc-ui'The named class, for extending or instantiating in script. Pulls in the full registry.
arc-code-block is the one exception: it carries a syntax highlighter, so it is excluded from every barrel. Import it at @arclux/arc-ui/code-block.

Framework Setup

Prism reads the Lit source and generates a native wrapper package per framework: typed props, idiomatic events, tree-shakeable imports. Same components, different import:

The Frameworks guide covers install and usage for each one, including the SSR story.

Theming

Three theme modes, one attribute on <html>:

The toggle in this site's top bar sets exactly that attribute. Try it. For a theme of your own, override the tokens (see Theming) or build one visually in the Theme Synthesizer and export it.

Design Tokens

237 custom properties drive the visual language, and they are the same ones the components read. Import the stylesheet and your own CSS speaks the same system:

Colors
Spacing--space-xs · sm · md · lg · xl · 2xl
Radii--radius-xs · sm · md · lg · xl · full
Shadows--shadow-xs · sm · md · lg · xl

The Design Tokens reference lists every one.

TypeScript

The framework wrappers ship their own types. For plain web components, add the ambient declarations and every arc-* element gets autocomplete and checking in JSX and template literals:

Your Own Components

A component you write with Lit has its own shadow root, and a shadow root does not see document styles. The *, *::before, *::after { box-sizing: border-box }reset in your global stylesheet stops at its boundary, so padded boxes inside it overflow in a way nothing on the page explains.

Adopt the styles ARC UI's own components start from.tokenStyles carries the box-sizing and margin reset, the static token defaults, and the reduced-motion rule:

Themed tokens (colors, shadows, gradients) are not in it and do not need to be. Custom properties inherit through the shadow boundary, so they arrive from base.csson the document as they do for every ARC component.

tokenStyles also zeroes every margin and padding, as ARC's components expect. To add only the box-sizing reset to components you already have, adoptresetStyles from the same module instead.

Testing

Some components read the children you write as data and render their own copies. Thearc-menu-items inside arc-dropdown-menu and thearc-options inside arc-segmented-control andarc-select are display: none. The visible, clickable item is the copy in the parent's shadow root. A test that clicks the element you authored fails with "element is not visible", however correct the markup is. Each component that works this way says so on its default slot ("read as data") in the API reference and incustom-elements.json, where each parent also lists the elements it expects under children, with their slot.

Find the rendered item the way a user does, by its role and its text. The rendered copies carry the roles (menuitem, radio, option), and Playwright's role locators pierce shadow roots:

Going to Production

Nothing here is needed to build with ARC UI. It covers what to do once you are shipping it.

A custom element renders its fallback content until JavaScript registers it.base.css ships the guard for that (:not(:defined) { opacity: 0 }), so unregistered components stay hidden and fade in as their definitions land. On a page registering many of them, two additions make the upgrade invisible.

Register what is above the fold first. Static imports of the components visible on first paint form a small, fast chunk; the full registry loads lazily behind it.

Reserve space for layout-critical elements. A hidden element still occupies layout, so give shell components their final size before they upgrade and nothing shifts when the definitions arrive.

This site does exactly that: the visible frame upgrades from a chunk roughly an eighth the size of the full registry. If you server-render, seeServer Rendering: every component emits declarative shadow DOM, so the markup arrives styled before any of this matters.

Next Steps