Package Manager
3va install axios --allow-net=registry.npmjs.org # from npm
3va install react@18 --allow-net=registry.npmjs.org # specific version
3va install @std/path --allow-net=jsr.io # from JSR
3va reinstall axios --allow-net=registry.npmjs.org # force-reinstall one package
3va update --allow-net=registry.npmjs.org # update to latest versionsPost-install scripts are blocked by default
preinstall, install, and postinstall lifecycle scripts are not
executed by 3va install unless the project names the package in its
own package.json:
{ "3va": { "onlyBuiltDependencies": ["esbuild"] } }pnpm’s onlyBuiltDependencies and Bun’s trustedDependencies are read
as well. Being on the list is not enough on its own:
- A script that is a single JavaScript file (
node install.js) runs inside 3va’s sandbox, with only the permissions your project’spackage.jsongrants that package under"3va".permissions.<pkg>. Whatever the dependency declares in its ownpackage.jsonis ignored. - A shell command (
prebuild-install || node-gyp rebuild) is refused, even for a listed package. 3va doesn’t pass a package-authored string to a shell.
3VA_ALLOW_SCRIPTS=1 no longer enables scripts: a process-wide
environment variable isn’t a decision anyone can review.
Trusting a package the scanner rejects
The malware scan grades packages by their contents, so tools whose job is to spawn compilers or evaluate code can be rejected. After reviewing one, pin the exact artifact:
{
"3va": {
"trusted": ["oxlint@1.85.0"],
"trustedIntegrity": { "oxlint@1.85.0": "sha512-…" }
}
}A versioned pin stops applying when the version changes, so an upgrade
is scanned again. trustedIntegrity also pins the bytes. A pin without a
version doesn’t override a failed scan: pin name@version.
Storage: global content-addressable dedup
Package storage uses the same model as pnpm: a package at version X is
stored once on disk (in a global store, relocatable via _3VA_STORE, default
~/.3va/store/), and multiple projects reference it while declaring their
own permissions independently — installing the same package in two projects
doesn’t double the disk usage, and doesn’t share one project’s granted
permissions with another.
3va install resolves all of package.json as one dependency graph, so a
transitive or peer range can’t replace the version a direct dependency asked
for, and two packages can’t race linking the same files.
It writes 3va-lock.json (sorted, stable between runs) and installs from it
without contacting the registry when the store already has every package.
Prerelease versions no longer satisfy plain ranges: >=5.0.0, * or
latest could resolve to a nightly build (7.1.0-dev…). A prerelease now
matches only when the range names a prerelease of the same
major.minor.patch, as in npm.
Audit
3va audit # malware scan + OSV CVE scan (24h cache)
3va audit --secrets # also scan for leaked credentials
3va audit --deny # exit non-zero on CRITICAL/HIGH findings or an incomplete scan
3va audit --json # machine-readable outputAudit runs in three phases:
- Malware scan — static analysis of
node_modulesfor known malicious patterns. - OSV CVE scan — queries
api.osv.devfor known vulnerabilities; results are cached 24 hours. - Secrets detection (opt-in via
--secrets) — 21 patterns covering AWS keys, GitHub/GitLab tokens, Stripe keys, Slack/SendGrid/Twilio keys, private certificates, JWT secrets, npm tokens, database connection strings, and generic passwords/API keys — scanned over the current project’s source files.
A lighter automatic malware scan already gates every downloaded tarball
during 3va install (using the same scanning engine as 3va audit,
aborting the install on high-severity findings). The full 3va audit
command — OSV/CVE scan and, opt-in, secrets detection — does not run
automatically; run it yourself after adding new dependencies. See
Roadmap for more on this distinction.
Supply-chain checks at install time
- Tarball integrity — SHA-256/SHA-512 verification. A package with a missing or unknown hash is refused, and a hash that doesn’t match the lockfile aborts the install.
3va ci— installs the lockfile’s versions, transitive packages included, and fails if any package is recorded without a hash.- Dependency-confusion protection —
.npmrc-pinned scopes resolve only against their private registry; public fallback is refused. A registry set in.npmrcmust be in--allow-net, and must use HTTPS unless it is on loopback. - Store verification —
3va store verifycompares every stored file with the digest recorded when it was stored. - Typosquatting detection — edit-distance check against an embedded
popular-packages list, warned during
install. - npm provenance (opt-in strict mode,
--require-provenance) — verifies the signing certificate against Sigstore’s Fulcio root and the Rekor transparency-log entry. The signer must be a build of the repository the package declares. The first verified signer of each package is recorded in.3va/provenance-signers.json(commit it); a later release signed by a different identity, or shipped without provenance, is refused.
For install-time performance (3va vs. npm vs. Bun, same package, same warm-cache condition), see the Comparison table — those CI-measured numbers are the only authoritative source; treat any other install-timing figure as stale.