> ## Documentation Index
> Fetch the complete documentation index at: https://docs.9am.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Setup

> Authenticate against the private 9AM UI registry, scaffold a new script, or add the kit to an existing one.

## Get a token

The registry is private, so `shadcn` needs credentials.

<Steps>
  <Step title="Create a GitHub token">
    Create a personal access token with **read access to `ilovehugetits/9am-ui`**.
  </Step>

  <Step title="Export it">
    Add it to your shell profile so it survives a reboot.

    ```bash theme={null}
    export NINEAM_UI_TOKEN=github_pat_xxxxxxxx
    ```
  </Step>
</Steps>

<Warning>
  Never commit the token. `components.json` references it as `${NINEAM_UI_TOKEN}` and `shadcn` expands it at install time, so the file itself stays safe to check in.
</Warning>

## Point a script at the registry

Add a `registries` block to your script's `web/components.json`:

```json theme={null}
{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": false,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "src/index.css",
    "baseColor": "neutral",
    "cssVariables": true,
    "prefix": ""
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils",
    "ui": "@/components/ui",
    "lib": "@/lib",
    "hooks": "@/hooks"
  },
  "registries": {
    "@9am": {
      "url": "https://raw.githubusercontent.com/ilovehugetits/9am-ui/main/r/{name}.json",
      "headers": {
        "Authorization": "Bearer ${NINEAM_UI_TOKEN}"
      }
    }
  },
  "iconLibrary": "lucide"
}
```

Items are served straight off `raw.githubusercontent.com`, so there is nothing to host and no npm registry to authenticate against.

## Start a new script

<Steps>
  <Step title="Create the web project">
    ```bash theme={null}
    mkdir -p my-script/web && cd my-script/web
    bun init -y
    ```

    Then add the `components.json` shown above.
  </Step>

  <Step title="Install the scaffold">
    ```bash theme={null}
    bunx shadcn@latest add @9am/scaffold
    ```

    This writes `vite.config.ts`, `tsconfig.json`, `eslint.config.js`, `postcss.config.js`, `index.html`, `src/main.tsx`, and a starter `src/components/App.tsx` — and pulls in the theme, fonts, NUI bridge, i18n, viewport, and the icons the starter uses.
  </Step>

  <Step title="Add the Lua half">
    ```bash theme={null}
    cd .. && bun <path-to-9am-ui>/cli/index.ts lua
    ```

    Writes `fxmanifest.lua`, `client/nui.lua`, `shared/locale.lua`, and `locales/en.json` into the resource root. Existing files are skipped unless you pass `--force`.

    <Note>
      This step is not a registry item because `shadcn` rejects any install target containing `..`, and the Lua files belong one level above the web project.
    </Note>
  </Step>

  <Step title="Configure the script">
    Edit `web/src/nui.config.ts` — this is the one kit file you are meant to change.

    ```ts theme={null}
    export const nuiConfig = {
      resourceName: "my-script",
      themeStorageKey: "my-script:theme",
      defaultTheme: "dark",
    } as const;
    ```

    Keep the `localStorage` key in `index.html` in sync with `themeStorageKey`. It runs before first paint to stop the wrong theme flashing.
  </Step>

  <Step title="Build and verify">
    ```bash theme={null}
    bun install
    bun run build
    bun src/scripts/9am-ui.mjs doctor
    ```
  </Step>
</Steps>

## Add the kit to an existing script

Add the `registries` block, then take only what you want:

```bash theme={null}
bunx shadcn@latest add @9am/theme @9am/fonts
bunx shadcn@latest add @9am/viewport @9am/data-table
```

Dependencies resolve transitively. Asking for `@9am/data-table` also installs `button`, `input`, `table`, `i18n`, and its three icons — and nothing else, so a script that only wants a button does not pull in charts.

After adding the theme, import it from your entry stylesheet. Order matters:

```css theme={null}
@import "tailwindcss";
@import "tw-animate-css";

@import "./styles/9am-fonts.css";
@import "./styles/9am-theme.css";

/* your script's own styles go below */
```

## Where files land

| Item type                          | Destination              |
| ---------------------------------- | ------------------------ |
| Primitives and icons               | `src/components/ui/`     |
| `@9am/utils`, `@9am/smooth-scroll` | `src/lib/`               |
| `useNuiEvent`, `useTheme`          | `src/hooks/`             |
| `fetchNui`, `misc`, `debugData`    | `src/utils/`             |
| `VisibilityProvider`               | `src/providers/`         |
| `@9am/i18n`                        | `src/i18n/`              |
| `@9am/theme`, `@9am/fonts`         | `src/styles/`            |
| `@9am/nui` config                  | `src/nui.config.ts`      |
| `@9am/tools`                       | `src/scripts/9am-ui.mjs` |

## Recommended package scripts

```json theme={null}
{
  "scripts": {
    "start": "vite",
    "start:game": "vite build --watch",
    "build": "tsc && vite build",
    "production-build": "tsc && vite build --mode prod",
    "lint": "eslint src",
    "ui:check": "bun src/scripts/9am-ui.mjs check",
    "ui:doctor": "bun src/scripts/9am-ui.mjs doctor"
  }
}
```

| Command                    | Use it for                                                         |
| -------------------------- | ------------------------------------------------------------------ |
| `bun run start`            | Browser-only development with mock data. Fastest loop for UI work. |
| `bun run start:game`       | Rebuilds `dist` on save. Restart the resource to reload the NUI.   |
| `bun run build`            | Required before testing in-game — `web/dist` is gitignored.        |
| `bun run production-build` | Customer-ready build with dev seeds and console noise stripped.    |
