Skip to main content
Ship uses Tailwind CSS 4 for utility-first styling and shadcn/ui (New York style, no RSC) for accessible, customizable UI components.

Tailwind CSS

All styling is done with Tailwind utility classes. No CSS modules, no styled-components.
  • Mobile-first: Use sm:, md:, lg: breakpoints.
  • Dark mode: Use semantic CSS variables (text-foreground, bg-background, text-muted-foreground, border, etc.).
  • Theming: next-themes (system/light/dark). Use CSS variables, not hardcoded colors.

Conditional Classes with cn()

Use cn() from @/lib/utils for conditional class merging:
import { cn } from '@/lib/utils';

<div className={cn('p-4 rounded-lg', isActive && 'bg-primary text-primary-foreground')} />

shadcn/ui Components

UI primitives live in src/components/ui/. Add new components via:
npx shadcn@latest add <component>
Import them with the @/ alias:
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
Don’t modify shadcn/ui files unless necessary. Wrap them instead with custom components.

Icons

Use lucide-react for icons:
import { Plus, Trash, Pencil } from 'lucide-react';

<Button><Plus className="mr-2 h-4 w-4" /> Add Item</Button>

Component Organization

LocationScopeImport pattern
src/components/ui/shadcn/ui primitives@/components/ui/button
src/components/Shared components'components' (barrel)
pages/<name>/components/Page-scopedRelative import within page