pnpm -r (--recursive): run a command in every workspace package
- tool
- pnpm
- command
- pnpm
- flag
- -r, --recursive
- default
- off (the command applies to the current package only)
pnpm -r run build (long form --recursive) runs build in every package of the workspace, in dependency order: packages that others depend on are built first. -r works with most commands: pnpm -r exec, pnpm -r test, pnpm -r update, pnpm -r add, pnpm -r publish. In a workspace the root package is excluded unless you add --include-workspace-root, and packages without the script are skipped.
Example workspace
app depends on lib, so lib builds first:
printf 'packages:\n - "packages/*"\n' > pnpm-workspace.yaml
echo '{ "name": "root", "private": true }' > package.json
mkdir -p packages/lib packages/app packages/docs
echo '{ "name": "lib", "version": "1.0.0", "scripts": { "build": "node -e \"console.log(1)\"" } }' > packages/lib/package.json
echo '{ "name": "app", "version": "1.0.0", "dependencies": { "lib": "workspace:*" }, "scripts": { "build": "node -e \"console.log(2)\"" } }' > packages/app/package.json
echo '{ "name": "docs", "version": "1.0.0" }' > packages/docs/package.json
npx --yes pnpm@9 install >/dev/null 2>&1
npx --yes pnpm@9 -r --workspace-concurrency=1 run build 2>&1 | grep -E "^(Scope|> |[0-9]$)" | sed -E 's/^(> [a-z]+@1\.0\.0 build) .*/\1/'Output
Scope: 3 of 4 workspace projects > lib@1.0.0 build > node -e "console.log(1)" 1 > app@1.0.0 build > node -e "console.log(2)" 2
Scope: 3 of 4 workspace projects means three of the four projects were selected: the root is the fourth and is excluded. docs has no build script and is skipped without an error. The sed only removes the absolute package path that pnpm prints after the script name.
Options used with -r
| Option | Effect |
|---|---|
| --filter PATTERN | Limit the packages (name, glob, directory, changed since a git ref) |
| --include-workspace-root | Also run in the root package |
| --workspace-concurrency=N | Run at most N packages at a time (default 4; 1 = sequential) |
| --parallel | Ignore order and concurrency, run everything at once (watch or dev servers) |
| --no-sort | Do not sort packages topologically |
| --stream | Print output immediately, prefixed with the package directory |
| --no-bail | Keep going when a package fails (default is to stop) |
| --report-summary | Write pnpm-exec-summary.json with the result of each package |
Typical commands
pnpm -r run build # build everything in order
pnpm -r --parallel run dev # start every dev server at once
pnpm -r exec rm -rf dist # run a shell command in each package
pnpm -r update typescript@latest # update a dependency everywhere it is used
pnpm --filter "./packages/**" -r test # combine with a filter-r versus --filter
-r alone selects every workspace package; --filter selects some of them and implies recursion. Use filters for large monorepos and CI jobs that only build what changed: see pnpm --filter.
Pitfalls
- Outside a workspace (no
pnpm-workspace.yaml),-rlooks for packages in subdirectories of the current folder, which can pick up straypackage.jsonfiles in fixtures or examples. pnpm add pkgat the root of a workspace fails with ERR_PNPM_ADDING_TO_ROOT;pnpm -r add pkgadds it to every package instead, which is rarely what you want for a single package.- A failing package stops the run; the error shows which directory failed. Use
--no-bailin reports where you want every result. - Long-running scripts (
dev,watch) never finish, so dependants would wait forever in topological mode: use--parallelfor them.
FAQ
Does pnpm -r run build include the workspace root?
No. In a workspace, -r runs in every package matched by pnpm-workspace.yaml but skips the root package. Add --include-workspace-root to run it there too.
In which order does pnpm -r run scripts?
In topological order: a package runs after the workspace packages it depends on. Independent packages run in parallel, up to --workspace-concurrency (4 by default). --no-sort ignores the order.
How do I run a script only in some packages?
Use --filter instead of, or together with, -r: pnpm --filter "./packages/**" run build or pnpm --filter api... run build for a package and its dependencies.