Theme oks-ui to your brand in 10 minutes
· 5 min read · oks-ui team
oks-ui ships with a neutral default look on purpose — every colour, radius, space, and shadow it renders is a plain CSS custom property, not a baked-in design opinion. That means re-theming it isn't a config file or a build step; it's a stylesheet. Here's the whole path from default to your brand, in the order that actually matters.
1. Start with the primary ramp, not just one colour
primary is the semantic role that colours your main buttons, links, and focus rings. It's tempting to override just--oks-color-primary-500 and call it done, but a solid button also reads 600 for hover and 700 for pressed — override the whole ramp so those states stay coherent instead of falling back to the default orange.
:root {
--oks-color-primary-50: #eef2ff;
--oks-color-primary-100: #e0e7ff;
--oks-color-primary-500: #4f46e5; /* your brand */
--oks-color-primary-600: #4338ca; /* hover */
--oks-color-primary-700: #3730a3; /* active / pressed */
}500+ by default. Before you lock in a brand colour, check that white clears 4.5:1 against it — a vivid, light colour like a saturated yellow or orange usually won't, and needs a slightly deeper 500 to stay accessible.2. Match your shape language
Radius is one scale, reused everywhere — cards, buttons, inputs, modals. Nudge the two or three sizes you actually see and the whole UI shifts from sharp to soft in one edit.
:root {
--oks-radius-sm: 0.125rem; /* chips, small controls */
--oks-radius-md: 0.5rem; /* the one most components default to */
--oks-radius-lg: 0.875rem; /* cards, modals */
}3. Dial in density
The space scale drives padding and gaps across the library. If your product wants to feel airier or more compact than the default, nudge --oks-space-4 — it's the workhorse most components reach for.
:root { --oks-space-4: 14px; } /* default is 16px */4. Point neutral surfaces at your own grey
If your brand's grey isn't oks-ui's default, alias the neutral role instead of overriding a dozen individual tokens — form-field borders and muted text all read from it.
:root {
--oks-color-neutral-100: var(--oks-palette-stone-100);
--oks-color-neutral-500: var(--oks-palette-stone-500);
}5. Do it again for dark mode
Dark mode is a data-theme="dark" attribute on <html>, not a second theme system — repeat the same overrides under that selector. The one thing to remember is that two tokens (--oks-color-surface and the form-field background) have light-only defaults, so your app has to supply the dark values itself:
:root[data-theme="dark"] {
--oks-color-primary-500: #6366f1; /* usually a touch lighter than light mode */
--oks-color-surface: #0a0a0a;
--oks-form-field-bg: #171717;
}That's the whole system — no provider, no rebuild, no JavaScript theme object. See the full token reference at Theming and dark-mode specifics at Dark mode.