Create Zuplo API
The create-zuplo-api CLI makes it easy to create a new Zuplo API using the
default template or an
example from a public
GitHub repository. It's the fastest way to get started with Zuplo.
Code
Options
create-zuplo-api comes with the following options:
-v, --version- Output the current version of create-zuplo-api--linter <linter>- The linter to configure (eslint,biome,oxlint, ornone). See Choosing a linter and formatter--formatter <formatter>- The formatter to configure (prettier,biome,oxfmt, ornone)--empty- Initialize an empty project--use-npm- Explicitly tell the CLI to bootstrap the application using npm--use-pnpm- Explicitly tell the CLI to bootstrap the application using pnpm--use-yarn- Explicitly tell the CLI to bootstrap the application using Yarn--use-bun- Explicitly tell the CLI to bootstrap the application using Bun--reset, --reset-preferences- Reset the preferences saved for create-zuplo-api--git- Whether or not to initialize the project as a git repository--version-check- Whether or not to check for an outdated version--install- Whether or not to install packages--verbose- Enable verbose logging--yes- Use saved preferences or defaults for unprovided options--server-project- Create a matching project on portal.zuplo.com and link this working copy to it, skipping the interactive prompt. See Creating a matching portal project--account <account-name>- The Zuplo account that will host the server project. Implies--server-project--agents <agents>- Comma-separated list of AI coding agents to configure (claude,copilot,cursor,windsurf,codex), ornoneto skip agent setup. See Configuring AI coding agents--template <template-name>- A built-in template to bootstrap the API with (default,default-empty, orai-gateway-v2). Can't be combined with--exampleor--empty. See Choosing a template-e, --example <example-name|github-url>- An example to bootstrap the API with. You can use an example name from the official Zuplo repository or a public GitHub URL. The URL can use any branch and/or subdirectory--example-path <path-to-example>- In a rare case, your GitHub URL might contain a branch name with a slash (for example, bug/fix-1) and the path to the example (for example, foo/bar). In this case, you must specify the path to the example separately:--example-path foo/bar-h, --help- Display the help message
Opting out with --no- flags
Each boolean option also accepts a --no- form that turns the feature off:
| Opt-out flag | Effect |
|---|---|
--no-git | Don't initialize the project as a git repository |
--no-install | Don't install packages |
--no-version-check | Don't check for an outdated version |
--no-server-project | Don't create a matching project on portal.zuplo.com |
These flags matter most in CI and scripted use. --yes accepts whatever is
saved in your preferences for any option you didn't pass, so a value you chose
once on a workstation can carry into a later run. A --no- flag, or an explicit
value such as --linter none, ignores saved preferences and suppresses the
prompt outright, which makes the result the same on every machine:
Code
If you pass both spellings of the same option, the affirmative flag wins — so
--git --no-git initializes a git repository. --no-server-project is the
exception: it always wins, even when combined with --server-project or
--account.
Choosing a template
--template selects which built-in template the CLI scaffolds from. Without the
flag you get the default template.
| Value | What it scaffolds |
|---|---|
default | Sample /todos routes, a hello-world module, a dev portal in docs/, and VS Code settings |
default-empty | The same project with no routes defined and no VS Code settings |
ai-gateway-v2 | An AI Gateway project, without a dev portal |
--empty is shorthand for --template default-empty.
The ai-gateway-v2 template scaffolds config/ai.oas.json, which routes
/:app_id/v1/* to the AI Gateway handler, and config/policies.json, which
declares the policies an application's policy chain can select. It ships no
docs/ directory, so the CLI skips the
dev portal workspace:
Code
--template names a built-in template, which is why it can't be combined with
--example (a project pulled from GitHub) or with --empty (use
--template default-empty). Either combination stops the CLI before it writes
any files, as does a template name that isn't in the table above.
Choosing a linter and formatter
--linter and --formatter pick the tools the CLI sets up. Without either flag
the CLI asks, with ESLint and Prettier preselected.
--linter | Config file | Dev dependencies |
|---|---|---|
eslint | eslint.config.js | eslint, @eslint/js, typescript-eslint |
biome | biome.json | @biomejs/biome |
oxlint | .oxlintrc.json | oxlint |
none | None | None |
--formatter | Config file | Dev dependencies |
|---|---|---|
prettier | .prettierrc.json | prettier |
biome | biome.json | @biomejs/biome |
oxfmt (in beta) | .oxfmtrc.json | oxfmt |
none | None | None |
A linter adds lint and lint:fix scripts to package.json, and a formatter
adds format and format:check. The dev portal workspace in docs/ gets the
same lint script. The CLI also writes a .vscode/extensions.json that
recommends the editor extensions for the tools you picked.
Biome fills both roles from one dependency and a single biome.json:
Code
Picking Biome as the linter preselects it as the formatter in the interactive
prompt. Pairing ESLint with Prettier also installs eslint-config-prettier, so
the linter doesn't fight the formatter.
An unrecognized value is an error and prints the valid values. With --yes or in
CI, the CLI uses your saved preferences, or ESLint and Prettier if you have none.
Configuring AI coding agents
Pass --agents to write instruction files and MCP configuration for the coding
agents you use. Each selected agent also gets the
Zuplo agent skills, so it works from
accurate Zuplo documentation instead of training data. Claude Code enables them
through the zuplo/tools plugin marketplace in .claude/settings.json. For
every other agent, the CLI downloads the skill files into that agent's skills
directory, such as .cursor/skills/.
| Value | Agent | Files written |
|---|---|---|
claude | Claude Code | CLAUDE.md, .claude/settings.json, .mcp.json |
copilot | GitHub Copilot | .github/copilot-instructions.md, .mcp.json |
cursor | Cursor | .cursorrules, .mcp.json |
windsurf | Windsurf | .windsurfrules, .mcp.json |
codex | OpenAI Codex | AGENTS.md, .mcp.json |
none | — | Nothing — skips agent setup |
Combine values with commas:
Code
The CLI validates the list before scaffolding anything:
- An unrecognized agent name is an error.
--agents zedfails and prints the valid values. nonecan't be combined with a real agent. Use--agents noneto skip agent setup, or list only the agents you want.
Creating a matching portal project
By default, the CLI asks whether to create a matching project on
portal.zuplo.com and link your new working copy to it. Answering yes runs
zuplo project create and zuplo link, which creates the project in your Zuplo
account and writes ZUPLO_ACCOUNT_NAME and ZUPLO_PROJECT_NAME to a
.env.zuplo file in the project directory. The CLI then prints the portal URL
for the new project.
Pass --server-project to opt in without the prompt, or --account <name> to
also choose which account hosts the project:
Code
Creating the project requires authentication. Run
zuplo login first, or let zuplo project create walk
you through signing in. When you have access to exactly one account, the CLI
picks it automatically; with more than one and no --account, it asks which
account should host the project.
To keep everything local, pass --no-server-project:
Code
--yes and CI environments skip this step unless you pass --server-project or
--account. Unlike the other prompts, the answer isn't saved to your
preferences, so a yes on your workstation never becomes a yes in CI.
In non-interactive runs the CLI can't ask which account to use. Unless your
credentials resolve to exactly one account, pair --server-project with
--account. Otherwise the CLI prints a note, leaves your local files in place,
and skips the portal project:
Code
If project creation or linking fails, the scaffolded files stay on disk and the
CLI tells you how to finish up — run zuplo project create --name my-api and
zuplo link from inside the project directory.
Examples
The following examples show different ways to use create-zuplo-api:
With Default Template
Code
The CLI asks the following questions:
Code
Pass the directory as an argument to skip the first question, then start the development server:
Code
With an Official Example from GitHub
To create a new Zuplo API using an official example from the Zuplo GitHub
repository, you specify the example name using the --example option.
Code
You can find the list of available examples in the Zuplo examples repository.
Examples ship their own linting, formatting, and agent configuration, so the CLI skips those questions. It still asks about creating a matching project on portal.zuplo.com, because that choice is independent of the template.
With any Public GitHub Repository
To create a new Zuplo API using any public GitHub repository, you can specify
the repository URL using the --example option.
Code