Getting started
Two ways in: scaffold a new project, or add helix-ui to an app you already have.
Every snippet on this page is the same code the create-helix-ui-app templates
ship, which CI scaffolds, installs, and compiles on every commit.
Requirements
- Node 20 or newer
- React 18 or 19 — both are supported peer ranges
- A bundler that understands ESM and CSS imports (Vite, Next.js, Remix, Parcel, webpack 5). helix-ui ships ESM only.
What it costs you
Named imports tree-shake, so you pay for what you render. Measured gzipped, with
react and react-dom treated as already present, each component bundled alone:
| Import | gzip |
|---|---|
Button, Text, Card, Stack, Badge | 250–450 B each |
TextInput, Switch, Checkbox | 11–14 kB |
Dialog | ~18 kB |
Select | ~57 kB |
A typical form (TextInput + Checkbox + Select + Button) | ~60 kB |
@helix-ui/tokens CSS | ~1.6 kB |
One icon from @helix-ui/icons | ~380 B |
The shape is worth understanding before you commit: the layout and visual
primitives are almost free because they are CSS-driven markup with no behavior.
The cost arrives with the first interactive component, which pulls in
React Aria — that’s the price of
the focus management, keyboard interaction, and ARIA wiring you’d otherwise
write yourself. Select is the outlier; it brings the overlay, listbox, and
collection machinery with it.
These numbers are enforced as budgets in CI (pnpm size), so they can’t drift
silently.
Option A — start a new app
npm create helix-ui-app@latest my-appcd my-appnpm run devThe scaffolder asks which template you want and installs with whichever package manager you invoked it with:
| Template | What you get |
|---|---|
minimal | One themed card and the DNA preset switcher. Start here. |
admin | Sidebar, page header, stat cards, data table. |
marketing | Hero, feature grid, pricing. |
agent-ui | Chat shell with thinking blocks and tool calls. |
Pick one non-interactively with --template:
npm create helix-ui-app@latest my-app -- --template adminOption B — add to an existing app
npm install @helix-ui/core @helix-ui/tokens @helix-ui/dna @helix-ui/icons@helix-ui/core needs @helix-ui/tokens and @helix-ui/dna, so a package
manager will pull them in regardless — installing them explicitly just makes the
dependency visible in your manifest. @helix-ui/icons is optional.
1. Import the stylesheet, once
At your app entry, before your own CSS:
import '@helix-ui/core/styles.css';That’s the only import you need — styles.css already @imports
@helix-ui/tokens/css, so the design tokens come with it.
Skip it and every component renders as a plain browser default: component CSS
references var(--helix-ui-…) with no fallbacks, so with no stylesheet loaded
those declarations are simply invalid. In development helix-ui notices and tells
you in the console; in production it says nothing, so keep the import.
What that stylesheet will and won’t do to your app
Dropping a component library into an app that already has styles is usually the risky part, so this is explicit:
- It only styles its own elements. Every rule is scoped to a
helix-ui-*class. Nothing selectsbody,*,button,a, or any element your app owns — importing helix-ui cannot change how your existing markup renders. - It ships no global reset. Your margins, your typography, your box model stay exactly as they were.
- It doesn’t depend on your reset either. helix-ui applies
box-sizing: border-boxto its own elements, so components size correctly whether or not your app has a reset of its own. - The one shared hook is
data-theme. helix-ui readsdata-theme="light"/"dark"to pick its token set, so if your app already toggles that attribute, helix-ui follows your theme automatically. It only ever defines--helix-ui-*variables there — it never restyles your elements.
helix-ui does not use CSS @layer, so its rules compete on normal specificity.
Most are a single class (0,1,0), so your own class targeting the same element
wins by source order or a slightly more specific selector — no !important
needed.
Importing the tokens on their own is also fine if you want the CSS variables without any components:
import '@helix-ui/tokens/css';2. Wrap your tree in a DNA provider
import { HelixUIDNAProvider } from '@helix-ui/core';import { wildtype } from '@helix-ui/dna';
export function App() { return <HelixUIDNAProvider dna={wildtype()}>{/* your app */}</HelixUIDNAProvider>;}wildtype() is the default genome. The provider resolves it into CSS variables
on a wrapper element, so everything below re-themes through the cascade — no
context reads, no re-renders.
3. Render something
import { Button, Card, Stack, Text } from '@helix-ui/core';import { Sparkle } from '@helix-ui/icons';
<Card variant="elevated" style={{ padding: 'var(--helix-ui-space-8)' }}> <Stack gap={5}> <Stack direction="row" gap={3} align="center"> <Sparkle /> <Text size="2xl" weight="semibold"> Hello, helix-ui. </Text> </Stack> <Button tone="brand">Ship it</Button> </Stack></Card>;That’s the whole setup. Everything else on this site is detail.
Change the theme
Swap the genome and the tree follows. The five built-in presets:
import { PRESETS, wildtype } from '@helix-ui/dna';
<HelixUIDNAProvider dna={PRESETS.noir()}>…</HelixUIDNAProvider>;wildtype · studio · botanic · solstice · noir.
To go further than a preset, breed one:
npx @helix-ui/dna breed studio noir --seed 42 --output shorthandPass the resulting mutations array to the provider. See
DNA for the gene model.
Framework notes
Next.js App Router — every helix-ui component carries 'use client', so
importing one from a server component works without extra wrapping. Import the
stylesheets in app/layout.tsx. See React Server Components.
Components also hydrate cleanly: nothing renders from Math.random(), from the
viewport, or from document on the first pass, so the browser reproduces the
server’s HTML instead of replacing it. Components that do care about the
viewport or the current theme — Chart, CodeEditor — render the server’s
answer while hydrating and pick up the real one immediately after. A test
renders the library in Node and hydrates it in a real browser on every CI run,
so this stays true.
Tailwind — helix-ui tokens are available as a Tailwind preset, so utilities and components share one scale rather than drifting. See Tailwind.
TypeScript — every package you import from ships its own declarations
(@helix-ui/core, tokens, dna, icons, document, slides); no @types/*
needed. The spec.md beside each component is the same API surface the types
express. The CLI-only packages (@helix-ui/mcp, @helix-ui/prompt,
@helix-ui/stylelint-plugin) are plain JS — you run them, you don’t import them.
Point your AI tools at it
helix-ui is built to be read by a model as easily as by a person:
claude mcp add helix-ui -- npx -y @helix-ui/mcpOr hand any assistant a single URL: llms.txt for the index,
llms-full.txt for everything. See
Integrations for Cursor, Copilot, Windsurf, and
a tool-agnostic AGENTS.md.
Where to next
- Components — every component’s props, tokens, and a11y contract.
- Tokens overview — how the DTCG JSON becomes CSS variables.
- DNA — the 22-gene theme model.
- Compatibility — exact versions helix-ui is tested against.