NPM Scripts Runner Visualizer
Visualize pre/post hooks, cross-references, and execution order from your package.json
package.json
15 scripts
Click ▸ Execution on any card to trace what runs when you execute that script.
tscnpm run copy-assetseslint src/ --fixprettier --write src/vitest runts-node src/index.tsnode dist/index.jshusky installnpm run cleannpm run compressnpm run lintnpm run coveragerm -rf distcp -r public dist/gzip dist/*.jseslint src/vitest run --coverageYour package.json has 15 scripts — build, prebuild, postbuild, test, pretest, lint, deploy, and 8 more that chain each other with && and npm run. You run npm run deploy and 6 scripts execute in sequence, but you can’t figure out which one is failing because you don’t know the execution order. You need a visual dependency tree.
Why This Visualizer (Not the Package.json Generator)
PureDevTools has a Package.json Generator for building new package.json files. This tool visualizes the dependency tree of your existing npm scripts — it detects pre/post lifecycle hooks, traces npm run chains, and shows the complete execution order as a tree. Paste your package.json and see which scripts trigger which.
What Is This Tool?
The NPM Scripts Runner Visualizer parses your package.json and builds a visual dependency graph of your npm scripts. It detects pre/post lifecycle hooks, cross-script references via npm run, and command chaining — then shows you exactly what runs when you execute any script.
This is useful for understanding unfamiliar projects, documenting complex build pipelines, finding orphaned scripts, and debugging unexpected behaviour when npm test or npm run build seem to trigger more steps than expected.
How npm Scripts Work
Pre/Post Lifecycle Hooks
npm automatically runs a pre<name> script before <name> and a post<name> script after it. For example:
{
"scripts": {
"pretest": "npm run lint",
"test": "vitest run",
"posttest": "npm run coverage"
}
}
Running npm test executes pretest, then test, then posttest in sequence. You never need to call them manually — npm handles the ordering automatically.
This convention works for any script name: prebuild/build/postbuild, prestart/start/poststart, or any custom name like predeploy/deploy/postdeploy.
Cross-Script References
Scripts can call other scripts using npm run <name>:
{
"scripts": {
"clean": "rm -rf dist",
"build": "npm run clean && tsc"
}
}
Here build depends on clean. Running npm run build first removes the dist directory, then compiles TypeScript.
Command Chaining
A single script command can chain multiple sub-commands using shell operators:
| Operator | Behaviour |
|---|---|
&& | Run next command only if previous succeeded (exit code 0) |
|| | Run next command only if previous failed (non-zero exit code) |
; | Run next command regardless of the previous result |
{
"scripts": {
"ci": "npm run lint && npm run test && npm run build"
}
}
How to Use This Tool
1. Paste Your package.json
Paste either the full package.json content or just the scripts object into the input area. Both formats are accepted:
Full package.json:
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"build": "tsc"
}
}
Scripts object only:
{
"build": "tsc",
"test": "vitest"
}
2. Read the Script Cards
Each script appears as a card with:
- A type badge showing its role (ENTRY, HOOK, or REF)
- The command it runs, with chained parts displayed on separate lines
- A relationships section showing pre-hooks, post-hooks, scripts it calls, and scripts that call it
3. Explore Execution Order
Click the ▸ Execution button on any script card to see the full sequence of steps that run when you execute npm run <name>. The panel shows the pre-hook, main script, and post-hook with their commands.
4. Copy Commands
Each script card has a copy button for its command. The execution order panel has a copy button for the full run sequence. The summary bar has a copy button for the entire tree as plain text.
Script Types
| Badge | Meaning |
|---|---|
| ENTRY | Not called by any other script and not a pre/post hook. These are your top-level commands. |
| HOOK | A pre<name> or post<name> script that runs automatically before or after another script. |
| REF | Called by at least one other script via npm run. Acts as a helper or utility script. |
Example: Full Build Pipeline
{
"scripts": {
"clean": "rm -rf dist",
"prebuild": "npm run clean",
"build": "tsc && npm run copy-assets",
"copy-assets": "cp -r public dist/",
"postbuild": "npm run compress",
"compress": "gzip dist/*.js",
"pretest": "npm run lint",
"test": "vitest run",
"posttest": "npm run coverage",
"lint": "eslint src/",
"coverage": "vitest run --coverage"
}
}
Running npm run build executes:
prebuild(pre-hook) → callscleanbuild(main) → runstsc, then callscopy-assetspostbuild(post-hook) → callscompress
The visualizer surfaces this entire chain from a single click.
Frequently Asked Questions
Is my package.json sent to any server?
No. All parsing and analysis happens entirely in your browser using JavaScript. Your package.json content never leaves your device.
Why does my script show as REF instead of ENTRY?
A script is marked REF when at least one other script references it via npm run <name>. This means it’s used as a dependency of another script rather than being called directly by users. You can still run it manually with npm run <name>.
What if a script name starts with “pre” but isn’t a hook?
The tool only flags a script as a lifecycle hook if a corresponding base script exists. For example, prettier would not be flagged as a hook because there is no ttier script. pretest IS flagged as a hook because test exists.
Does this handle scripts that call themselves?
The tool detects self-references (a script that calls itself via npm run) and skips them to avoid circular dependency display. Direct recursion is unusual in npm scripts and usually indicates a configuration error.
Can I use this with Yarn or pnpm?
Yes. The package.json scripts format is identical across npm, Yarn, pnpm, and Bun. The yarn run or pnpm run commands work the same way; just paste your package.json regardless of which package manager you use.
Why are some npm run references not showing as dependencies?
Only references to scripts that exist in the same package.json are shown as edges. References to scripts in other packages or workspace packages are not resolved (they appear as plain text in the command).