Skip to Content

From pnpm

3va’s own node_modules layout is pnpm-style: real files in a store, symlinks at the top level. So pnpm projects feel familiar.

Run on pnpm’s node_modules

pnpm install 3va run server.js --allow-read=./node_modules --allow-net=127.0.0.1

Tested with pnpm 12 and Express 4. pnpm’s symlinks into node_modules/.pnpm/ resolve fine, and --allow-read=./node_modules covers the symlink targets because they live under the same directory.

3va install on a pnpm project

  • 3va migrate converts pnpm-lock.yaml (v9, from pnpm 12 in our test): Would migrate pnpm-lock.yaml → 3va-lock.json (68 package(s)). After that, 3va install keeps the locked versions and 3va ci installs them exactly.
  • The layout is compatible: 3va puts packages in node_modules/.3va/<name>@<version>/ (pnpm uses .pnpm/). Delete node_modules when you switch between the two so they don’t mix.
  • workspace:* works in monorepos (see Monorepos).
  • pnpm.overrides wasn’t tested. npm-style overrides and Yarn-style resolutions do work.

Scanner false positives and packages with install scripts are covered in the Migration Guide.

Scripts

With a pnpm-lock.yaml present, 3va <script> delegates to pnpm (pnpm run <script>), outside the sandbox.

Things to keep in mind

  • --node-linker hoisted gives a flat, npm-style node_modules if a tool can’t handle symlinks: 3va install --node-linker hoisted.
  • .npmrc is read for registry=, scoped registries (@scope:registry=) and _authTokens, so private registries keep working. pnpm-specific settings (shamefully-hoist, public-hoist-pattern) have no effect.