Tailwind CSS Best Practices for Large Scale Design Systems
Tailwind CSS has revolutionized styling by adopting a utility-first approach. However, as projects grow into massive design systems like our UI Encyclopedia, managing thousands of utility classes requires discipline and structure.
1. Single Source of Truth (tailwind.config.ts)
Don't use arbitrary values (e.g., w-[413px]) unless absolutely necessary. Your tailwind.config.ts should define your entire design system: colors, spacing, typography, and breakpoints.
// tailwind.config.ts theme: { extend: { colors: { primary: 'var(--primary)', secondary: 'var(--secondary)', } } }
Using CSS variables for colors allows for easy implementation of Dark Mode later on.
2. Component Abstraction vs. @apply
A common mistake is overusing @apply to recreate traditional CSS classes.
Bad:
.btn { @apply px-4 py-2 bg-blue-500 text-white rounded; }
Good: Create a React component.
export function Button({ children }) { return <button className="px-4 py-2 bg-blue-500 text-white rounded">{children}</button> }
This keeps the utility nature of Tailwind while providing reusability through the framework (React), not the stylesheet.
3. Class Ordering
Inconsistent class ordering makes code hard to read. Use the official prettier-plugin-tailwindcss. It automatically sorts your classes (e.g., layout first, then spacing, then typography).
4. Derived Styles with "cva"
For complex components with multiple variants (primary component, secondary, outline, ghost), use class-variance-authority (cva).
const button = cva("button", { variants: { intent: { primary: "bg-blue-500 hover:bg-blue-600", secondary: "bg-gray-500 hover:bg-gray-600", }, size: { small: "text-sm py-1 px-2", medium: "text-base py-2 px-4", }, }, });
5. Avoid Dynamic Class Names
Tailwind's compiler (JIT) needs to see the full class name to generate the CSS.
Don't do: bg-${color}-500
Do: Map props to full class names or use the full string.
Conclusion
Tailwind scales incredibly well if you treat it as an API for your design system rather than just a way to write inline styles. By leveraging configuration and component composition, you can maintain consistency across thousands of pages.
