Skip to Content

Monorepos

3va reads the workspaces field of the root package.json and installs all members with one command:

package.json
{ "name": "root", "private": true, "workspaces": ["packages/*"] }
3va install --allow-net=registry.npmjs.org
Installing 1 unique dep(s) into workspace root... ✓ Workspace install complete.

Linking local packages

Use the workspace: protocol (the pnpm and Yarn Berry convention):

packages/app/package.json
{ "dependencies": { "@ws/utils": "workspace:*", "ms": "^2.1.3" } }

3va then symlinks the member into packages/app/node_modules/@ws/utils, and it resolves:

$ cd packages/app && 3va run index.js --allow-read=../.. hi ws 60000

npm-style ranges link too. As with npm and Yarn Classic, "@ws/utils": "*" (or "^1.0.0") links the local member, and the member’s package.json is left as it is. So an npm or Yarn Classic monorepo installs without changes.

A workspace member always wins over the registry. If a member is called ms and another member depends on "ms": "*", 3va links the local package and never downloads ms from npm. That closes off dependency confusion inside the monorepo:

$ cd packages/app && 3va run index.js --allow-read=../.. LOCAL ms

While it links members, the install may print a false ✗ Version ms@^2.1.0 not found in registry for an external dependency of a member. The package is installed anyway (ms@2.1.3 in our test), and the command exits with code 0.

file: links aren’t supported either. A "file:../utils" dependency fails with Invalid version 'file:../utils'. Use workspace:*.

Workspace commands

3va workspace list # members, their paths and dependency counts 3va workspace run build # run a script in every member, in dependency order 3va workspace graph # dependency graph 3va workspace info # workspace + global store statistics

Things to keep in mind

  • Grant reads for the whole repo when a member imports a sibling: the symlink points outside the member’s own folder, so run it with --allow-read=../.. (or list both folders).
  • The symlinks are absolute paths. Moving the repo or building in a container with another path breaks them. Run 3va install again after moving.
  • Nx/Turborepo pipelines call your package manager and scripts. Point them at 3va commands only for the tasks 3va runs well (tests, scripts, backend).