Skip to content

Getting StartedCreate Courier

Create Courier

Set Courier up in one command, in your project or a new one: the typed API, the route the browser calls it through, Studio and mock data.

6 min readboth modes

@noverax/create-courier sets Courier up in one command. It finds your framework, shows what it is about to do, and once you agree writes the files, installs the packages with your package manager and type-checks what it added. You get a working page at /courier before you have a backend: the example API answers from a mock that Studio runs.

In your project

Run it in the project's folder:

npx @noverax/create-courier

It prints the plan and asks before it changes anything:

Set Courier up in shop (Next.js 16.4.0, npm)

Files
  + src/courier/api.ts              your API, typed, with an example to start from
  + src/courier/boundary.ts         the endpoints the browser may call
  + courier.config.ts               lists your APIs for the app, Studio and agents
  + courier.mocks.ts                the mock Studio runs on port 7001
  + src/app/api/request/route.ts    the route the browser calls your API through
  + src/courier/query.ts            React Query hooks for your API
  + src/app/courier/page.tsx        a page that shows Courier at work
  + src/instrumentation.ts          registers your APIs as the server starts
  + src/instrumentation-client.ts   the browser's connection to Studio

Changes to your files
  ~ package.json                    adds Courier's scripts
      +     "studio": "courier-studio"

Packages
  + @noverax/courier @noverax/courier-next @noverax/courier-react @tanstack/react-query zod @noverax/courier-studio-core
  + @noverax/courier-studio @noverax/courier-mock hono @hono/node-server  (dev)

Then start Studio, which runs the mock, and your app:

bash
npm run studio
npm run dev

Open /courier: the users the mock answers with, and a form that creates one, each call in Studio's timeline.

In a new project

Point it at a folder that does not exist yet, and name the framework:

bash
npx @noverax/create-courier shop --framework next

It creates the project with the framework's own generator — create-next-app, sv, create-astro and the others, run without a question at the major the setup is checked against — puts right what a template gets wrong for the project it makes, installs its packages with your package manager, and sets Courier up in it. Express has no generator of its own: the command writes a minimal server in TypeScript. In a terminal, it asks for the framework when --framework is left out, and whether to offer the API to AI agents, all before it makes anything.

A project it creates is moved to TypeScript 6 where its template came with an older one. A project you already have keeps the TypeScript it has, and the plan says how to move when you are ready.

What it sets up

FrameworkWhere your API is servedWhat it changes in your files
Next.jsapp/api/request/route.ts, registered from instrumentation.tsnext.config only when Studio's default port is taken
Nuxtserver/api/request.ts, registered from a Nitro pluginStudio's module in nuxt.config; app.vue renders pages where it showed the welcome
SvelteKitsrc/routes/api/request/+server.ts, registered from hooks.server.tsStudio's plugin in vite.config
Astrosrc/pages/api/request.ts, on demand, registered from the middlewareStudio's integration in astro.config
React Router, Remixapp/routes/api.request.tsthe routes in app/routes.ts; Studio's plugin in vite.config
SolidStartsrc/routes/api/request.tsStudio's plugin in vite.config
React with Viteno server: the browser calls your API directlyStudio's plugin in vite.config
Vue with Viteno server: the browser calls your API directlyStudio's plugin in vite.config
Expono server: the app calls your API directlya Courier tab in the template's tabs
Expressa router on /api/request and /courierthe router mounted after express()
Honoroutes on /api/request and /courierthe routes mounted after new Hono(); include in a tsconfig that compiles src/
Fastifya plugin on /api/request and /courier.courier/ kept out of fastify start -w
NestJSa module on /api/request and /courierthe module imported into your root module

Every setup adds courier.config.ts, the list of your APIs that your server, Studio and the MCP server read; courier.mocks.ts, the mock Studio starts with itself; and your API's definition, with its Zod schemas and the boundary that holds the browser to the endpoints it may call. A server compiled by tsc from src/ — Express, Hono, Fastify, NestJS — cannot import a file at the project's root, so its list lives in src/courier/config.ts, which the server registers from, and courier.config.ts passes it on to Studio and agents. It is still one list: an API Studio imports is declared where the list is written.

What it will not do

  • Change anything you have not seen. The plan comes first; without a terminal to answer, in CI or for an agent, nothing changes unless --yes is passed. --dry-run shows the plan and stops, and Ctrl+C at any of its questions stops it with nothing changed.
  • Replace a file of yours. A file is only ever added. Where a file of yours stands where Courier's would go — your own instrumentation.ts, say — it is kept, and the lines it would hold are listed for you.
  • Edit a file it cannot read. A change to a file of yours is made only where the file has a shape the command knows: one default export of a config object, one const app = express(). It is shown line by line in the plan and checked against the file right before it is written; a file that changed meanwhile stops the setup with its name. Anywhere else, the change is left to you, with the lines to add.
  • Take a port that is taken. Studio takes 6280 and the mock 7001 unless something listens there already, another project's Studio say; then the next free one, written in courier.config.ts and courier.mocks.ts.

Your own API

bash
npx @noverax/create-courier --openapi https://petstore3.swagger.io/api/v3/openapi.json

Imports an OpenAPI, Swagger or Postman specification in place of the example, with Studio's own importer: the typed code is written and the API is declared in courier.config.ts. See Import an API.

Behind a corporate proxy, npm installs through the proxy its own settings or HTTPS_PROXY name, and the specification is fetched through it once NODE_USE_ENV_PROXY=1 is set — see Proxies & Certificates.

AI agents

bash
npx @noverax/create-courier --mcp

Writes agents: { offer: "reads" } into the config — every read is offered to agents, a write once you mark it .agent() — describes the example's reads with .agent(), and adds .mcp.json, which Claude Code reads, so your editor's agent can call your API through the same middleware as your app. An imported API's reads are offered the same way, each described by its specification's summary. In a project set up before, it adds the policy to the config you have, unless the config says already what agents may call. In a terminal, it asks, for a project you have and for one it creates; with --yes, or without a terminal, it leaves agents out unless --mcp is passed. See What agents may call.

Options

Option
[dir]The project's folder, or a new one to create (default: the working directory)
--framework <name>next, nuxt, sveltekit, astro, react-router, remix, solid-start, expo, nestjs, fastify, hono, express, react, vue (default: found in package.json)
--openapi <spec>Import your API from a specification, a URL or a file, in place of the example
--name <name>The imported API's name (default: from the specification)
--no-studioLeave Studio out
--no-mocksLeave the example's mock out
--mcpOffer the API's reads to AI agents in your editor
--package-manager <name>npm, pnpm, yarn or bun (default: the project's, or the one that started the command)
--no-installWrite the files, and name the install commands
--yes, -yGo ahead without asking
--dry-runShow the plan, and change nothing

It needs Node.js 22 or later, and a project with a tsconfig.json: Courier is typed end to end.