JORVEL

CLI reference

The jorvel CLI ships every workflow you need — scaffold, dev, build, federation, SSR, quality gates, deploy. Run jorvel --help or jorvel <cmd> --help for the live command list.

Where commands run

Most commands work from anywhere in the workspace. Per-app commands (e.g. jorvel routes) infer the target from your current directory. Use --app <name> to override.

Project commands

CommandPurpose
npm create jorvel@latest <name>Shorthand for jorvel init via the create-jorvel package (works with pnpm/yarn/bun create too)
jorvel init <name>Scaffolds a runnable app — workspace + starter host + remote, auto-wired. cd, install, jorvel dev and it runs (create-next-app style)
jorvel init <name> --no-appBare workspace only — skip the starter host + remote
jorvel init <name> --template <t>Starter template: host-remote (default) · saas · blank
jorvel init <name> --pm <m>Package manager: pnpm (default) · npm · yarn · bun
jorvel init <name> --tailwindWire Tailwind v3 + PostCSS in the scaffolded apps
jorvel generate host <name>Add a host app (React). Interactive: prompts to add Tailwind
jorvel generate remote <name>Add a remote — auto-wired into the host (federation + host routes + REMOTES map). Prompts for framework, language, Tailwind
jorvel generate remote <name> --no-wireAdd a remote WITHOUT auto-wiring it into the host
jorvel generate remote <name> --framework vue --lang js --tailwindSkip prompts: Vue remote in JavaScript with Tailwind
jorvel generate remote <name> --no-tailwindSkip the Tailwind prompt (no Tailwind)
jorvel generate wizardPrompt-driven generator (framework + Tailwind per app)
jorvel generate typesEmit the host's src/remotes.d.ts from its federation/routes wiring (so import('remote/App') type-checks)
jorvel add remote <name> [--port n] [--url …]Wire an existing remote into the host: federation map + route + remotes.d.ts + bootstrap REMOTES/NavLink
jorvel add db [app] [--driver sqlite|libsql]Scaffold a Drizzle ORM backend into an app: schema + client + migrations + seed + a defineLoader data module

Naming rules

  • App names must match /^[a-z][a-z0-9-]*$/ (lowercase, alphanumeric, hyphens; must start with a letter).
  • Ports must be in 1–65535; the CLI refuses duplicates and reserved ranges.
  • The host should be on a stable port (e.g. 3000) — generated configs reference it from every remote.

Dev & build

CommandPurpose
jorvel devRun all apps with the Rspack dev-server (colored per-app output; fails fast on duplicate and already-in-use ports — --no-port-check to skip)
jorvel dev --only shell,dashboardRun only the named apps (--exclude for the inverse)
jorvel dev --proxy-remotesServe every remote under the host origin (recommended)
jorvel dev --hmr-remotesCross-app HMR — host reloads when any remote recompiles
jorvel buildProduction build, host first then remotes
jorvel build --app dashboardBuild one app
jorvel build --compressEmit .gz / .br alongside every static asset
jorvel build --compute-sriHash remoteEntry.js for SRI; writes jorvel.federation.sri.json
jorvel build --parallelBuild apps concurrently (they are independent — federation resolves at runtime)
jorvel build --stats [path]Write a JSON summary (apps, sizes, shared-dep conflicts) — default jorvel-build-stats.json
jorvel image optimize [--app n] [--formats webp,avif] [--widths …] [--quality n]Generate responsive/modern-format image variants from dist/
jorvel lazyScaffold a lazy-boundary helper for code-split remote components
jorvel analyze --app dashboardOpen a bundle analyzer (rsdoctor → rspack-bundle-analyzer → built-in HTML fallback)
jorvel perf-dashboard [--input file] [--budgets file]Live terminal dashboard: remote loads, p95, size, budget status
jorvel route-editor [--manifest file]Emits a self-contained HTML editor for the host route tree (drag remotes onto a parent path). Defaults the manifest to the discovered host app.
jorvel adapter add <vue|svelte|solid> --name XScaffold a remote built with a non-React framework
jorvel split [--log file] [--top N]Analyze a traffic log and suggest the highest-impact component to split into its own remote
jorvel loadtest [--target url]Scaffold a k6 load-test script with p95 / failure-rate thresholds
jorvel typedoc [--out dir]Generate the TypeDoc API reference from libs/* into the docs site (markdown by default)
jorvel schema [--out dir]Emit the authoritative JSON Schemas (jorvel.config / jorvel.app / jorvel.federation) re-sourced from @jorvel/types
jorvel config validateValidate jorvel.config.json against the bundled schema
jorvel turbo [--force]Scaffold a turbo.json with the standard JORVEL task graph (build / typecheck / test / lint / dev)
jorvel federationRegenerate jorvel.federation.json for every app
jorvel federation diff [--base ref] [--allow-breaking] [--json]Diff federation contracts vs a git base ref; exits 1 on a breaking change (removed expose, dropped remote, singleton demotion) — a CI gate
jorvel canary <remote> --url … [--weight n] [--promote] [--rollback] [--status]Weighted canary rollout for a remote → jorvel.federation.canary.json (runtime picks per user via pickWeightedRemote)
jorvel federation impact [remote] [--json]Impact analysis — which hosts consume a remote (before changing/retiring it)
jorvel info [--json]Shareable environment diagnostic bundle (OS, Node, pkg managers, apps, @jorvel deps)
jorvel routesCompile src/pages/ into src/jorvel.routes.ts (or .js for JS apps)
jorvel routes --watchRe-compile on file changes

Typical dev session

bash
# Terminal 1
jorvel dev --proxy-remotes --hmr-remotes

# Terminal 2 — auto-regenerate routes when you add a page
cd apps/dashboard
jorvel routes --watch

SSR

CommandPurpose
jorvel ssr exportPre-render the routes table to static HTML (SSG)
jorvel ssr export --out dist-ssg --manifest manifest.jsonCustom output + content-hash manifest
jorvel ssr serve --port 3000Streaming Node SSR (default)
jorvel ssr serve --port 3000 --no-streamSynchronous SSR — useful for buggy CDN edges
jorvel ssr serve --static apps/shell/distAlso serve built client assets so hydration bundles resolve

Quality

CommandPurpose
jorvel lintESLint across the workspace; reuses the workspace config
jorvel lint --fixApply auto-fixes
jorvel testVitest across every package, parallel by default
jorvel test --coverageGenerate HTML + lcov coverage under each coverage/ dir
jorvel typechecktsc --noEmit per package, project-references aware
jorvel perfBundle-size budget check; reads perf.budget.json
jorvel e2eRun Playwright against the example app

Budget format

perf.budget.json takes pattern entries like { "*.js": { "maxSize": "200kb" } }. Patterns are matched against the emitted asset names; failing budgets exit non-zero so CI catches regressions.

Ops

CommandPurpose
jorvel diagnoseVerify Node, pnpm, Rspack peer, ports, configs, .env vs .env.example, federation contract drift, React-duplication risks
jorvel env checkFail if any var listed in .env.example is missing
jorvel env scaffoldWrite a starter .env.example
jorvel deploy --target vercelScaffold vercel.json + edge handler
jorvel deploy --target cloudflareScaffold wrangler.toml + Worker handler
jorvel deploy --target nodeScaffold a Node server entry
jorvel deploy --target dockerScaffold a multi-stage Dockerfile
jorvel ci affectedList apps changed since the last commit — feed into a build matrix
jorvel sw generate [--app <name>]Write jorvel-sw.js into the host's public/ (auto-discovers the host app when --app is omitted)

CI snippet

.github/workflows/ci.yml
yaml
jobs:
  affected:
    runs-on: ubuntu-latest
    outputs:
      apps: ${{ steps.affected.outputs.apps }}
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: pnpm/action-setup@v4
        with: { version: 9.15.5 }
      - run: pnpm install --frozen-lockfile
      - id: affected
        run: echo "apps=$(jorvel ci affected --json)" >> "$GITHUB_OUTPUT"

  build:
    needs: affected
    if: needs.affected.outputs.apps != '[]'
    strategy:
      matrix:
        app: ${{ fromJSON(needs.affected.outputs.apps) }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
        with: { version: 9.15.5 }
      - run: pnpm install --frozen-lockfile
      - run: jorvel build --app ${{ matrix.app }} --compress --compute-sri

Workspace config

Every command loads a single jorvel.config.json from the workspace root (validate it with jorvel config validate). Key fields:

FieldEffect
appsDirDirectory the CLI scans for apps. Default "apps"; set it to relocate the apps folder — honored by app + host discovery across dev/build/routes/federation/deploy/ci/sw/route-editor.
federation.sharedExtra packages to share as singletons across host + remotes (merged into every generated federation config).
securityCSP / allowlist defaults consumed by the security helpers.
deployAdapter target + options for jorvel deploy.
pluginsCLI plugins loaded at startup.

Environment variables

VariableEffect
JORVEL_DEBUG=1Print full stack traces from CLI errors
JORVEL_NO_COLOR=1Disable ANSI colors (also respects NO_COLOR)
JORVEL_OFFLINE=1Skip network checks during scaffolding
JORVEL_DEV_RELOAD_URLInjected by --hmr-remotes; the host's reload-WS endpoint
JORVEL_E2E=1Opt into the Playwright suite locally

Exit codes

CodeMeaning
0Success
1Generic failure (uncaught exception, validation error)
2User input invalid (bad flag, missing argument)
3Lifecycle failure (build/test/typecheck step exited non-zero)