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:
checkandbuildfirst build internal workspace dependencies.prodanddeployfirst run the selected workspace'scheckandbuildtasks.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
checkandbuild, Nova first builds any internal workspace packages used by the root. The root's<script>:*steps then run one at a time inpackage.jsonorder before the remaining workspace tasks. Forprodanddeploy, the root steps still precede every workspace task. Fordevandclean, they run alongside the workspaces. - Filtering —
--workspacekeeps 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.rootto"skip"to leave the root out of every run. - Nesting — A run started from inside the tree, or by a legacy
<script>:workspacesscript, does not add the root again.
Usage
Options
| Flag | Description |
|---|---|
-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-error | Continue independent tasks after a failure while blocking tasks that depend on it. |
-d, --dry-run | Validate and print the expanded task plan without running package scripts. |
-x, --exclude-workspace <name…> | Exclude package names or configured workspace paths. |
-f, --force | Bypass 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
| Field | Description |
|---|---|
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. |
{
"settings": {
"runWorkspaces": {
"concurrency": {
"build": 2,
"check": 2,
"deploy": 2
}
}
}
}
Examples
nova utility run-workspaces check --concurrency 2
nova utility run-workspaces build \
--concurrency 2 \
--workspace @example/api @example/web
nova utility run-workspaces clean \
--dry-run \
--exclude-workspace @example/container
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.
{
"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
packageManagerto an exact npm, pnpm, or Yarn descriptor. - Workspace name drift — Keep each
nova.config.jsonworkspace name identical to its package'spackage.jsonname. - 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.