npm workspaces let one repository hold several packages that npm installs together. Declare the folders in a workspaces array in the root package.json, run npm install once at the root, and use the workspace flag to target one package or the workspaces flag to target all of them.
Declare the workspaces
In the root package.json:
{
"name": "my-monorepo",
"workspaces": ["packages/a", "packages/b"]
}
The npm documentation shows that a path in this list makes that folder a workspace. You can also create one with npm init -w ./packages/a, which makes the folder and package.json if needed and adds the path to the root file.
What install does
Running npm install from the root symlinks each workspace into the root node_modules. For packages/a you get node_modules/a pointing to ../packages/a. Code in package b can then require a by its package name, without publishing a first.
That is convenient and also a thing to understand: the name a resolves to your local folder, not to a registry package. Keep workspace names unique and, if you publish them, scoped.
Add a dependency to one package
npm install abbrev -w a
The change lands in packages/a/package.json. Other commands, such as uninstall and ci, also respect the workspace setting.
Run a script
| Goal | Command |
|---|---|
| One package | npm run test --workspace=a |
| Two packages | npm run test --workspace=a --workspace=b |
| Every package under a folder | npm run test --workspace=packages |
| All packages | npm run test --workspaces |
| All, skipping packages without the script | npm run test --workspaces --if-present |
You can also change into the package folder and run npm run test there. With the workspaces flag, commands run in the order paths appear in your workspaces array, so put shared libraries first if builds depend on them.
Review habits for a workspace repo
Each package has its own package.json, so a pull request that adds a dependency to one package is easy to miss in a wide diff. Add a review rule for every package.json and for the single root lockfile. Our post on code owners for dependency manifests shows one way.
Use npm ci in CI, which installs exactly what the lockfile says. See npm ci vs npm install for supply chain safety.
Gaps to check yourself
The npm workspaces page does not cover how npm places shared dependencies in node_modules. If your code depends on a package that only a sibling declared, test it in a clean install before assuming it will keep working.
Safeguard dependency and SBOM scanning can list the packages in each part of a repository and flag known vulnerabilities. You can try a free scan at gold.safeguard.sh/scan.
Quick check
How do I run a script in every workspace that defines it?
Use npm run test --workspaces --if-present, swapping in your script name. Packages without the script are skipped.
Do workspaces need a separate install per package?
No. One npm install at the root links them all. Use the workspace flag to add dependencies to a single package.
Sources
Last reviewed: 19 October 2026.