Project Generator
create-vercube is vercube init: it downloads a template, pins every @vercube/* package to its own version, applies a recipe per module and per deploy target, installs the dependencies and initializes git. A project created today keeps building when the next release ships.
$ pnpm create vercube my-app \
--template fullstack-vue \
--modules schema,auth,testing \
--yes
Templates
| Template | What you get |
|---|---|
api | A Vercube API: src/index.ts, src/boot/Container.ts, one controller, oxlint and oxfmt. The default |
fullstack-vue | A workspace: apps/api (the API) and apps/web (Vue on Vite), with packages/ for shared code. One dev at the root starts both, Vite proxies /api to the API, and the web app calls it through @vercube/client, typed by the API's controllers |
In the fullstack template the modules are added to apps/api. A React template is planned; Deno supports the api template only.
Modules
| Module | Flag value | What the recipe adds |
|---|---|---|
| Schema / OpenAPI | schema | SchemaPlugin, a validated route documented at /_schema/docs |
| Auth | auth | An API key provider (API_KEY, generated into .env), a route behind @Auth() |
| Storage | storage | StorageManager with a memory or S3 mount, a read/write route |
| Cache | cache | CacheManager on a storage mount (adds Storage), a @Cache() route |
| Queue | queue | QueuePlugin with the chosen driver, a consumer and a route that publishes to it |
| Scheduler | scheduler | SchedulerPlugin with the chosen store, an interval job (and a cron job with a shared store) |
| WebSockets | ws | WebsocketPlugin, a gateway at /chat |
| Telemetry | telemetry | TelemetryPlugin, OpenTelemetry started before the app, the OTLP exporter |
| Devtools | devtools | DevtoolsPlugin at /_devtools, with a token for production |
| Testing | testing | vitest, @vercube/testing, a test for the starter controller |
Schema, Testing and Devtools are selected by default. A module another one needs is added with it and named in the summary: Cache adds Storage.
Modules with a choice ask for it, or take a flag:
| Flag | Values | Default |
|---|---|---|
--queue | bullmq, rabbitmq, kafka, memory | bullmq |
--scheduler-store | memory, redis, postgres | memory |
--storage | memory, s3 | memory |
S3 is the exception: no local service is added, set the bucket, region and credentials (and an endpoint for an S3-compatible service such as MinIO) in .env. Any other driver with a server behind it adds the server to docker-compose.yml, published on 127.0.0.1 only, and its URL to .env and .env.example. Redis is added once when both the queue and the scheduler use it. The queue and the scheduler also turn on shutdown.handleSignals: an open broker or store connection would otherwise keep the process running after SIGTERM or Ctrl-C.
With vercube init, a flag for a module that is not selected, such as --queue with --modules none, fails rather than being ignored, and so does a mistyped flag.
Deploy targets
| Flag value | What changes |
|---|---|
node | Nothing: vercube build, then node dist/index.mjs (or Bun, or Deno). The default |
aws-lambda | export const handler in src/index.ts, serverless.yml, offline and deploy scripts |
azure-functions | src/functions/httpTrigger.ts, host.json, local.settings.json (gitignored), a second build entry |
app.listen() stays in the entry for both serverless targets: vercube dev needs it, and it binds no port on Lambda or Azure.
Flags
| Flag | |
|---|---|
<dir> | Where to create the project |
--template | api or fullstack-vue |
--modules | Comma separated, or none |
--deploy | node, aws-lambda or azure-functions |
--package-manager | pnpm, npm, yarn, bun or deno; the one running the CLI by default |
--yes | Take the default for every question no flag answers; a non-empty directory still needs --force |
--force | Replace the contents of a directory that is not empty (its .git stays) |
--no-install | Skip installing dependencies |
--no-git-init | Skip git init |
Without a terminal (CI, an agent) and without --yes, a missing answer fails with every flag still needed, instead of waiting for input:
ERROR Missing --template, --queue, --deploy, --package-manager.
Pass them, or --yes for the defaults, when there is no terminal to ask in.
Example:
vercube init my-app --template api --modules schema,testing --deploy node --yes
Adding modules to a project
vercube add applies the same recipes to an existing project. It takes the module question flags (--queue, --scheduler-store, --storage), --yes, --no-install and --cwd:
$ pnpm vercube add queue --queue rabbitmq
$ pnpm vercube add cache,ws --yes
Every recipe checks what is there before it adds anything, so adding a module twice changes nothing, and a file you edited is never overwritten. Code is edited through its syntax tree: a plugin goes into the plugins of vercube.config.ts, a binding into the exported function of src/boot/Container.ts that takes the container. When a recipe cannot find either, it stops and says what to add by hand.
A package can ship a recipe of its own, see Writing a recipe:
$ pnpm add @acme/vercube-search
$ pnpm vercube add @acme/vercube-search
In a fullstack project, install the package with pnpm --filter api add.