1. Docs
  2. Installation
  3. Manual Installation

Manual Installation

Add dependencies to your project manually.

Add Tailwind CSS

Components are styled using Tailwind CSS. You need to install Tailwind CSS in your project.

Follow the Tailwind CSS installation instructions to get started.

Add dependencies

Add the following dependencies to your project:

Terminal
npm install cva@beta tailwind-merge tailwindcss-motion tailwindcss-react-aria-components -D

Configure path aliases

I use the ~ alias. This is how I configure it in tsconfig.json:

tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".", 
    "paths": {
      "~/*": ["./src/*"]
    } 
  }
}

The ~ alias is a preference. You can use other aliases if you want, like @ or #.

If you use a different alias such as @, you'll need to update import statements when adding components.

Configure styles

Add the following to your styles/globals.css file. You can learn more about using CSS variables for theming in the theming section.

globals.css
@import "tailwindcss";

@plugin "tailwindcss-react-aria-components";
@plugin "tailwindcss-motion";

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

@theme inline {
    --radius: 0.625rem;
    --radius-sm: calc(var(--radius) - 4px);
    --radius-md: calc(var(--radius) - 2px);
    --radius-lg: var(--radius);
    --radius-xl: calc(var(--radius) + 4px);
    --color-background: light-dark(oklch(1 0 0), oklch(0.145 0 0));
    --color-foreground: light-dark(oklch(0.145 0 0), oklch(0.985 0 0));
    --color-card: light-dark(oklch(1 0 0), oklch(0.205 0 0));
    --color-card-foreground: light-dark(oklch(0.145 0 0), oklch(0.985 0 0));
    --color-popover: light-dark(oklch(1 0 0), oklch(0.205 0 0));
    --color-popover-foreground: light-dark(oklch(0.145 0 0), oklch(0.985 0 0));
    --color-primary: light-dark(oklch(0.205 0 0), oklch(0.922 0 0));
    --color-primary-foreground: light-dark(oklch(0.985 0 0), oklch(0.205 0 0));
    --color-secondary: light-dark(oklch(0.97 0 0), oklch(0.269 0 0));
    --color-secondary-foreground: light-dark(oklch(0.205 0 0), oklch(0.985 0 0));
    --color-muted: light-dark(oklch(0.97 0 0), oklch(0.269 0 0));
    --color-muted-foreground: light-dark(oklch(0.556 0 0), oklch(0.708 0 0));
    --color-accent: light-dark(oklch(0.97 0 0), oklch(0.269 0 0));
    --color-accent-foreground: light-dark(oklch(0.205 0 0), oklch(0.985 0 0));
    --color-destructive: light-dark(oklch(0.577 0.245 27.325), oklch(0.704 0.191 22.216));
    --color-border: light-dark(oklch(0.922 0 0), oklch(1 0 0 / 10%));
    --color-input: light-dark(oklch(0.922 0 0), oklch(1 0 0 / 15%));
    --color-ring: light-dark(oklch(0.708 0 0), oklch(0.556 0 0));
    --color-chart-1: light-dark(oklch(0.646 0.222 41.116), oklch(0.488 0.243 264.376));
    --color-chart-2: light-dark(oklch(0.6 0.118 184.704), oklch(0.696 0.17 162.48));
    --color-chart-3: light-dark(oklch(0.398 0.07 227.392), oklch(0.769 0.188 70.08));
    --color-chart-4: light-dark(oklch(0.828 0.189 84.429), oklch(0.627 0.265 303.9));
    --color-chart-5: light-dark(oklch(0.769 0.188 70.08), oklch(0.645 0.246 16.439));
    --color-sidebar: light-dark(oklch(0.985 0 0), oklch(0.205 0 0));
    --color-sidebar-foreground: light-dark(oklch(0.145 0 0), oklch(0.985 0 0));
    --color-sidebar-primary: light-dark(oklch(0.205 0 0), oklch(0.488 0.243 264.376));
    --color-sidebar-primary-foreground: light-dark(oklch(0.985 0 0), oklch(0.985 0 0));
    --color-sidebar-accent: light-dark(oklch(0.97 0 0), oklch(0.269 0 0));
    --color-sidebar-accent-foreground: light-dark(oklch(0.205 0 0), oklch(0.985 0 0));
    --color-sidebar-border: light-dark(oklch(0.922 0 0), oklch(1 0 0 / 10%));
    --color-sidebar-ring: light-dark(oklch(0.708 0 0), oklch(0.556 0 0));
}

@utility container {
    padding-inline: 2rem;
    margin-inline: auto;
}

@layer base {
    * {
        @apply border-border outline-ring/50;
    }

    html {
        scroll-behavior: smooth;

        scrollbar-color: var(--color-border) transparent;
        scrollbar-width: thin;

        &.light {
            color-scheme: light;
        }

        &.dark {
            color-scheme: dark;
        }
    }

    body {
        font-synthesis-weight: none;
        text-rendering: optimizeLegibility;

        @apply bg-background text-foreground antialiased font-sans;
    }

    input:-webkit-autofill {
        background-clip: text;
    }
}

Configure Class Variance Authority

Class Variance Authority (a.k.a. CVA) is a utility that helps you manage class variance in your project. Here's how I define it in lib/cva.ts:

lib/cva.ts
import { defineConfig } from "cva";
import { twMerge } from "tailwind-merge";

export const {
  cva,
  cx: cn,
  compose,
} = defineConfig({
  hooks: {
    onComplete: (className) => twMerge(className),
  },
});

That's it ✨

You can now start adding components to your project.