What Does Your postinstall Script Actually Do?
Paste your package.json. See every install-time script in your dependency tree, flagged and risk-scored against patterns from real 2026 supply chain attacks like Shai-Hulud. No install, no upload, nothing sent anywhere.
How Lifecycle Hook Scanner works
Paste one or more package.json contents
Paste your root package.json, or several package.json bodies from your dependency tree pasted one after another. The tool doesn't require an array or separators, it scans for balanced JSON objects.
JSON is parsed locally
Each pasted object is parsed entirely in your browser. For every package, the tool extracts its name, version, and any preinstall, install, or postinstall entry in its scripts object.
Each script is pattern-matched
Every found script is checked against a static rule set covering known attack indicators: encoded-payload execution, detached process spawning, remote scripts piped into a shell, raw-IP network calls, destructive filesystem commands, and inflated dependency-confusion version numbers.
Each hook gets a risk score
A script gets High if it matches a known-bad pattern, Medium for a weaker signal like a generic network call or inline eval, and Low if nothing suspicious matched, including a note when the package is a well-known legitimate user of install hooks (native modules, browser binary downloads).
Generate a --ignore-scripts allowlist
The Copy button builds a ready-to-use allowlist snippet (in the @lavamoat/allow-scripts config format) listing every package that scored Low, so you can run installs with scripts disabled by default and explicitly trust only what needs it.
What each risk score means
The script matched a pattern documented in real supply chain attacks: decoding and executing an encoded payload, spawning a detached background process, piping a remote script into a shell, calling out to a raw IP address, deleting a broad filesystem path, or using an inflated version number designed to win dependency-confusion resolution.
The script didn't match a known-bad pattern outright, but shows a weaker risk signal: a generic network call to an unrecognized domain, or inline JavaScript executed directly from the command line instead of a reviewable file.
No suspicious pattern was matched. This includes both a plain baseline finding (the script still runs automatically, which carries inherent risk even with no known-bad pattern present) and a stronger "known legitimate use" note when the package is a documented, common user of install hooks.
Input format reference
Lifecycle Hook Scanner looks for a scripts object with a preinstall, install, or postinstall entry inside any pasted JSON object. It accepts three input shapes:
A single package.json
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"postinstall": "node scripts/setup.js"
}
}A JSON array of several package.json objects
[
{ "name": "bcrypt", "version": "5.1.1", "scripts": { "install": "node-pre-gyp install --fallback-to-build" } },
{ "name": "some-dep", "version": "2.0.0", "scripts": { "postinstall": "node index.js" } }
]Several package.json bodies pasted back to back
{ "name": "my-app", "scripts": { "postinstall": "node scripts/setup.js" } }
{ "name": "sharp", "version": "0.33.4", "scripts": { "install": "node install/check" } }Packages with no scripts entry, or with a scripts object that contains no preinstall/install/postinstall key, are silently skipped since there is nothing to scan.
When to use Lifecycle Hook Scanner
| Scenario | What to paste |
|---|---|
| About to add a new npm package to your project | Run npm view <package> scripts, then paste the package's package.json before committing to the install |
| A new Shai-Hulud-family campaign is in the news | Your project's root package.json and any recently added dependencies' package.json files |
| Reviewing a PR that adds or bumps dependencies | The package.json of every new or changed dependency in the diff |
| Auditing an inherited or legacy project | As many dependency package.json files as you can gather, pasted back to back |
| Teaching a junior developer why --ignore-scripts matters | Their own project's package.json, then walk through any flagged results together |
| Setting up a CI allowlist for the first time | Your full dependency tree's package.json files, then copy the generated allowlist snippet |
Frequently Asked Questions
What is Lifecycle Hook Scanner and what does it check?
Lifecycle Hook Scanner is a browser-based tool that reads your package.json (or several pasted at once) and finds every preinstall, install, and postinstall script declared across your dependency tree. Each script gets a risk score (Low, Medium, or High) based on pattern matches drawn from documented 2026 npm supply chain campaigns, including the Shai-Hulud worm family, dependency-confusion attacks using inflated version numbers, and obfuscated payload droppers.
Everything runs entirely in your browser using pure pattern matching. No package is looked up on the npm registry, no data is sent to any server, and the tool works offline once the page loads.
How is Lifecycle Hook Scanner different from DepScan?
| Lifecycle Hook Scanner | DepScan | |
|---|---|---|
| Checks install-time scripts | Yes, with risk scoring | No |
| Checks CVEs | No | Yes (via OSV.dev) |
| Checks outdated/deprecated versions | No | Yes |
| Makes network requests | No, fully offline | Yes (npm registry, OSV.dev) |
| Best for | Auditing what a package runs on install | Auditing what a package's known issues are |
The two tools check different attack surfaces. DepScan tells you whether a dependency is outdated, deprecated, or has a filed CVE. Lifecycle Hook Scanner tells you whether a dependency runs code automatically at install time, and whether that code matches patterns seen in real postinstall-hook attacks. Run both for a fuller picture: a package can be fully up to date and CVE-free while still shipping a malicious postinstall script, since a fresh malicious publish has no CVE filed against it yet.
Is my package.json sent to DevEncyclopedia's servers?
No. Lifecycle Hook Scanner runs 100% client-side. The JSON you paste is parsed and pattern-matched entirely in your browser using JavaScript. There is no backend, no API call, and no network request of any kind, unlike tools that look packages up against a registry. Nothing you paste ever leaves your machine.
How do I check my full dependency tree, not just my root package.json?
Paste each dependency's package.json one after another into the same box. The tool scans for balanced JSON objects, so you don't need to wrap them in an array or add separators between them. A quick way to gather them locally:
find node_modules -maxdepth 2 -name "package.json" -exec cat {} \; > all-packages.txtPaste the contents of all-packages.txt directly into the scanner. Every package.json in that file that declares a preinstall, install, or postinstall script will be picked up and scored, even without valid JSON syntax joining them together.
A package is flagged "Low" with a "known legitimate use" note. Is it safe?
That label means the package name matches a well-known list of packages that commonly use install hooks for a documented, benign reason, native module compilation (bcrypt, sharp, better-sqlite3) or browser binary downloads (Puppeteer, Playwright), and its script didn't match any suspicious pattern.
The scanner found zero install hooks. Does that mean my project is safe?
It means none of the package.json content you pasted declares a preinstall, install, or postinstall script, which removes one specific attack surface (lifecycle hook abuse) from consideration for those packages. It says nothing about other risks: typosquatting, malicious code inside the package's normal runtime files, or compromised transitive dependencies you didn't paste in.
Lifecycle Hook Scanner is a narrow, focused check. Pair it with a broader tool like DepScan for CVEs and outdated versions, and read the linked guide below for the full defense checklist.