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.json file
  • 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.json to 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:

  1. Deep chains — Long chains of transitive dependencies increase your attack surface and bundle size.
  2. Duplicate packages — The same package appearing multiple times at different versions signals potential conflicts.
  3. Circular dependencies — Cycles can cause subtle runtime bugs and make refactoring harder.
  4. Orphaned packages — Packages listed in package.json that 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.