See what your lockfile's install scripts actually run, then generate the allowlist to match.
Drop in a lockfile and get the exact command behind every preinstall, install and postinstall script in your dependency tree, each classified with a plain reason. Then copy out a ready-to-commit allowlist for npm, pnpm, Yarn or Bun.
Everything runs in your browser. The lockfile is never uploaded.
npm v12 blocks install scripts by default. pnpm has done so since v10, and Bun always has. Every Node project now needs an allowlist.
The tooling that ships with each package manager tells you a dependency has a script. It does not tell you what that script does or whether you need it, so people click through npm approve-scripts and pnpm approve-builds prompts blind. This fills that gap.
- Reads
package-lock.json(v1/v2/v3),pnpm-lock.yaml(v5/v6/v9),yarn.lock(Classic and Berry) andbun.lock - Resolves every package against the npm registry and keeps the ones with an install-lifecycle script
- Shows the exact command, plus a classification and the reasoning behind it
- Marks packages that cannot install on your target platform, so you never allow a build you do not run
- Generates the config for all four package managers, with every decision overridable
| Verdict | Meaning | Default |
|---|---|---|
| Suspicious | Shell piping, eval, base64 payloads, credential paths |
Review |
| Opaque | Runs a script file whose contents the manifest does not reveal | Review |
| Native build | node-gyp, node-gyp-build, prebuild-install, cmake-js, … |
Allow |
| Binary download | Fetches a platform binary the package cannot run without | Allow |
| No-op | Wrapped in a catch-all that swallows every error, or literally empty | Deny |
The no-op rule is the interesting one. core-js and es5-ext both ship
node -e "try{require('./postinstall')}catch(e){}", a funding notice that by
construction cannot fail an install. Anything shaped like that is safe to deny.
Each was verified against the tool that consumes it, not against documentation alone.
| Manager | File | Field |
|---|---|---|
| npm v12 | package.json |
allowScripts (pinned on allow) |
| pnpm | pnpm-workspace.yaml |
allowBuilds |
| Yarn | package.json |
dependenciesMeta.<pkg>.built |
| Bun | package.json |
trustedDependencies |
registry.npmjs.org serves per-version documents with Access-Control-Allow-Origin: *, so there is no backend. Only package names and versions are requested, which is exactly what npm install already does. Your lockfile stays in the tab.
It reads the scripts field of the published manifest. It does not download or execute tarballs, so a script file's contents stay invisible, and a hostile package can still act through prepare or through a dependency of its own. Treat it as a migration and decision aid, not a malware scanner.
Ships in English, 简体中文, हिन्दी, Español, Português (Brasil), 日本語, Deutsch, Français, Русский and 한국어. Each locale is prerendered to its own URL with hreflang and a sitemap, so the translations are indexable rather than client-only.
bun install
bun run dev # http://localhost:5173Quality gate, in order: typecheck, lint, unit tests, end-to-end tests.
bun run testIndividually:
bun run check # svelte-check
bun run lint # prettier --check && eslint
bun run test:unit # vitest, 86 tests
bun run test:e2e # playwright, 52 tests across desktop and mobileThe E2E suite mocks registry.npmjs.org via e2e/registry-mock.ts with real command strings copied from the published manifests, so it is deterministic and runs offline.
Set PUBLIC_SITE_URL at build time so canonical and hreflang URLs point at your deployment.
SvelteKit 2 with Svelte 5 runes, TypeScript, Tailwind v4, adapter-static. The build is a folder of static files, deployable to any host that can serve HTTPS.
src/lib/
lockfile/ parsers for the four formats, normalising to ResolvedPackage[]
registry/ concurrent client for registry.npmjs.org
analysis/ classification, platform constraints, result assembly
output/ allowlist generators per package manager
i18n/ message contract, locales, key resolution
components/ UI
The domain layer emits message keys rather than English prose, so every verdict, note and diagnostic is translatable and the locale files are checked against a single Messages interface at compile time.
MIT