Getting Started
Prerequisites
- Node.js >= 22.12 or Bun >= 1.3
- MySQL / PostgreSQL / SQLite (pick one)
- Redis (optional, for cache/session/queue/realtime)
Create a Project
nexwire ships as a scaffolding CLI called create-nexwire. It downloads the latest stable template from npm and sets up a ready-to-run project.
npm create nexwire@latest my-projectpnpm create nexwire@latest my-projectyarn create nexwire@latest my-projectbun create nexwire@latest my-projectTIP
npx nexwire@latest my-project also works for npm users without the create prefix.
Choosing an HTTP engine
By default the project uses the Hono engine. To start with Express instead, pass --engine=express:
npm create nexwire@latest my-project -- --engine=expresspnpm create nexwire@latest my-project --engine=expressyarn create nexwire@latest my-project --engine=expressbun create nexwire@latest my-project --engine=expressSee Routing: Hono vs Express for how the two engines differ.
Scaffold into the current directory
Use . as the project name to scaffold directly into the current directory instead of creating a new folder:
npm create nexwire@latest .pnpm create nexwire@latest .yarn create nexwire@latest .bun create nexwire@latest .TIP
--engine=express works the same way: npm create nexwire@latest . -- --engine=express, or bun create nexwire@latest . --engine=express for the other managers.
The project name is derived from the current folder name.
Setup
cd my-project
npm installcd my-project
pnpm installcd my-project
yarn installcd my-project
bun installTIP
There is nothing to copy before installing — the scaffolder writes a working .env for you, pointing at a SQLite database that is already migrated and seeded. .env.example sits beside it as the reference for what you can change; see Environment.
Package Manager Setup
Bun works out of the box — no extra configuration needed.
npm
npm 11.19+ blocks dependency install scripts by default. The template ships an allowScripts map covering the packages it uses (esbuild, @parcel/watcher, msgpackr-extract, vue-demi and redis-commander), so a fresh npm install finishes without the "install scripts not yet covered" warning. If you add a dependency that needs a build step, review and approve it:
npm install-scripts approve <package>Older npm versions ignore the field; nothing else changes.
pnpm
pnpm 11+ blocks install scripts by default. Create a pnpm-workspace.yaml in the project root:
allowBuilds:
esbuild: true
"@parcel/watcher": true
msgpackr-extract: true
redis-commander: true
vue-demi: true
bcrypt: trueAlternatively, run pnpm approve-builds during install to approve them interactively.
Yarn
Yarn 4.14+ disables build scripts and uses PnP by default. Create a .yarnrc.yml in the project root:
nodeLinker: node-modulesAlso add dependenciesMeta to your package.json to allow build scripts for required packages:
{
"dependenciesMeta": {
"esbuild": { "built": true },
"@parcel/watcher": { "built": true },
"msgpackr-extract": { "built": true },
"vue-demi": { "built": true }
}
}Without .yarnrc.yml, you'll also need to install peer dependencies explicitly (e.g. @asteasolutions/zod-to-openapi, @bull-board/ui, @popperjs/core).
Configure Database
Edit .env and set your DATABASE_URL:
# MySQL
DATABASE_URL=mysql://root:password@localhost:3306/nexwire
# PostgreSQL
DATABASE_URL=postgres://user:password@localhost:5432/nexwire
# SQLite
DATABASE_URL=sqlite:./src/storage/database/nexwire.sqliteSetup Database
npm run maker -- db:migrate --seedpnpm maker db:migrate --seedyarn maker db:migrate --seedbun maker db:migrate --seedThis generates the schema from your model files, runs migrations, and seeds the database — all in one step.
Start Development
The dev command starts everything you need at once:
npm run maker devpnpm maker devyarn maker devbun maker devThis starts:
| Component | Command | Auto-enabled |
|---|---|---|
| API server | maker serve --src | Always |
| Vue 3 UI (HMR) | maker ui:dev | Unless UI=false |
| Queue worker (default + mail) | maker queue:work | Unless REDIS=false |
All URLs are printed in the console when the dev server starts:
http://localhost:3000— API serverhttp://localhost:3000/api-docs— API documentation (Scalar)http://localhost:3000/queues— BullMQ queue dashboard (auto-enabled when Redis is on)http://localhost:5173— Vue 3 UI (hot reload)
Sidecar Tools
Add optional dev tools with --with|--view|--viewer:
npm run maker dev -- --with=redis,maildev,studiopnpm maker dev --with=redis,maildev,studioyarn maker dev --with=redis,maildev,studiobun maker dev --with=redis,maildev,studio| Tool | URL | Flag |
|---|---|---|
| MailDev (email preview) | http://localhost:1080 | --with=maildev |
| Redis Commander | http://localhost:1369 | --with=redis |
| Drizzle Studio | https://local.drizzle.studio | --with=studio |
Run Components Individually
You don't have to run everything together. Each component can be started separately:
# API server only
npm run maker serve -- --src
# Queue worker (background jobs)
npm run maker queue:work -- --queue=default,mail
# Scheduler (cron jobs)
npm run maker schedule:work
# Vue UI only
npm run maker ui:dev
# UI tools on demand
npm run maker maildev:view
npm run maker redis:viewpnpm maker serve --src
pnpm maker queue:work --queue=default,mail
pnpm maker schedule:work
pnpm maker ui:dev
pnpm maker maildev:view
pnpm maker redis:viewyarn maker serve --src
yarn maker queue:work --queue=default,mail
yarn maker schedule:work
yarn maker ui:dev
yarn maker maildev:view
yarn maker redis:viewbun maker serve --src
bun maker queue:work --queue=default,mail
bun maker schedule:work
bun maker ui:dev
bun maker maildev:view
bun maker redis:viewThis is useful when you want to run only the API server without the UI, or run the queue worker on a separate machine, or debug a specific component without the overhead of the full dev stack.
Production Mode
Run compiled (dist/) code for production-like testing:
maker serve --prod --runtime=node
maker queue:work --queue=default,mail --prod --runtime=node
maker schedule:work --prod --runtime=nodeThe --prod flag uses the compiled JavaScript in dist/ instead of running from TypeScript source. The --runtime flag switches between node and bun.
