# 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.

<Callout type="warning" title="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.
</Callout>

## Install [#install]

<InstallTabs name="@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';
```

<Callout type="warning" title="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';`.
</Callout>

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 there's no prebuilt CSS to import [#why-theres-no-prebuilt-css-to-import]

Appica UI ships its components' class names as source for *your* Tailwind to
compile, rather than a prebuilt stylesheet you drop in. That extra `@source` 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 — utilities for components you never import are never generated.
* **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. A prebuilt
  stylesheet would freeze those values 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.

## 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            |
| ----------------------------------------------------------------------------------------------------------- | ---------------------- | ----------------------- | ---------------------------- |
| <span className="flex items-center text-nowrap"><FrameworkLogo name="nextjs" />Next.js (App Router)</span>  | `@tailwindcss/postcss` | `app/globals.css`       | root layout `<body>`         |
| <span className="flex items-center text-nowrap"><FrameworkLogo name="vite" />Vite / CRA</span>              | `@tailwindcss/vite`    | `src/index.css`         | root component in `main.tsx` |
| <span className="flex items-center text-nowrap"><FrameworkLogo name="tanstack" />TanStack Start</span>      | `@tailwindcss/vite`    | `src/styles/app.css`    | root route component         |
| <span className="flex items-center text-nowrap"><FrameworkLogo name="remix" />React Router 7 / Remix</span> | `@tailwindcss/vite`    | `app/app.css`           | root component in `root.tsx` |
| <span className="flex items-center text-nowrap"><FrameworkLogo name="astro" />Astro</span>                  | `@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).

<Callout type="warning" title="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.
</Callout>

## 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.
