Building a design system with Tailwind CSS 4 and React.
How we built Ketryon's component library using Tailwind CSS 4's new features — oklch colors, @theme directives, and a component-first architecture.
Every project started from scratch.
Before the design system, every new Ketryon project meant rebuilding the same components — buttons, cards, navigation, layouts. Same patterns, slightly different implementations, subtle inconsistencies.
We needed a shared component library that was flexible enough to adapt across projects but opinionated enough to enforce consistency. And with Tailwind CSS 4 landing, the timing was right to rethink our approach from the ground up.
The system by the numbers.
We shipped the first version in three weeks. It now powers every Ketryon project.
Components in the core library.
Color palettes supported via oklch.
External CSS dependencies. It's all Tailwind.
What Tailwind CSS 4 unlocked.
Tailwind CSS 4 introduced features that fundamentally changed how we approach design systems. Here are the decisions that mattered most.
oklch color palette
We defined our sage palette in oklch — perceptually uniform colors that look consistent across lightness levels. Dark mode is just a different set of oklch values, not a separate palette.
@theme for design tokens
Tailwind 4's @theme directive lets us define tokens in CSS and reference them in utility classes. Fonts, colors, spacing — all in one place, all type-safe.
Component-first architecture
Each component is a self-contained React component with its own props interface. No CSS modules, no styled-components — just Tailwind utilities composed via cn().
Composition over configuration
Components like Section, Container, and Text are building blocks, not page templates. They compose together to create any layout without fighting the system.
Dark mode as a first-class citizen
Every component supports dark mode from the start. The oklch palette means we can derive dark variants mathematically rather than hand-picking hex values.
Serif + sans pairing
Playfair Display for headings, Manrope for body text, JetBrains Mono for code. The type scale is built into the Tailwind config as semantic classes.
The details that make it feel like Ketryon.
A design system isn't just components — it's the small details that create a recognizable identity.
Corner dots
Subtle decorative dots in card corners. A small detail that ties every card and panel together visually.
Bracket eyebrows
Section labels wrapped in monospaced brackets — [ Like this ]. Gives a technical, precise feel without being cold.
Dashed dividers
Horizontal dashed lines between sections. Lighter than solid borders, they create rhythm without visual weight.
Wallpaper backgrounds
Gradient backgrounds with SVG noise texture overlay. Four color options (green, blue, purple, brown) for visual variety.
Mono step numbers
Process steps labeled with monospaced 01, 02, 03. Clean, scannable, and immediately conveys sequence.
Serif headlines
Playfair Display for major headings creates contrast with the sans-serif body. Feels authoritative without being stuffy.
What we'd do differently.
Three months in, we have enough perspective to be honest about what we got right and wrong.
Start with fewer components. We built 19 components upfront. In practice, 8 of them handle 90% of use cases. The rest could have been added as needed. Build for what you know, not what you imagine.
Document the "why" early. We documented the API but not the reasoning behind design decisions. Six weeks later, we couldn't remember why we chose certain spacing values. A short decision log would have saved hours.
Test dark mode from day one. We built the light theme first and added dark mode later. Every component needed adjustment. If we were starting over, dark mode would be the default and light the variant.
Need a design system for your product?
We build component libraries that scale with your product. Consistent, accessible, and built on modern CSS.