LOKE Design System
Guides

Tailwind CSS

How Tailwind CSS relates to the LOKE Design System — what's included, what's optional, and when you might want your own setup.

Tailwind CSS

The LOKE Design System is built with Tailwind CSS internally, but you do not need to install Tailwind to use the design system. All styles are pre-compiled and shipped as standard CSS.

This guide explains the relationship between Tailwind and the design system, and when you might want to set up Tailwind in your own project.


Do I need Tailwind?

No. The design system works without Tailwind installed in your project. When you import the stylesheet:

import "@loke/design-system/styles";

You get pre-compiled CSS that includes all component styles, color tokens, and a set of common utility classes. No build tools, PostCSS plugins, or Tailwind configuration needed.

The design system is plug-and-play. Install it, import the styles, and start using components. Tailwind is an implementation detail — not a requirement.


What is Tailwind CSS?

If you've never used Tailwind before, here's the short version: Tailwind is a CSS framework that provides small, single-purpose CSS classes you apply directly in your HTML/JSX. Instead of writing CSS in a separate file, you compose styles using class names.

// Traditional CSS approach
<div className="card">Content</div>
// .card { padding: 1rem; background: white; border-radius: 0.5rem; }

// Tailwind approach
<div className="p-4 bg-white rounded-lg">Content</div>

Each class does one thing: p-4 sets padding, bg-white sets background color, rounded-lg sets border radius. You combine them to build up your styles.

Common patterns you'll see in examples:

ClassWhat it does
p-4Padding on all sides (1rem)
px-4Horizontal padding
py-2Vertical padding
m-4Margin on all sides
mt-2Top margin
flexDisplay flex
gap-4Gap between flex/grid children
w-fullWidth 100%
text-smSmall text size
bg-primaryBackground using the primary color token
rounded-lgRounded corners
border1px border

For a full reference, see the Tailwind CSS documentation.


What ships with the design system

The pre-compiled stylesheet (@loke/design-system/styles) includes:

  1. All component styles — everything needed for design system components to render correctly
  2. Theme tokens — CSS custom properties for colors, radii, and animations that components use
  3. Common utility classes — a subset of Tailwind utilities pre-compiled for convenience

The included utilities cover the most common layout and styling needs: spacing (p-*, m-*, gap-*), flexbox (flex, items-center, justify-between), sizing (w-full, h-*), grid (grid, grid-cols-*), positioning, borders, shadows, typography, and more.

This means you can use Tailwind-style classes in your own components without installing Tailwind:

import { Button } from "@loke/design-system/button";

export function Header() {
  return (
    <header className="flex items-center justify-between p-4 border-b">
      <h1 className="text-lg font-semibold">My App</h1>
      <Button>Sign in</Button>
    </header>
  );
}

The pre-compiled stylesheet includes utilities that the design system itself uses, plus a broad set of common classes. If you use a Tailwind class that isn't included, it simply won't have any effect. If you find yourself needing classes that aren't available, consider setting up Tailwind in your project.


Layout components vs. Tailwind classes

The design system includes layout components like Box, Stack, Columns, and Inline. These provide a props-based API for common layout patterns. If you're comfortable with Tailwind, you can achieve the same results with utility classes directly.

Here's how they compare:

Vertical stack

// Using the Stack component
import { Stack } from "@loke/design-system/stack";

<Stack gap={4}>
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</Stack>

// Equivalent Tailwind classes
<div className="flex flex-col gap-4">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</div>

Horizontal row

// Using the Inline component
import { Inline } from "@loke/design-system/inline";

<Inline gap={2} alignItems="center">
  <span>Label</span>
  <Badge>New</Badge>
</Inline>

// Equivalent Tailwind classes
<div className="inline-flex gap-2 items-center">
  <span>Label</span>
  <Badge>New</Badge>
</div>

Grid columns

// Using the Columns component
import { Columns } from "@loke/design-system/columns";

<Columns columns={3} gap={4}>
  <Card>One</Card>
  <Card>Two</Card>
  <Card>Three</Card>
</Columns>

// Equivalent Tailwind classes
<div className="grid grid-cols-3 gap-4">
  <Card>One</Card>
  <Card>Two</Card>
  <Card>Three</Card>
</div>

Spacing and backgrounds

// Using the Box component
import { Box } from "@loke/design-system/box";

<Box padding={4} background="card" borderRadius="md" border>
  Content
</Box>

// Equivalent Tailwind classes
<div className="p-4 bg-card rounded-md border">
  Content
</div>

Responsive layout

The layout components support responsive values via arrays, where each value maps to a breakpoint ([mobile, sm, md, lg]):

// Using Box with responsive props
<Box padding={[2, 4, 6]} display={["block", "flex"]}>
  Content
</Box>

// Equivalent Tailwind classes
<div className="p-2 sm:p-4 md:p-6 block sm:flex">
  Content
</div>

Which should I use?

Use whichever you prefer — both approaches are valid. Here are some considerations:

  • Layout components are useful if you're not familiar with CSS/Tailwind, or if you want a more React-like API with type-checked props
  • Tailwind classes give you more flexibility and are the standard approach if you're already comfortable with CSS
  • Mix and match — you can use layout components for structure and Tailwind classes for fine-tuning, or vice versa. All components accept a className prop

Using color tokens

The design system defines semantic color tokens as CSS custom properties. These are available as Tailwind color classes whether or not you have Tailwind installed in your project:

// Background colors
<div className="bg-primary">Primary background</div>
<div className="bg-secondary">Secondary background</div>
<div className="bg-card">Card background</div>
<div className="bg-muted">Muted background</div>
<div className="bg-destructive">Destructive background</div>

// Text colors
<div className="text-foreground">Default text</div>
<div className="text-muted-foreground">Secondary text</div>
<div className="text-primary">Accent text</div>

// Border colors
<div className="border border-border">Default border</div>
<div className="border border-primary">Primary border</div>

These tokens automatically adapt for dark mode when the dark class is on the <html> element. See the Color System page for the full palette.


CSS custom properties

You can also use the design system's tokens directly in your own CSS via custom properties:

.my-custom-element {
  background: var(--card);
  color: var(--card-foreground);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

Available tokens include:

  • --background / --foreground
  • --card / --card-foreground
  • --primary / --primary-foreground
  • --secondary / --secondary-foreground
  • --muted / --muted-foreground
  • --accent / --accent-foreground
  • --destructive / --destructive-foreground
  • --border, --input, --ring
  • --radius
  • --brand-50 through --brand-950

Setting up Tailwind in your project

If you need Tailwind utilities beyond what ships with the design system — for example, arbitrary values, additional responsive breakpoints, or classes that aren't pre-compiled — you can install Tailwind in your project.

1. Install Tailwind CSS

bun add -d tailwindcss @tailwindcss/postcss

2. Configure PostCSS

Create or update postcss.config.mjs:

const config = {
  plugins: {
    "@tailwindcss/postcss": {},
  },
};
export default config;

3. Set up your stylesheet

Replace the import "@loke/design-system/styles" import in your entry point with a custom CSS file that imports Tailwind and the design system's theme:

/* globals.css */
@import "tailwindcss";
@import "@loke/design-system/styles/tailwind";

@plugin "tailwindcss-animate";

/* Scan the design system source so its classes are included */
@source "node_modules/@loke/design-system/dist";

@custom-variant dark (&:is(.dark *));

@layer base {
  * {
    @apply border-border outline-ring/50;
  }
  body {
    @apply bg-background text-foreground;
  }
}

Then import this file in your app entry instead:

// app/layout.tsx
import "./globals.css";

The @loke/design-system/styles/tailwind import provides the theme configuration (color tokens, radii, animations) without the pre-compiled utilities. Tailwind will generate the utility classes itself based on what your code uses.

4. Install the animate plugin

If you use components that animate (like Accordion), install the animation plugin:

bun add -d tailwindcss-animate

The cn utility

The design system exports a cn utility for merging class names. It combines clsx (conditional classes) with tailwind-merge (conflict resolution):

import { cn } from "@loke/design-system/cn";

function MyComponent({ className, isActive }: { className?: string; isActive: boolean }) {
  return (
    <div className={cn(
      "p-4 rounded-lg border",
      isActive && "bg-primary text-primary-foreground",
      className
    )}>
      Content
    </div>
  );
}

cn is useful when you want to:

  • Conditionally apply classes
  • Let consumers override styles via a className prop
  • Resolve conflicting Tailwind classes (e.g., cn("p-4", "p-2") results in "p-2")

See the cn utility reference for details.


Summary

QuestionAnswer
Do I need to install Tailwind?No. The design system ships pre-compiled CSS.
Can I use Tailwind classes?Yes. Common utility classes are included in the pre-compiled stylesheet.
Can I use layout components instead of Tailwind?Yes. Box, Stack, Columns, and Inline provide equivalent functionality with a props API.
When should I install Tailwind myself?When you need utilities beyond what's pre-compiled, or want full Tailwind in your project.
Do the color tokens work without Tailwind?Yes. They're standard CSS custom properties.