Skip to Content
Examples05 · npm Packages

05 · npm Packages

Installs two real npm packages, is-odd (which depends on is-number) and ms, and uses them from app.js. The permissions the app needs are declared in package.json, so the run command has no flags.

Source: examples/05-packages

Install

cd examples/05-packages 3va install --allow-net=registry.npmjs.org
Resolving dependency graph... ! Possible typosquatting: 'ms' looks like 'ws' (edit distance 1). Verify the spelling before trusting this package. Downloading 1 package(s) in parallel... ✓ ms@2.1.3 Downloading 2 package(s) in parallel... ✓ is-number@6.0.0 ✓ is-odd@3.0.1 ✓ All dependencies installed.

Run

3va run app.js
=== Package Usage === Parity check (is-odd): isOdd(1) = true isOdd(2) = false isOdd(7) = true isOdd(10) = false isOdd(99) = true Durations (ms package): ms('2 days') = 172800000 ms ms('1.5h') = 5400000 ms ms(120000) = 2m ms(86400000) = 1d

How it works

package.json
{ "dependencies": { "is-odd": "^3.0.1", "ms": "^2.1.3" }, "3va": { "no-prompt": true, "permissions": { ".": { "allow-read": ["./node_modules/is-odd", "./node_modules/ms", "./node_modules/is-number"] } } } }
  • 3va install resolves the graph, downloads tarballs (cached under ~/.3va/store/<registry>/), and lays out node_modules pnpm-style: real files under node_modules/.3va/<name>@<version>/node_modules/<name>, with top-level symlinks (node_modules/ms -> .3va/ms@2.1.3/node_modules/ms). Lifecycle scripts (postinstall and friends) don’t run unless the package is listed in "3va".onlyBuiltDependencies (Package Manager).
  • require("is-odd") is a file read. Loading a package reads its files, so without a grant the run fails with Permission denied: --allow-read=…/node_modules/is-odd/index.js is required.
  • The "3va" key in package.json grants those reads to the app scope ("."). CLI flags are added on top of these grants; they can’t remove them. 3va run app.js --allow-read=./node_modules works too, but is broader.
  • "no-prompt": true means: never ask interactively, deny whatever isn’t granted.

Things to keep in mind

  • The installer needs its own network grant. Without --allow-net=registry.npmjs.org every download fails with Network access denied: --allow-net not specified.

  • Grant each package directory, not all of node_modules, when you can. Transitive dependencies need their own entry: is-number is listed because is-odd requires it.

  • The typosquatting warning is informational. ms is one letter away from ws, so 3va flags it. Read these warnings: they are cheap to check and expensive to ignore.

  • 3va audit re-scans what’s installed:

    Auditing 4 package(s) in node_modules/ ... ms@2.1.3 ✓ Clean is-number@6.0.0 ✓ Clean is-odd@3.0.1 ✓ Clean ✓ Heuristic scan complete. Nothing suspicious found.
  • The malware scanner errs on the side of blocking, so a legitimate package can be flagged (oxlint and some Expo packages are). Review it, then trust that exact version in package.json. The pin expires when the version changes:

    { "3va": { "trusted": ["oxlint@1.85.0"] } }

    --no-scan also exists, but it skips the scan for the whole install.

  • To go further (per-package scopes, deny-* exceptions, ${VAR} expansion), see Permissions and Package Manager.