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:
| Class | What it does |
|---|---|
p-4 | Padding on all sides (1rem) |
px-4 | Horizontal padding |
py-2 | Vertical padding |
m-4 | Margin on all sides |
mt-2 | Top margin |
flex | Display flex |
gap-4 | Gap between flex/grid children |
w-full | Width 100% |
text-sm | Small text size |
bg-primary | Background using the primary color token |
rounded-lg | Rounded corners |
border | 1px 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:
- All component styles — everything needed for design system components to render correctly
- Theme tokens — CSS custom properties for colors, radii, and animations that components use
- 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
classNameprop
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-50through--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/postcss2. 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-animateThe 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
classNameprop - Resolve conflicting Tailwind classes (e.g.,
cn("p-4", "p-2")results in"p-2")
See the cn utility reference for details.
Summary
| Question | Answer |
|---|---|
| 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. |