CLI reference
Every command below runs as devora <command> — via pnpm exec, npm exec/npx, or yarn, whichever your project uses (or a package.json script). This page describes @devorajs/cli 0.3.5; npx devora --version prints yours.
dev, build, start and deploy load the project root's .env files first (.env, .env.local, .env.<mode>, .env.<mode>.local, with Vite's precedence; mode is development for dev, production otherwise). A variable already set in the environment always wins, and only file names are printed, never values.
| Command | Does | |
|---|---|---|
dev | Run every app (or one) in dev mode | |
build | Build for production, optionally for an adapter | |
start | Serve a production build (self-hosted) | |
deploy | Build and push straight to Vercel/Netlify | |
new | Scaffold a new app in the project | |
add | Alias of new | |
remove | Delete an app (alias: rm) | |
list | List every registered app (alias: ls) | |
split | Split an app/backend into its own repo | 0.2+ |
sync | Pull/push a split-off piece's remote | 0.2+ |
status | Sync state across every split-off piece | 0.2+ |
generate:proxy | Write an nginx/Caddy reverse-proxy config |
devora dev
Runs every app in the project in dev mode at once, each on its own Vite dev server. Pass --app <name> to run just one app instead — the common case once a project has more than one app and you're only working on one of them.
Ports start at 10000, one per app in devora.config.ts order (10000, 10001, 10002, …). Set devPort on an app's entry in devora.config.ts to pin a different one. If a port is taken, that app moves to the next free port and the CLI says so, rather than failing. These are dev-only; devora start uses its own ports (from 4173).
On boot it prints a short header, then every app's URLs, then the routes per app — so you can see what's actually being served without opening routes/. Pages are always listed; an app's API routes are listed when it has 10 or fewer and counted above that. This is real output from a fresh three-app project (NO_COLOR=1; in a color terminal the mark is drawn in the logo's gradient):
▄█
▄▄▄▄▄██ ▄ devora.js 0.3.5
▄█▀▀▀▀▀██ ▀█▄ dev · 3 apps · ready in 312 ms
██ ██ ▄█▀
▀███████ █▀
marketing auth: none · marketing.example.com
Local: http://localhost:10000/
Network: use --host to expose
dashboard auth: shared · dashboard.example.com
Local: http://localhost:10001/
Network: use --host to expose
API: http://localhost:10001/api
admin auth: isolated · admin.example.com
Local: http://localhost:10002/
Network: use --host to expose
Routes
marketing
page /
dashboard
page /
page /account
page /login
page /logout
api /api/hello
admin
page /
page /account
page /login
page /logout| Flag | Does |
|---|---|
--app <name> | Run only this app |
--host | Listen on every network interface and print LAN URLs (with a warning) |
--routes | List every API route, however many (same as DEVORA_ROUTES=all) |
--quiet | Only warnings, errors and one URL line per app; Vite logs at warn |
Terminal output follows the usual conventions: color in a terminal, plain text when piped or in CI (CI set), NO_COLOR=1 turns color off and FORCE_COLOR (0 off, 1/2/3 for 16/256/truecolor) overrides both. Terminals narrower than 43 columns get a one-line header. Nothing animates.
--host (off by default) listens on all network interfaces instead of just localhost, and adds each app's LAN address to that output (Network: http://192.168.x.x:10000/) — for testing on a phone or another device on the same network. It prints a warning when enabled, since anyone on that network can then reach your dev server. Scaffolded projects include it as a script: npm run dev:host.
devora build
Builds every app for production (or one, with --app <name>). Add --adapter <target> (vercel or netlify) to also write that platform's build output format alongside the standard build — needed before a Vercel or Netlify deploy, not needed for self-hosting. Any other --adapter value is an error.
- Always builds with
NODE_ENV=production, and says so if it overrides a value you set. - Runs the app's
prebuildcommands (app.config.ts) first, in the app folder, withnode_modules/.binonPATH; a failing command stops the build. - With
--adapter, runs preflight checks before any build work: session secret and store for the app's auth mode (both platforms); a supported function runtime and no top-levelapi/folder in the Vercel project (Vercel); the API folder listed innetlify.toml'sincluded_files(Netlify). --out <dir>(with--adapter=vercel --app=<name>) writes the Build Output directory somewhere other thanapps/<name>/.vercel/output— e.g.--out=.vercel/outputwhen the Vercel project's Root Directory is the repo root.--quietkeeps only warnings and errors.
devora start
Serves a production build with the plain Node adapter — run devora build first. Pass --app <name> to serve just one app. The port is --port, else the PORT environment variable, else 4173; each additional app gets the next port, so multiple apps never collide on the same host. The interface is --host, else HOST, else every interface (use HOST=127.0.0.1 behind a reverse proxy). Values taken from the environment are printed. It always runs with NODE_ENV=production. The same server is available as createNodeServer() from @devorajs/adapter-node if you need your own entry point.
devora deploy
Builds and deploys straight to Vercel or Netlify via --adapter <target> (required), for all apps or one with --app <name>, deploying to production instead of a preview with --prod. Each app must already be linked to its own platform project/site (vercel link / netlify link, run once per app directory) — an unlinked app is skipped with an instruction rather than failing the whole run, and one app's deploy failure doesn't stop the rest. This is a convenience on top of the git-integration deploy flow described in Deployment, not a replacement for it.
devora new <app-name>
Scaffolds a new app inside an existing project — creates apps/<name> and registers it in devora.config.ts. Prompts whether the app needs auth/sessions unless you pass --auth shared|isolated|none, and --domain <domain> sets the domain recorded in the config (otherwise a placeholder is used). --kind pages|api picks a page app or a backend-only API app; without it, a project whose apps are all backend-only gets an API app, otherwise a page app. New apps keep API routes in endpoints/ (apiDir: "endpoints").
devora add <app-name>
Identical to devora new — a friendlier alias for the same scaffolding action, same flags.
devora remove <app-name> alias: rm
Undoes new/add: deletes apps/<name> and its entry in devora.config.ts. No flags.
devora list alias: ls
Lists every app currently registered in devora.config.ts — name, directory, domain, and effective auth mode. Useful for checking a project's shape without opening the config file.
devora split <app-name|backend> since 0.2.0
See Repo-splitting for the full explanation. Converts apps/<name> (or the literal backend, for packages/backend) into a real git submodule pointing at --repo <url> — an empty remote you create yourself first. Prompts for confirmation before doing anything (skip with --yes for scripted use).
devora sync [names...] since 0.2.0
Pulls or pushes a split-off app/backend against its own remote — exactly one of --from-main (merge the remote's latest into your local checkout) or --to-main (push local commits made inside that checkout) is required. Name one or more targets, or pass --all for every split-off piece. Shows the real commits it's about to pull/push and asks for confirmation first (--yes skips it).
devora status since 0.2.0
One view across every split-off app/backend: up to date, local commits not pushed, remote commits not pulled, or diverged.
devora generate:proxy
Reads every app's domain out of devora.config.ts and writes a working reverse proxy config for self-hosting. --target <target> (required) is nginx or caddy; --out <path> sets where the file is written instead of the default location.