Why Visualizing Your Dependency Graph Matters
Every modern JavaScript project pulls in dozens — sometimes hundreds — of packages. Without a clear picture of how those packages relate to each other, you're flying blind. A dependency graph turns that invisible web of relationships into something you can actually reason about, spot problems in, and optimize.
In this guide, you'll learn how to generate and explore the dependency graph for any npm-based project, from a simple app to a complex monorepo.
Prerequisites
- Node.js (v16 or later) and npm installed
- A project with a
package.jsonfile - Basic comfort with the terminal
Step 1: Use npm's Built-In List Command
The simplest starting point is npm ls, which is built right into npm. Run it from your project root:
npm ls
This prints a tree of your direct dependencies and their sub-dependencies. To see the full depth of the tree (not just the top two levels), use:
npm ls --all
You can also filter to a specific package to see why it's in your tree:
npm ls lodash
Step 2: Export the Dependency Tree as JSON
For programmatic analysis or feeding into a visualization tool, export the tree as JSON:
npm ls --all --json > deps.json
The resulting file contains a nested object where each package lists its own dependencies, making it easy to parse and render as a graph.
Step 3: Use a Visual Tool
CLI output is useful, but a visual graph is far easier to navigate. Several tools can render npm dependency trees as interactive graphs:
- npmgraph.js.org — Paste a package name or upload a
package.jsonto get an interactive graph in the browser. No install required. - Madge — An npm package that generates dependency graphs for JavaScript/TypeScript modules. Supports Graphviz and JSON output.
- Depcruise (dependency-cruiser) — Analyzes module dependencies and can output SVG, HTML, or dot format graphs.
Step 4: Install and Run Madge
To visualize module-level dependencies (not just package-level), Madge is a great choice:
npm install -g madge
madge --image graph.svg src/index.js
This generates a graph.svg file showing how your source files depend on each other. You'll need Graphviz installed for image output.
Step 5: Interpreting the Graph
Once you have your graph, here's what to look for:
- Deep chains — Long chains of transitive dependencies increase your attack surface and bundle size.
- Duplicate packages — The same package appearing multiple times at different versions signals potential conflicts.
- Circular dependencies — Cycles can cause subtle runtime bugs and make refactoring harder.
- Orphaned packages — Packages listed in
package.jsonthat nothing actually imports are dead weight.
Next Steps
Visualizing your dependency graph is just the beginning. Once you can see the shape of your dependencies, you can start making informed decisions: removing unused packages, consolidating duplicate dependencies, and auditing for security vulnerabilities. Check out our guides on dependency auditing and version pinning to go deeper.