# Install in Vite

> Add @azmr/ui to a Vite React app with Tailwind CSS v4's Vite plugin, a first component and dark mode.

Source: https://platform.azmara.io/docs/guide/install-vite

This guide adds `@azmr/ui` to a React app built with Vite. It takes about five minutes. If you do not have an app yet, create one with `npm create vite@latest my-app -- --template react-ts`; everything below is what you add or change.

## 1. Install

```bash
pnpm add @azmr/ui @azmr/core
# or
npm install @azmr/ui @azmr/core
```

`react` and `react-dom` are already in your app. `@azmr/core` is a peer dependency, so install it yourself: see [Installation](https://platform.azmara.io/docs/guide/installation.md#the-four-steps).

## 2. Set up Tailwind CSS v4

Tailwind v4 has a Vite plugin. Install it (`pnpm add -D tailwindcss @tailwindcss/vite`) and add it to your Vite config:

`vite.config.ts`

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

export default defineConfig({
  plugins: [react(), tailwindcss()],
});
```

## 3. Import the stylesheet

In your global CSS, import Tailwind and then the package's stylesheet:

`src/index.css`

```css
@import "tailwindcss";
@import "@azmr/ui/styles.css";
```

Load it once, where your app starts. The entry file below also sets up dark mode, explained in [step 5](#5-add-dark-mode):

`src/main.tsx`

```tsx
import { ThemeProvider } from "@azmr/ui/react";
import {
  DENSITY_COOKIE,
  parseDensity,
  parseThemePreference,
  readCookie,
  THEME_COOKIE,
} from "@azmr/ui/theme";
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
import "./index.css";

// Read the choice saved by an earlier visit, so a reload keeps it.
const theme = parseThemePreference(readCookie(document.cookie, THEME_COOKIE));
const density = parseDensity(readCookie(document.cookie, DENSITY_COOKIE));

createRoot(document.getElementById("root") as HTMLElement).render(
  <StrictMode>
    <ThemeProvider defaultTheme={theme} defaultDensity={density}>
      <App />
    </ThemeProvider>
  </StrictMode>,
);
```

## 4. Use a component

`src/App.tsx`

```tsx
import { Button } from "@azmr/ui/button";
import { Input } from "@azmr/ui/input";
import { ThemeToggle } from "./theme-toggle";

export default function App() {
  return (
    <main className="mx-auto flex max-w-sm flex-col gap-3 p-6">
      <h1 className="text-2xl font-semibold">Hello</h1>
      <label htmlFor="name" className="text-sm font-medium">
        Your name
      </label>
      <Input id="name" placeholder="Aroha" />
      <Button>Say hello</Button>
      <ThemeToggle />
    </main>
  );
}
```

Run `pnpm dev` and open the page. You should see a heading, a labelled field and a button, styled with the design tokens.

## 5. Add dark mode

With no setup at all the page already follows the operating system. To let people choose, the entry file above wraps the app in `ThemeProvider`, which remembers a choice in a cookie. The entry file reads that cookie when the page starts, so a reload keeps the choice. A component changes it with `useTheme()`:

`src/theme-toggle.tsx`

```tsx
import { Button } from "@azmr/ui/button";
import { useTheme } from "@azmr/ui/react";

export function ThemeToggle() {
  const { resolvedTheme, setTheme } = useTheme();
  const next = resolvedTheme === "dark" ? "light" : "dark";
  return (
    <Button variant="outline" onClick={() => setTheme(next)}>
      Switch to {next} mode
    </Button>
  );
}
```

Density works the same way: `useTheme()` also returns `density` and `setDensity`, with the values `compact`, `comfortable` and `spacious`.

A page that is built in the browser can only apply the saved choice once its JavaScript has run, so someone who chose dark while their system is light may see a brief flash of the light theme first. If that matters, inline the `themeInitScript()` described in [Theming](https://platform.azmara.io/docs/guide/theming.md#remember-the-choice-without-a-flash).

## What was tested

The files above are the files of an app that CI builds. On every change it packs `@azmr/ui` into a tarball, installs it into that app, type-checks and builds it, and checks that:

- Tailwind found the package's classes inside `node_modules`, with nothing added to the config;
- the colour tokens are in the built stylesheet;
- the built bundle contains the app and the Button, and reads the saved theme cookie.

## Next steps

- [Theming](https://platform.azmara.io/docs/guide/theming.md): change the brand colour, density and dark mode.
- [Components](https://platform.azmara.io/docs/components.md): every component, with live demos.
- [Examples](https://platform.azmara.io/docs/examples.md): complete screens to copy.
- [Tailwind CSS setup](https://platform.azmara.io/docs/guide/tailwind.md): what the package needs from Tailwind.
