Skip to content

Tailwind CSS

helixui is not a Tailwind replacement. The two solve different problems, and a lot of teams want both:

  • helixui ships components, tokens, an a11y baseline, and a theme engine.
  • Tailwind ships layout utilities (flex, grid, gap-4, md:px-6) that are awkward to express any other way.

This page shows how to use them together without fighting either.

Install both

Terminal window
npm install @helixui/core @helixui/tokens @helixui/icons tailwindcss postcss autoprefixer
npx tailwindcss init -p

Mirror helixui tokens into Tailwind’s theme

This is the key step. Tailwind’s theme.extend reads helixui’s token variables so utilities like bg-brand-500 resolve to the same OKLCH color helixui’s components use.

tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
content: [
'./index.html',
'./src/**/*.{ts,tsx,js,jsx}',
// Match helixui's own component source so Tailwind doesn't purge
// utilities that exist inside @helixui/core's CSS files.
'./node_modules/@helixui/core/dist/**/*.{js,mjs,css}',
],
theme: {
extend: {
colors: {
brand: {
50: 'oklch(var(--helixui-color-brand-50-l) var(--helixui-color-brand-50-c) var(--helixui-color-brand-50-h))',
// ... or simpler: read the CSS var directly
DEFAULT: 'var(--helixui-color-bg-action-brand-default)',
},
// ...repeat for neutral, success, warning, danger
},
spacing: {
// helixui scales spacing via the density gene. Don't hard-code
// here — point at the CSS variable.
1: 'var(--helixui-space-1)',
2: 'var(--helixui-space-2)',
3: 'var(--helixui-space-3)',
4: 'var(--helixui-space-4)',
6: 'var(--helixui-space-6)',
8: 'var(--helixui-space-8)',
},
borderRadius: {
sm: 'var(--helixui-radius-sm)',
DEFAULT: 'var(--helixui-radius-md)',
lg: 'var(--helixui-radius-lg)',
},
fontFamily: {
sans: 'var(--helixui-font-family-sans)',
mono: 'var(--helixui-font-family-mono)',
},
},
},
// Tailwind's reset can clash with helixui's component CSS. Disable
// preflight and either rely on helixui's reset or write your own.
corePlugins: { preflight: false },
};

The corePlugins.preflight: false is the one non-obvious bit — Tailwind’s CSS reset (@tailwind base) nukes some defaults helixui relies on. If you’re moving an existing Tailwind project to helixui, this line prevents a wave of subtle visual breakage.

Import both stylesheets

src/index.css
@import '@helixui/tokens/css';
@import '@helixui/core/styles.css';
@tailwind components;
@tailwind utilities;

helixui’s stylesheet ships first so Tailwind utilities can override.

Use them in tandem

import { Button, Card, Stack } from '@helixui/core';
function PaymentRow({ amount, status }: Props) {
return (
// helixui Card + Stack handle the design system. Tailwind handles
// the page layout.
<Card className="md:col-span-2">
<Stack direction="row" align="center" justify="between" className="gap-4">
<div className="text-brand">{amount}</div>
<Button>Pay</Button>
</Stack>
</Card>
);
}

Rule of thumb:

Use helixui forUse Tailwind for
Buttons, inputs, cards, dialogs, popoversGrid spans, responsive breakpoints
Color, radius, typography, motionMargins, padding overrides at breakpoints
Anything that should be themable via DNAAnything that’s “just layout”

When the cascade fights

If you find yourself writing !bg-brand-500 to override a helixui component’s background, that’s a smell — the right move is to pass helixui’s own variant / tone prop. Tailwind override should be for layout properties, not visual ones.

// ❌ Fighting the cascade
<Button className="!bg-purple-600">Save</Button>
// ✅ Use helixui's API
<Button tone="brand" variant="solid">Save</Button>
// ✅ Tailwind for layout
<Button className="w-full md:w-auto">Save</Button>

What you give up

  • Two stylesheets to ship. Together they’re ~30 KB gzip. Tradeoff for the breadth.
  • Two mental models for color. helixui’s tokens are the source of truth; the Tailwind names mirror them. Don’t author colors in two places.

Migrating from Tailwind-only

A typical path:

  1. Install helixui.
  2. Set corePlugins.preflight: false.
  3. Replace your hand-rolled <button className="bg-blue-600 px-4 py-2 ...">s with <Button>.
  4. Keep your layout utilities (grid, flex, md:*) — they’re still useful.
  5. Move your colors into helixui tokens so DNA themes Just Work.

The migration is incremental. You don’t have to do it all at once.