# Installation (/ui/docs/react/installation)



Appica UI ships as a single tree-shakeable package. Components are built on
[Base UI](https://base-ui.com) primitives and styled with Tailwind CSS v4 design
tokens, so installation is two steps: add the package, then point Tailwind at it.

## Prerequisites [#prerequisites]

Appica UI targets modern React and Tailwind. Make sure your project has:

| Dependency   | Version  |
| ------------ | -------- |
| React        | `>= 19`  |
| React DOM    | `>= 19`  |
| Tailwind CSS | `>= 4.0` |

**React 19 is a hard requirement:** components use the modern ref-as-prop API and
other React 19 patterns, with no `forwardRef` shims. If you're on React 18,
upgrade before installing.

> **Warning - Tailwind v4 must be working first:**
>
> Appica UI doesn't bundle Tailwind - it relies on *your* project's Tailwind to compile the component styles. Before
> installing, set up Tailwind v4 in your app: install `tailwindcss` **and** its build plugin (`@tailwindcss/vite` for
> Vite, `@tailwindcss/postcss` for PostCSS/Next.js), then confirm that `@import 'tailwindcss';` in your global
> stylesheet generates utilities. If Tailwind isn't compiling your own classes yet, Appica UI's components will render
> unstyled.

## Install [#install]

```bash
pnpm add @appica/ui-react   # or: npm install @appica/ui-react / yarn add @appica/ui-react / bun add @appica/ui-react
```

## Configure Tailwind [#configure-tailwind]

Import the design tokens after Tailwind in your global stylesheet, and add a
`@source` directive so Tailwind scans the compiled library for class names.

```css title="globals.css"
@import 'tailwindcss';
@import '@appica/ui-react/styles.css';

@source '../node_modules/@appica/ui-react/dist';
```

> **Warning - Don't skip @source - and give it a real path:**
>
> Tailwind ignores `node_modules` by default. Without the `@source` directive it won't generate the utility
> classes used inside the compiled components, and they'll render unstyled.
>
> `@source` takes a path or glob **relative to the stylesheet that contains it**, not a bare package name -
> `@source '@appica/ui-react'` does not resolve and silently scans nothing. Count the `../` needed to reach
> `node_modules` from your CSS file: a stylesheet one level deep (`app/globals.css`, `src/index.css`) needs a
> single `../`; a deeper one (`src/styles/app.css`) needs `../../`. This matches Tailwind's own
> [`@source` documentation](https://tailwindcss.com/docs/functions-and-directives#source-directive), whose
> example is `@source '../node_modules/@my-company/ui-lib';`.

The `styles.css` import brings in the full token system - colors, radii, shadows,
typography, and the `light`/`dark` themes. See [Theming](/ui/docs/react/theming) to
customize it.

### Why source-scanning is the default [#why-source-scanning-is-the-default]

Appica UI ships its components' class names as source for *your* Tailwind to
compile, rather than defaulting to a prebuilt stylesheet you drop in. There's an
opt-in prebuilt file for projects that don't run Tailwind (see [Without
Tailwind](#without-tailwind) below), but wherever Tailwind is present the
`@source` path is the one to reach for. That extra line buys a lot:

* **One deduplicated build.** The utilities the components use are generated into
  the same pass as your own, so shared classes (`flex`, `rounded-lg`, `px-4`…)
  are emitted once instead of shipping twice.
* **Only what you use.** Tailwind tree-shakes across your app and the library
  together, folding the component utilities into your existing stylesheet instead
  of a second file, and unused component modules drop out with your bundler.
* **Your tokens win.** Because the classes are compiled against *your* Tailwind
  config, overrides to the design tokens in [Theming](/ui/docs/react/theming) - colors,
  radii, spacing, fonts - flow into the components automatically. The prebuilt
  file freezes the non-token utilities (spacing, layout) at publish time.
* **No version-locked CSS.** There's no compiled stylesheet to drift out of sync
  with your Tailwind version; the components restyle themselves against whatever
  Tailwind v4 you're on.

## Without Tailwind [#without-tailwind]

Appica UI is built on Tailwind, and the [source-scanning](#configure-tailwind)
setup above is the recommended path. If your project doesn't use Tailwind, skip
that step and import the **prebuilt stylesheet** instead. It's a single
self-contained file with every component's styles and the full token system
compiled in, so there's nothing to configure:

```css title="globals.css"
@import '@appica/ui-react/css';
```

No bundler? Link it straight from a CDN:

```html
<link rel="stylesheet" href="https://unpkg.com/@appica/ui-react/appica.css" />
```

Tailwind stays an *optional* peer dependency, so nothing installs it on your
behalf when you take this path.

> **Tip - Your tokens still override:**
>
> The prebuilt file keeps every design token as a CSS variable, so theming works exactly like
> [Theming](/ui/docs/react/theming) describes: redefine the variable after the import and every component
> follows, dark mode included.
>
> ```css
> :root {
>   --primary: oklch(60% 0.25 150);
> }
> ```

What you trade for the convenience, versus the Tailwind path:

* **It carries a baseline reset.** The file includes Tailwind's Preflight, which
  normalizes element styles (margins, headings, borders) across your whole page.
  That's what makes it self-contained, but it is global.
* **Only the token variables stay live.** Colors, fonts, radii, and shadows
  remain overridable through their CSS variables; the structural utilities
  (spacing, layout) are frozen at publish time, since there's no Tailwind config
  of yours for them to compile against.

> **Warning - Don't load both:**
>
> If you already run Tailwind, use [Configure Tailwind](#configure-tailwind) instead of this file.
> Importing the prebuilt stylesheet *and* scanning with `@source` ships the reset and utilities twice.

## Add the provider [#add-the-provider]

Wrap your app in `ThemeProvider` to enable theming and dark mode. It injects a
small inline script that applies the stored theme before first paint, so there's
no flash of the wrong theme. In Next.js that's the root layout's `<body>`; in a
Vite/CRA app, wrap your root the same way.

```tsx title="app/layout.tsx (Next.js)"
import { ThemeProvider } from '@appica/ui-react/providers/theme-provider'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        <ThemeProvider>{children}</ThemeProvider>
      </body>
    </html>
  )
}
```

That's all you need to start. See [Theme Provider](/ui/docs/react/theme-provider) for
the full API - custom themes, forcing a theme, and flash-prevention details - and
the optional [`DirectionProvider`](/ui/docs/react/direction-provider) (RTL) and
[`ReducedMotionProvider`](/ui/docs/react/reduced-motion-provider), which you add only
when you need them.

## Framework notes [#framework-notes]

Appica UI is a plain package, so the steps above are the same everywhere - unlike a
file-scaffolding CLI, there's no per-framework setup to learn. The only things that
move are which Tailwind build plugin you install, where your global stylesheet lives,
and where the provider goes:

| Framework                                                                                                   | Tailwind plugin        | Global stylesheet       | Wrap the provider            |
| ----------------------------------------------------------------------------------------------------------- | ---------------------- | ----------------------- | ---------------------------- |
| Next.js (App Router)  | `@tailwindcss/postcss` | `app/globals.css`       | root layout `<body>`         |
| Vite / CRA              | `@tailwindcss/vite`    | `src/index.css`         | root component in `main.tsx` |
| TanStack Start      | `@tailwindcss/vite`    | `src/styles/app.css`    | root route component         |
| React Router 7 / Remix | `@tailwindcss/vite`    | `app/app.css`           | root component in `root.tsx` |
| Astro                  | `@tailwindcss/vite`    | `src/styles/global.css` | see note below               |

Everything else (the `@import`s and the subpath imports) is identical regardless
of framework. The one value that tracks the stylesheet is the `@source` path: count
the `../` needed to reach `node_modules` from wherever your global CSS lives (see
[Configure Tailwind](#configure-tailwind) above).

> **Warning - Astro needs the React integration and an island:**
>
> Astro renders React as [islands](https://docs.astro.build/en/concepts/islands/), not a
> single tree, so it needs a little extra wiring. Add the `@astrojs/react` integration first,
> then mount anything interactive with a client directive (e.g. `client:load`) - components
> without one ship zero JS and won't react to theme changes. Because each island is its own
> React root, a `ThemeProvider` placed in an `.astro` layout **won't** share context across
> islands; either render an interactive section as one island wrapped in the provider, or apply
> the theme class in your `.astro` `<head>` and use the provider only inside hydrated islands.

## Use a component [#use-a-component]

Import components from their subpath for the smallest bundle, and you're ready:

```tsx
import { Button } from '@appica/ui-react/button'

export default function App() {
  return <Button>Get started</Button>
}
```

## Next steps [#next-steps]

* [Usage](/ui/docs/react/usage) - import conventions, variants, and composition basics.
* [Theming](/ui/docs/react/theming) - customize colors, radii, and tokens.
* [Dark Mode](/ui/docs/react/dark-mode) - build a theme toggle.
* [Components](/ui/components/react/button) - browse the full catalog.
