Installation

Vite

Add Vamos UI to a Vite + React + TypeScript single-page app.

Requirements: React 19, Tailwind CSS v4, Node 20 or newer.

Steps

  1. Create the app
    pnpm create vite@latest my-panel --template react-ts
    cd my-panel && pnpm install
  2. Add Tailwind v4
    pnpm add -D tailwindcss @tailwindcss/vite
    vite.config.ts
    // vite.config.ts
    import { defineConfig } from "vite";
    import react from "@vitejs/plugin-react";
    import tailwindcss from "@tailwindcss/vite";
    
    export default defineConfig({
      plugins: [react(), tailwindcss()],
    });
  3. Install the kit
    pnpm add @vamos-ui/react
  4. Import the styles

    Replace the template's src/index.css with the two imports, then add the font variables:

    src/index.css
    @import "tailwindcss";
    @import "@vamos-ui/react/styles.css";
    
    /* The data-font="editorial" preset reads these variables. */
    :root {
      --ff-onest: "Onest";
      --ff-instrument: "Instrument Serif";
      --ff-jetbrains: "JetBrains Mono";
    }

    Delete src/App.css and its import; its global rules fight the tokens.

    No @source line needed
    Importing @vamos-ui/react/styles.css after tailwindcss is enough: Tailwind v4 also scans the package the stylesheet comes from, so the classes used inside the components are generated.
  5. Theme attributes, boot script and fonts in index.html

    The six axes are attributes on <html> (or any element): class="dark", data-material="glass|solid", data-accent="lime|ocean|ember|rose|graphite", data-density="comfortable|compact", data-font="editorial|grotesk|corporate|system" and, optionally, data-radius="sharp|round" for corners. The boot script reads the user's saved choice from localStorage (key vamos-theme) before the first paint. See Theming for every token.

    index.html
    <!doctype html>
    <html lang="en" data-material="glass" data-accent="lime" data-density="comfortable" data-font="editorial">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>My panel</title>
        <!-- Restore the saved theme axes before the first paint. -->
        <script>try{var s=JSON.parse(localStorage.getItem("vamos-theme")||"{}");var h=document.documentElement;if(s.dark)h.classList.add("dark");h.dataset.material=s.material||"glass";h.dataset.accent=s.accent||"lime";h.dataset.density=s.density||"comfortable";h.dataset.font=s.font||"editorial"}catch(e){}</script>
        <!-- Fonts of the editorial preset -->
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Onest:wght@100..900&family=Instrument+Serif:ital@0;1&family=JetBrains+Mono:wght@100..800&display=swap" />
      </head>
      <body class="min-h-dvh font-sans">
        <div id="root"></div>
        <script type="module" src="/src/main.tsx"></script>
      </body>
    </html>
  6. Providers

    VamosProvider sets the locale (strings, numbers, dates) and is where you hand in your router's link later. TooltipProvider turns icon-button titles into real tooltips.

    src/main.tsx
    // src/main.tsx
    import { StrictMode } from "react";
    import { createRoot } from "react-dom/client";
    import { TooltipProvider, VamosProvider } from "@vamos-ui/react";
    import "./index.css";
    import App from "./App";
    
    createRoot(document.getElementById("root")!).render(
      <StrictMode>
        <VamosProvider locale="en-US">
          <TooltipProvider>
            <App />
          </TooltipProvider>
        </VamosProvider>
      </StrictMode>,
    );
  7. Use a component
    // src/App.tsx
    import { Badge, Button, Card, CardBody, CardHeader } from "@vamos-ui/react";
    
    export default function Welcome() {
      return (
        <main className="mx-auto grid max-w-xl gap-4 p-8">
          <Card>
            <CardHeader
              title="Spring campaign"
              description="Newsletter · 12,480 recipients"
              action={<Badge tone="success" dot>Scheduled</Badge>}
            />
            <CardBody className="flex gap-2">
              <Button variant="primary">Publish</Button>
              <Button>Preview</Button>
            </CardBody>
          </Card>
        </main>
      );
    }
    pnpm dev

Self-hosted fonts

To avoid the Google Fonts request, install the families with Fontsource and point the --ff-* variables at their family names:

pnpm add @fontsource-variable/onest @fontsource/instrument-serif @fontsource-variable/jetbrains-mono
/* src/main.tsx */
import "@fontsource-variable/onest";
import "@fontsource/instrument-serif";
import "@fontsource/instrument-serif/400-italic.css";
import "@fontsource-variable/jetbrains-mono";

/* src/index.css: the variable fonts register "… Variable" family names */
:root {
  --ff-onest: "Onest Variable";
  --ff-instrument: "Instrument Serif";
  --ff-jetbrains: "JetBrains Mono Variable";
}
Using a router?
With React Router in data or declarative mode, pass a link adapter to VamosProvider as shown in React Router, so kit links navigate without a full page load.

With the CLI instead

Prefer owning the source? Instead of the npm package, let the CLI copy the kit into your project. It detects the framework, Tailwind v4 and your package manager, writes vamos.json, adds the stylesheet import to src/index.css and prints the <html> attributes:

npx vamos-ui init
npx vamos-ui add button card badge

Components land in components/vamos (or src/components/vamos) and are imported from your alias, for example @/components/vamos. Every written file is recorded in .vamos-lock.json, so npx vamos-ui diff and upgrade keep your edits apart from kit updates.