Styling and Design System

Create consistent UI patterns while keeping implementation speed high.

Use Tailwind CSS as the default styling layer and shadcn/ui as the default component system.

Component policy:

  • Build product UI from shadcn/ui components first.
  • Use Base UI (preferred) or Radix UI as under the hood primitives for shadcn components.
  • Keep styling in Tailwind and shared tokens.

Utility helper (cn)

import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}

Design system structure

  • components/ui/* for shadcn/ui-based reusable components.
  • components/* for app-level composed components.
  • Tokens in a single shared theme layer (colors, spacing, typography, radius, shadows).
  • One cn() helper for class composition consistency.

Implementation checklist

  • Define tokens for color, spacing, typography, and radius.
  • Keep shadcn/ui components close to upstream conventions unless there is a clear product need.
  • Build a small internal set of approved wrappers (button, input, dialog, table).

Common pitfalls

  • Introducing mixed styling patterns outside Tailwind.
  • Using arbitary sizes and colors instead of tokens or tailwind provided colors.

On this page