Library

React · Vite

Integrate Sitka into a Vite + React SPA. No framework dependencies — just CSS variables, Tailwind 4, and React components.

1

Create a Vite project

Skip this step if you already have a project.

bash
npm create vite@latest my-app -- --template react-ts
cd my-app
2

Install dependencies

bash
# Runtime
npm install clsx tailwind-merge framer-motion lucide-react @fontsource/inter

# Dev
npm install -D tailwindcss @tailwindcss/vite
3

Configure Vite + Tailwind 4

Tailwind 4 ships its own Vite plugin — no postcss.config needed:

vite.config.ts
ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import path from "path";

export default defineConfig({
  plugins: [react(), tailwindcss()],
  resolve: {
    alias: { "@": path.resolve(__dirname, "src") },
  },
});
4

Add CSS variables

Replace the contents of src/index.css with the Sitka token layer:

src/index.css
css
@import "tailwindcss";
@import "@fontsource/inter/variable.css";

:root {
  --background:      9   9  12;
  --surface:        13  13  17;
  --surface-raised: 22  22  28;
  --surface-hover:  32  32  40;

  --accent:         0 192 232;
  --accent-hover:   0 160 200;
  --accent-subtle:  0  38  46;
  --accent-muted:   0  72  86;

  --text-primary:   242 242 246;
  --text-secondary: 155 155 170;
  --text-tertiary:  100 100 115;

  --border:          38  38  48;
  --border-subtle:   26  26  33;

  --radius-sm: 4px;
  --radius:    6px;
  --radius-md: 10px;
  --radius-lg: 16px;
}

[data-theme="light"] {
  --background:      250 250 250;
  --surface:         255 255 255;
  --surface-raised:  246 246 248;
  --surface-hover:   240 240 244;
  --accent:          0 192 232;
  --accent-subtle:   224 247 252;
  --accent-muted:    179 237 249;
  --text-primary:    40  40  40;
  --text-secondary:  116 116 116;
  --text-tertiary:   167 167 172;
  --border:          224 224 231;
  --border-subtle:   240 240 244;
}

html, body {
  background-color: rgb(var(--background));
  color: rgb(var(--text-primary));
  font-family: "Inter Variable", Inter, system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.glass {
  background-color: rgb(var(--surface) / 0.92);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgb(var(--border));
}
5

Add the cn helper

src/lib/cn.ts
ts
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

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

Copy & use components

Copy any component files from src/components/ui/ into your project, then import normally:

src/App.tsx
tsx
import { Button } from "@/components/ui/Button";
import { Card }   from "@/components/ui/Card";
import { Badge }  from "@/components/ui/Badge";

function App() {
  return (
    <div className="min-h-screen p-8">
      <Card className="max-w-sm mx-auto p-6 flex flex-col gap-4">
        <Badge variant="info">Beta</Badge>
        <h1>Hello Sitka</h1>
        <Button variant="primary">Continue</Button>
      </Card>
    </div>
  );
}

export default App;

Differences vs. Next.js

  • All components work as-is — the "use client" directive at the top of each file is ignored by Vite and has no effect.
  • Replace any next/link imports with react-router-dom or your SPA router.
  • Replace next/image with a plain <img> tag.
  • The next/font Inter loader is replaced by the @fontsource/inter CSS import above.

Back to all libraries.