# @cuesheet/vite

> Vite plugin for cuesheet — handler auto-registration with HMR, dev-only injection, and typed scenarios.

Latest version **1.0.1** (published 2026-09-28) · MIT license · 0 weekly downloads

## Install

```sh
npm install @cuesheet/vite
pnpm add @cuesheet/vite
yarn add @cuesheet/vite
bun add @cuesheet/vite
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.1 |
| Published | 2026-09-28 |
| First published | 2026-09-27 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 45.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | GUMBOKIM (https://github.com/GUMBOKIM) |
| Maintainers | gumbokim |
| Keywords | cuesheet, msw, mock, vite, vite-plugin, hmr, devtools |

## Links

- npm: https://www.npmjs.com/package/@cuesheet/vite
- Repository: https://github.com/GUMBOKIM/cuesheet
- Homepage: https://github.com/GUMBOKIM/cuesheet#readme
- Issues: https://github.com/GUMBOKIM/cuesheet/issues
- npm.io page: https://npm.io/package/@cuesheet/vite

## Alternatives

- [pagerjs](https://npm.io/package/pagerjs.md) — 60 weekly downloads
- [whistle.savefor-mock](https://npm.io/package/whistle.savefor-mock.md) — 4 weekly downloads
- [@crvouga/mockingbird-service-fcm](https://npm.io/package/@crvouga/mockingbird-service-fcm.md) — 0 weekly downloads
- [jabber](https://npm.io/package/jabber.md) — 0 weekly downloads
- [@simulacrum/ldap-simulator](https://npm.io/package/@simulacrum/ldap-simulator.md) — 0 weekly downloads

## Recent versions

- 1.0.1 (latest) — 2026-09-28
- 1.0.0 — 2026-09-27

## README

# @cuesheet/vite

Vite plugin for [cuesheet](https://www.npmjs.com/package/cuesheet). It injects cuesheet into dev builds
only, registers your handler files with HMR, and generates types for your scenario names.

## Install

```bash
npm install -D cuesheet @cuesheet/vite msw
```

## Usage

```ts
// vite.config.ts
import { cuesheet } from '@cuesheet/vite'

export default defineConfig({
  plugins: [cuesheet()],
})
```

```ts
// src/mocks/cuesheet.ts — the runtime options, picked up by name
import { defineCuesheet } from 'cuesheet'

export default defineCuesheet({ baseUrl: 'https://api.example.com' })
```

```ts
// app — undefined in disabled builds
import { cuesheet } from 'virtual:cuesheet'
```

## What it does

- **Injects into dev builds only.** By default it is enabled only on the dev server and injected at the
  very top of `index.html`. It runs before the app, so the first request and time conditions are never
  missed. `vite build` output contains no cuesheet code.
- **Stays off under Vitest and `--mode test` by default.** Even if you run unit tests with the same
  `vite.config.ts`, cuesheet won't answer in place of your tests' msw handlers.
- **Guards against leaks.** If `cuesheet`, `@cuesheet/react` or a file from the handler folder ends up in
  a disabled build, the build fails and reports the file that imported it (`Disabled build: cuesheet ended
  up in ...`). It catches static and dynamic imports, as well as bare import statements left behind by
  `external`. Handler files count because they carry your mock responses, even when one imports `http`
  straight from `msw` and so mentions nothing of cuesheet.
- **Registers handlers automatically, with HMR.** Collects the files in the handler folder; edits and
  new files apply without a reload. If a scenario that was selected disappears, the selection is cleared
  and falls back to the first entry.
- **Pre-bundles `cuesheet` and `msw` on the dev server.** They reach the browser through the injected
  script rather than app code, so without this Vite discovers them mid-session and reloads the page —
  which drops the `?cue=` link the page was opened with.
  Turn it off with `optimizeDeps: false` if your app pre-bundles its own way. If you work on a **linked**
  copy of cuesheet (`npm link`, a workspace), add `optimizeDeps: { force: true }` to your Vite config:
  that cache is keyed on the lockfile, so edits to a linked package otherwise sit behind it.
- **Generates scenario types.** Generates a `.d.ts` that fills `CueRegistry` with handler ids and
  scenario names. Typos like `select('getCoupons', 'Emtpy')` and calls with mismatched id/scenario pairs
  are caught by the type checker.

## Good to know

- **The type file is generated by executing handler files on the dev server (Node).** If a handler file
  touches `window` or `localStorage` at the top level, the type file won't update (a warning is shown).
  This is also why editing a mock file prints an `(ssr) page reload …` log in the terminal even though
  the browser doesn't reload.
- **The type file only updates while the dev server is running.** Commit it and CI can type-check too.
- **An invalid handler definition doesn't stop the app.** If a handler definition is invalid (duplicate
  id, etc.), the app starts without cuesheet, and the error is shown in the console and the Vite error
  overlay.

## Options

| Option | Default | Description |
|---|---|---|
| `handlers` | `'src/mocks/handlers'` | Handler folder (relative to the project root) |
| `include` | `'**/*.mock.{ts,tsx,js,jsx}'` | Files in the folder treated as handlers |
| `setup` | `src/mocks/cuesheet.{ts,mts,tsx,js,mjs,jsx}` | Module that default-exports the runtime options. `false` skips it |
| `enabled` | `true` on the dev server (except Vitest and `--mode test`) | `boolean` or `({ command, mode }) => boolean` |
| `dts` | `'src/cuesheet-env.d.ts'` | Type file path. `false` disables it |
| `optimizeDeps` | `true` | Pre-bundle `cuesheet` and `msw` on the dev server. `false` leaves it to Vite |
| `leakGuard` | `'error'` | What to do when it leaks into a disabled build. `'warn'` · `false` |

The plugin decides what is collected and when cuesheet runs. What cuesheet then does — `baseUrl`,
`storage`, `record`, `log`, `expose`, `defaultEnabled`, `plugins` — belongs to the setup module, so it
stays in code you can read, import into and type-check:

```ts
// src/mocks/cuesheet.ts
import { defineCuesheet } from 'cuesheet'

export default defineCuesheet({
  baseUrl: 'https://api.example.com',
  record: { limit: 200 },
})
```

- The file is optional. Without it the plugin starts cuesheet with `defaultEnabled: true` and
  `window.localStorage`, falling back to memory where reading that storage throws (a sandboxed iframe,
  blocked site data). Anything the setup module sets wins over those two defaults.
- `setup` must exist if you name one — a typo would silently drop every option, so the build fails
  instead. The module has to **default-export** the options: without a default export the build fails (and
  the dev server errors), and a default export that isn't the options object is reported in the console
  and ignored.
- `defaultEnabled` isn't an environment gate: a `?cue=` link or saved state overrides it, so use
  `enabled` to keep cuesheet out of a build.
- Every option also accepts `undefined`, so conditional values work under `exactOptionalPropertyTypes`.

> [!TIP]
> To use only the virtual module types when there is no type file, add `"@cuesheet/vite/client"` to
> `types` in `tsconfig.json`.

Supports Vite 6 · 7 · 8 (the same tests run on all three).

## For AI agents

The guide ships with the core package at `node_modules/cuesheet/AGENTS.md`, and the generated type file
points there too.

---

**Documentation:** [Getting started](https://github.com/GUMBOKIM/cuesheet/blob/main/docs/getting-started.md) ·
[Handlers](https://github.com/GUMBOKIM/cuesheet/blob/main/docs/handlers.md) ·
[All docs](https://github.com/GUMBOKIM/cuesheet/blob/main/docs/index.md)

---
_Source: https://npm.io/package/@cuesheet/vite · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
