Skip to main content

Run Workspaces

Run one package script across Nova workspaces in dependency order without a separate monorepo runner.

Summary

run-workspaces reads workspace paths from nova.config.json, reads scripts and internal package relationships from each workspace's package.json, validates the complete graph, and runs ready tasks concurrently. The project root is the top node of that graph, so its own steps run as part of the same command.

Nova applies lifecycle prerequisites consistently:

  • check and build first build internal workspace dependencies.
  • prod and deploy first run the selected workspace's check and build tasks.
  • dev, clean, and custom script names run directly.
  • A missing script skips that workspace and is reported instead of failing the entire graph.

Root Node

The root package.json is the top of the tree. Each lifecycle script there calls run-workspaces, such as "check": "nova utility run-workspaces check", and the root's own work lives in child steps such as check:lint and check:test.

  • Order — For check and build, Nova first builds any internal workspace packages used by the root. The root's <script>:* steps then run one at a time in package.json order before the remaining workspace tasks. For prod and deploy, the root steps still precede every workspace task. For dev and clean, they run alongside the workspaces.
  • Filtering — --workspace keeps the root. Pass --workspace ./ to run only the root, or --exclude-workspace ./ (or the root package name) to leave it out.
  • Caching — Root steps read the whole repository, so they always run and are never cached. Workspace tasks still cache normally.
  • Skipping — Set settings.runWorkspaces.root to "skip" to leave the root out of every run.
  • Nesting — A run started from inside the tree, or by a legacy <script>:workspaces script, does not add the root again.

Usage

Options

FlagDescription
-b, --buffer <ms>Flush interval in milliseconds for grouped task output. Defaults to 500.
-c, --concurrency <count>Override the configured limit for this run. Falls back to the script limit, then 10.
-k, --continue-on-errorContinue independent tasks after a failure while blocking tasks that depend on it.
-d, --dry-runValidate and print the expanded task plan without running package scripts.
-x, --exclude-workspace <name…>Exclude package names or configured workspace paths.
-f, --forceBypass verified local cache hits and refresh successful task records.
-n, --node-env <environment>Set child NODE_ENV to development, production, or test.
-w, --workspace <name…>Limit the requested task to package names or configured workspace paths.

Place -- after Nova's options to forward the remaining arguments to every workspace running the requested script. Lifecycle prerequisites with a different script name do not receive those arguments.

The default limit belongs to Nova's reusable runner. A consumer can define per-script limits under settings.runWorkspaces.concurrency without restricting unrelated tasks such as long-running development servers.

An explicit --concurrency option overrides the configured limit for that run. Scripts omitted from the map use Nova's default of 10.

Config Fields

FieldDescription
settings.runWorkspaces.concurrency.<script>Positive integer limit for one workspace script, such as check or build.
settings.runWorkspaces.root"first" (default) runs the root's own steps before the workspaces. "skip" leaves the root out.
nova.config.json
json
{
  "settings": {
    "runWorkspaces": {
      "concurrency": {
        "build": 2,
        "check": 2,
        "deploy": 2
      }
    }
  }
}

Examples

Check every workspace with two concurrent tasks
bash
nova utility run-workspaces check --concurrency 2
Build two publish scopes and their internal dependencies
bash
nova utility run-workspaces build \
  --concurrency 2 \
  --workspace @example/api @example/web
Preview cleanup while excluding a workspace
bash
nova utility run-workspaces clean \
  --dry-run \
  --exclude-workspace @example/container
Forward a representative build mode to every build workspace
bash
nova utility run-workspaces build -- --representative

Verified Local Cache

Nova caches successful check and build tasks locally by default. A task is skipped only when its command, arguments, toolchain, stable environment, root manifests, dependency-task states, and complete workspace state still match the verified record.

The cache stores hashes, not build artifacts or raw environment values. If a source file changes, an output is removed, a dependency task changes, or a record becomes unreadable, Nova runs the real task again. Failed and interrupted tasks are never cached.

nova.config.json
json
{
  "settings": {
    "runWorkspaces": {
      "cache": {
        "directory": "./node_modules/.cache/nova/run-workspaces",
        "enabled": true,
        "scripts": ["build", "check"]
      }
    }
  }
}

Use --force when you intentionally want every selected cacheable task to execute and replace its successful record. Set enabled to false to disable cache reads and writes, or change scripts to choose which exact package-script names are eligible.

Failure and Interrupt Behavior

By default, Nova stops scheduling new tasks after the first failure, asks active children to stop, and exits unsuccessfully. With --continue-on-error, unrelated branches continue while dependent tasks are listed as blocked.

Pressing Ctrl + C stops active workspace scripts and exits cleanly. Buffered output uses the same framed sections as run-scripts, labeled as workspace#script.

Troubleshooting

  • Unsupported package manager — Set the root packageManager to an exact npm, pnpm, or Yarn descriptor.
  • Workspace name drift — Keep each nova.config.json workspace name identical to its package's package.json name.
  • Unknown workspace selection — Pass an exact package name or configured Nova workspace path.
  • Dependency cycle — Remove the circular internal package relationship before retrying; Nova validates this before spawning tasks.
  • Unexpected cache miss — Nova intentionally reruns when any verified input or workspace output differs. Use the task output to confirm what regenerated, then let the successful run establish the new record.