Styling
Customize Honest UI's semantic CSS tokens, themes, and copied component classes.
Honest UI separates visual decisions into CSS tokens and component classes. Tokens keep shared decisions consistent; copied component files give you local control when one component needs to change.
For the complete token reference, start with Theme, then open the page for colors, typography, spacing, radius, or effects. This page focuses on deciding where a customization belongs.
Install the shared styles
The init command installs the shared style setup and records the stylesheet path in components.json:
npx honestui@latest initRun initialization once before adding UI components. If the project is already initialized, inspect components.json instead of replacing it.
How the token system works
Every Honest UI token starts with --hui-; hui stands for Honest UI. Tokens are organized from low-level values to semantic roles:
Components should normally use semantic tokens rather than primitive palette values. For example, a destructive action uses a danger role so the component remains meaningful when the palette changes.
Use tokens in Tailwind
Copied Honest UI components pass tokens through Tailwind CSS arbitrary-value utilities. Use the same pattern in your own component code:
<div
className="
rounded-[var(--hui-radius-3)]
border border-[var(--hui-color-border-base-primary)]
bg-[var(--hui-color-background-base-secondary)]
p-[var(--hui-space-5)]
text-[var(--hui-color-foreground-base-primary)]
shadow-[var(--hui-shadow-feather)]
"
/>The same classes resolve in light and dark themes because the browser reads the current variable values. Tailwind v4 also supports shorter custom-property syntax and optional semantic aliases; see Tailwind CSS for the complete guidance.
Light and dark themes
Theme values are scoped with data-theme:
<html data-theme="light">Switch the value to dark for the dark theme. If you use a theme library, configure it to write the same data-theme values.
The primitive gray and accent scales resolve differently for each theme, while semantic roles keep their names. A component can therefore continue using --hui-color-background-base-primary without knowing which theme is active.
Change the palette
Set theme and palette attributes on a shared ancestor:
<html
data-theme="light"
data-gray-color="gray"
data-accent-color="orange"
>Change primitive palette values when you are adapting the entire system. Change semantic values when your product needs a different meaning for a role.
Keep semantic token names stable when possible. Changing a token's value updates every component that uses that role; renaming it requires updating each reference.
Customize one component
Copied UI components are normal source files. Edit their class names when a change belongs to one component:
<Button className="min-w-32">Save profile</Button>Add or adjust a variant when the same option must be reused. Do not create a new shared token for a single isolated value unless it represents a product-wide decision.
Check every state
After changing tokens or classes, verify:
- Default, hover, active, focus, disabled, and invalid states.
- Light and dark themes.
- Text and non-text contrast.
- Focus visibility in keyboard use.
- Meaning without color alone.
- Content at 200% and 400% zoom or equivalent reflow.
- Forced-colors behavior where the component supports system colors.
Use text, icons, labels, or patterns alongside color when a state must be understood. A new palette should not turn warning, success, or destructive states into color-only distinctions.