# tailwind-to-style > Zero-build runtime Tailwind CSS engine. Convert utility classes to real CSS at runtime — with variants, slots, design tokens, and React bindings. ## Installation ``` npm install tailwind-to-style ``` ## Overview tailwind-to-style replaces the Tailwind CSS build step entirely. You write Tailwind utility classes as strings, and the library generates and injects real CSS into the DOM at runtime. It supports responsive breakpoints (md:, lg:), pseudo-classes (hover:, focus:), arbitrary values, variants, slots, design tokens, and SSR. --- ## API Reference ### `tw()` — The main function (4 modes) #### Mode 1: Atomic classes Pass a string of Tailwind utilities. Returns auto-generated class names. CSS is injected into the DOM automatically, including @media queries and pseudo-class rules. ```js import { tw } from 'tailwind-to-style'; tw('flex items-center gap-4 hover:bg-gray-100 md:hidden') // Returns: "tw-flex tw-items-center tw-gap-4 tw-hover-bg-gray-100 tw-md-hidden" ``` Use with `className={}` in React. Supports all responsive prefixes (sm:, md:, lg:, xl:, 2xl:) and pseudo-classes (hover:, focus:, active:, disabled:, focus-within:, etc.). #### Mode 2: Named class (preferred for static styles) Two string arguments: name + Tailwind classes. Returns the name as the class. This is the preferred shorthand for defining reusable static styles. ```js tw('sidebar', 'w-64 h-screen bg-white border-r border-gray-200') // Returns: "sidebar" // Injects: .sidebar { width: 16rem; height: 100vh; background: #fff; ... } ``` #### Mode 3: Variants (returns a selector function) Object config with `name`, `base`, `variants`, optional `compoundVariants` and `defaultVariants`. Returns a function you call with variant selections. ```js const button = tw({ name: 'btn', base: 'px-4 py-2 rounded-lg font-medium transition-all cursor-pointer', variants: { color: { primary: 'bg-blue-600 text-white hover:bg-blue-700', secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300', danger: 'bg-red-600 text-white hover:bg-red-700', ghost: 'bg-transparent text-gray-700 hover:bg-gray-100', }, size: { sm: 'text-sm px-3 py-1.5', md: 'text-base px-4 py-2', lg: 'text-lg px-6 py-3', }, fullWidth: { true: 'w-full', }, }, compoundVariants: [ { color: 'primary', size: 'lg', class: 'shadow-lg shadow-blue-500/25' }, { color: 'danger', size: 'lg', class: 'shadow-lg shadow-red-500/25' }, ], defaultVariants: { color: 'primary', size: 'md' }, }) button({ color: 'danger', size: 'lg' }) // Returns: "btn btn--color-danger btn--size-lg" ``` #### Mode 4: Slots (multi-part components) Object config with `name`, `slots`, and `variants` where each variant value is an object mapping slot names to classes. ```js const card = tw({ name: 'card', slots: { root: 'bg-white rounded-xl border overflow-hidden', header: 'border-b flex items-center justify-between', title: 'font-semibold text-gray-900', body: 'text-gray-700', footer: 'border-t bg-gray-50', }, variants: { variant: { default: { root: 'border-gray-200 shadow-sm', header: 'border-gray-100', footer: 'border-gray-100', }, elevated: { root: 'border-gray-200 shadow-lg hover:shadow-xl', header: 'border-gray-100', footer: 'border-gray-100', }, }, size: { sm: { header: 'px-4 py-3', title: 'text-sm', body: 'px-4 py-3 text-sm', footer: 'px-4 py-3' }, md: { header: 'px-6 py-4', title: 'text-base', body: 'px-6 py-4', footer: 'px-6 py-4' }, lg: { header: 'px-8 py-5', title: 'text-lg', body: 'px-8 py-5', footer: 'px-8 py-5' }, }, }, defaultVariants: { variant: 'default', size: 'md' }, }) const slots = card({ variant: 'elevated', size: 'lg' }) // Returns: { root: "card__root card__root--variant-elevated card__root--size-lg", ... } // Use:
...

... ``` --- ### `tws()` — Inline style converter Converts Tailwind classes to CSS string or JS style object. Does NOT support responsive or pseudo-class variants (those require `tw()`). ```js import { tws } from 'tailwind-to-style'; // CSS string tws('bg-blue-500 text-white p-4 rounded-lg') // → "background-color: rgb(59,130,246); color: #fff; padding: 1rem; border-radius: 0.5rem;" // JS object (pass true as second arg) tws('flex items-center gap-4', true) // → { display: 'flex', alignItems: 'center', gap: '1rem' } ``` --- ### `cx()` — Conditional class merging ```js import { cx } from 'tailwind-to-style'; cx('base-class', isActive && 'ring-2 ring-blue-500', { 'opacity-50': disabled }) cx(button({ color: 'primary' }), disabled && tw('opacity-50 pointer-events-none'), className) ``` --- ### Design Tokens ```js import { createTheme, activateTheme, token, tokenRegistry } from 'tailwind-to-style/tokens'; createTheme({ colors: { primary: '#2563eb', surface: '#ffffff', text: '#0f172a', border: '#e2e8f0' }, }, { name: 'light' }); createTheme({ colors: { primary: '#60a5fa', surface: '#1e293b', text: '#f1f5f9', border: '#334155' }, }, { name: 'dark' }); // Reference in tw() via arbitrary value syntax tw('themed-btn', `bg-[${token('colors.primary')}] text-white px-4 py-2 rounded-lg`) // token('colors.primary') → "var(--tws-colors-primary)" // Switch themes at runtime activateTheme('dark') // Programmatic access tokenRegistry.get('colors.primary') tokenRegistry.set('colors.primary', '#1d4ed8') tokenRegistry.subscribe((tokens) => { /* react to changes */ }) tokenRegistry.toCSS() // → ":root { --tws-colors-primary: ...; }" ``` --- ### React Bindings ```jsx import { ThemeProvider, useTheme, styled } from 'tailwind-to-style/react'; // Inside components: const { tokens, setTheme } = useTheme(); // styled() — creates React components with variant props const Button = styled('button', { name: 'btn', base: 'px-4 py-2 rounded-lg font-medium', variants: { color: { primary: 'bg-blue-600 text-white', secondary: 'bg-gray-200 text-gray-800' }, }, defaultVariants: { color: 'primary' }, }) ``` --- ### Animations ```js import { animate, defineAnimation } from 'tailwind-to-style/animations'; element.className = animate('fadeIn', { duration: '300ms', delay: '100ms' }); // Built-in: fadeIn, fadeOut, slideInUp, slideInDown, slideInLeft, slideInRight, // scaleIn, scaleOut, bounce, shake, pulse, spin, ping defineAnimation('wiggle', { keyframes: [ { transform: 'rotate(0deg)' }, { transform: 'rotate(-3deg)' }, { transform: 'rotate(3deg)' }, { transform: 'rotate(0deg)' }, ], duration: '300ms', easing: 'ease-in-out', }); ``` --- ### SSR (Server-Side Rendering) ```js import { tw, createSSRCollector } from 'tailwind-to-style'; const collector = createSSRCollector(); const html = renderToString(); const css = collector.extract(); // Inject css into