---
name: setup-vui
description: >
  Set up @veracity/vui in a React application. Use when installing VUI, wrapping
  an app with VuiProvider, configuring reset/global styles, extending the theme,
  using VUI 5 CSS variables, loading Veracity platform links, or wiring
  toast/offline support.
sources:
  - 'WEB-VUI:apps/docs/stories/guides/overview/GettingStarted.mdx'
  - 'WEB-VUI:apps/docs/stories/guides/foundations/VuiProvider.mdx'
  - 'WEB-VUI:apps/docs/stories/guides/foundations/Theme.mdx'
  - 'WEB-VUI:apps/docs/stories/guides/foundations/DesignTokens.mdx'
  - 'WEB-VUI:apps/docs/stories/guides/foundations/Links.mdx'
  - 'WEB-VUI:apps/docs/static/llms/components/toast.md'
metadata:
  type: lifecycle
  library: '@veracity/vui'
  library_version: '5.2.3'
---

# Set Up VUI

Use `@veracity/vui` from the package root. Avoid deep imports from `dist`.

## Install

Install VUI in a React 18 or React 19 app:

```bash
npm install @veracity/vui
```

`@veracity/vui@5.1.1` declares these peer dependencies:

- `react`: `^18.0.0 || ^19.0.0`
- `react-dom`: `^18.0.0 || ^19.0.0`

Do not install React 17 for new VUI projects. The repository's Vite + React + TypeScript example uses React 19, Vite 8, and TypeScript 6. Fresh Vite projects on React 18 or 19 are supported as long as the peer dependency range is satisfied.

## Vite + React + TypeScript Bootstrap

For a new Vite app:

```bash
npm create vite@latest my-vui-app -- --template react-ts
cd my-vui-app
npm install
npm install @veracity/vui
```

Configure `src/main.tsx`:

```tsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { VuiProvider } from '@veracity/vui'

import App from './App'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <VuiProvider>
      <App />
    </VuiProvider>
  </StrictMode>,
)
```

Start with a block-like VUI surface in `src/App.tsx`:

```tsx
import { Box, Button, Card, Heading, P } from '@veracity/vui'

export default function App() {
  return (
    <Box column minH="100vh" p={4} gap={4} bg="var(--vui-background-default)">
      <Card column p={4} gap={3}>
        <Heading level={1}>VUI app</Heading>
        <P>VUI is ready.</P>
        <Button variant="primary" intent="brand">
          Continue
        </Button>
      </Card>
    </Box>
  )
}
```

## Provider Setup

Wrap the application with `VuiProvider` before rendering VUI components:

```tsx
import { Button, VuiProvider } from '@veracity/vui'

export function App() {
  return (
    <VuiProvider>
      <Button variant="primary" intent="brand">
        Continue
      </Button>
    </VuiProvider>
  )
}
```

`VuiProvider` provides the VUI theme, injects global design-token CSS variables, includes reset/global styles by default, and renders the internal toast stack.

Disable reset or global body styling only when the host application already owns those concerns:

```tsx
<VuiProvider resetCSS={false} globalStyle={false}>
  <AppRoutes />
</VuiProvider>
```

## Theme Overrides

Use `extendTheme` for theme overrides, then pass the theme to `VuiProvider`:

```tsx
import { extendTheme, VuiProvider } from '@veracity/vui'

const overrides = {
  fontSizes: {
    md: '14px',
  },
}

type Overrides = typeof overrides

declare module '@veracity/vui' {
  interface VuiThemeExtensions extends Overrides {}
}

const theme = extendTheme(overrides)

export function App() {
  return <VuiProvider theme={theme}>...</VuiProvider>
}
```

Prefer small theme extensions over ad hoc component overrides. Keep the module augmentation next to the override object so TypeScript sees custom keys.

## CSS Variables

VUI 5 injects `--vui-*` custom properties through `VuiProvider`. Prefer semantic tokens in application CSS:

```css
.panel {
  background: var(--vui-background-default);
  color: var(--vui-foreground-default);
  border: 1px solid var(--vui-utility-border-default);
}
```

Use semantic tokens such as `--vui-background-*`, `--vui-foreground-*`, `--vui-action-*`, and `--vui-feedback-*` first. Use primitive `--vui-color-{family}-{shade}` values only when no semantic token fits.

## Toasts

Use `useToast()` inside components wrapped by `VuiProvider`:

```tsx
import { Button, useToast } from '@veracity/vui'

export function SaveButton() {
  const { showSuccess, showError } = useToast()

  async function save() {
    try {
      await saveChanges()
      showSuccess('Changes saved.')
    } catch {
      showError('Could not save changes.')
    }
  }

  return <Button onClick={save}>Save</Button>
}
```

Do not render `<Toaster>` manually. `VuiProvider` already renders it. Use `duration: 'sticky'` only with a later `hideToast(id)` call.

## Offline Notifications

Use `notifyOffline` when the app should notify users about online/offline state:

```tsx
import { VuiProvider } from '@veracity/vui'

export function Root() {
  return (
    <VuiProvider notifyOffline>
      <AppRoutes />
    </VuiProvider>
  )
}
```

Use `useOfflineMode()` when the app also needs to read the offline state in UI logic.

## Veracity Platform Links

Use `LinksProvider` only when components need Veracity CDN link dictionaries for environments such as Test, Stag, or Prod:

```tsx
import { LinksProvider, useLoadLinks } from '@veracity/vui'

function Root() {
  return (
    <LinksProvider>
      <App />
    </LinksProvider>
  )
}

function App() {
  const env = resolveVeracityEnvironment()
  const isLoggedIn = getUserIsLoggedIn()

  useLoadLinks(env, isLoggedIn)

  return <AppRoutes />
}
```

Read loaded links through `useLinks()`:

```tsx
import { Link, useLinks } from '@veracity/vui'

function MarketplaceLink() {
  const [links] = useLinks()

  return <Link href={links.marketplace}>Go to Marketplace</Link>
}
```

## Common Mistakes

### HIGH Missing VuiProvider

Wrong:

```tsx
import { Button } from '@veracity/vui'

export function App() {
  return <Button>Save</Button>
}
```

Correct:

```tsx
import { Button, VuiProvider } from '@veracity/vui'

export function App() {
  return (
    <VuiProvider>
      <Button>Save</Button>
    </VuiProvider>
  )
}
```

Without `VuiProvider`, VUI components miss theme context, global CSS variables, and toast context.

### MEDIUM Rendering Toaster Manually

Wrong:

```tsx
import { Toaster, VuiProvider } from '@veracity/vui'

export function App() {
  return (
    <VuiProvider>
      <Toaster />
      <AppRoutes />
    </VuiProvider>
  )
}
```

Correct:

```tsx
import { VuiProvider } from '@veracity/vui'

export function App() {
  return (
    <VuiProvider>
      <AppRoutes />
    </VuiProvider>
  )
}
```

`VuiProvider` already includes the toast renderer.

### MEDIUM Using Primitive Tokens By Default

Wrong:

```css
.message {
  color: var(--vui-color-sea-blue-28);
}
```

Correct:

```css
.message {
  color: var(--vui-foreground-brand-primary);
}
```

Semantic tokens encode intent and survive design-token changes better than raw palette values.
