Reference

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.

CommandDoes
devRun every app (or one) in dev mode
buildBuild for production, optionally for an adapter
startServe a production build (self-hosted)
deployBuild and push straight to Vercel/Netlify
newScaffold a new app in the project
addAlias of new
removeDelete an app (alias: rm)
listList every registered app (alias: ls)
splitSplit an app/backend into its own repo0.2+
syncPull/push a split-off piece's remote0.2+
statusSync state across every split-off piece0.2+
generate:proxyWrite 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
FlagDoes
--app <name>Run only this app
--hostListen on every network interface and print LAN URLs (with a warning)
--routesList every API route, however many (same as DEVORA_ROUTES=all)
--quietOnly 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 prebuild commands (app.config.ts) first, in the app folder, with node_modules/.bin on PATH; 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-level api/ folder in the Vercel project (Vercel); the API folder listed in netlify.toml's included_files (Netlify).
  • --out <dir> (with --adapter=vercel --app=<name>) writes the Build Output directory somewhere other than apps/<name>/.vercel/output — e.g. --out=.vercel/output when the Vercel project's Root Directory is the repo root.
  • --quiet keeps 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.