
πΈοΈ Dependency Graph
A Dart command-line tool that shows who imports whom in a Dart package or a pub workspace β and which pub libraries it pulls in β as one interactive HTML page.

π Features
- π¦ Packages graph β one node per package, edges weighted by the number of directives
- π Package graph β its files boxed by folder, every neighbour package as one node
- π External libraries β every library
pubspec.lockdownloaded, with its version and who imports it - π΄ Packages that depend on each other are marked red
- π§² Live physics, Obsidian-style β drag a node and its neighbours follow
- ποΈ Adjustable forces β center, repel, link force, link distance, damping
- π Light and dark theme, following the system
π Installation
In a project (as dev dependency)
dart pub add -d dependency_graph
Or manually in pubspec.yaml:
dev_dependencies:
dependency_graph: ^0.4.0
Globally
dart pub global activate dependency_graph
π Usage
From a project that has it as a dev dependency:
dart run dependency_graph [root] [out.html]
Installed globally, from anywhere:
dependency_graph [root] [out.html]
Both take the same arguments and write the same page. Both arguments are optional:
rootis the folder of the project to scan, the one withpubspec.yaml: a single package or a workspace root.out.htmlis where to write the page.
# the current folder, page in ./build/dependency_graph/index.html
dart run dependency_graph
# another project, page in its build/dependency_graph/index.html
dart run dependency_graph ../my_app
# another project, page in graph.html in the current folder
dart run dependency_graph ../my_app graph.html
Arguments
| Argument | Description | Default |
|---|---|---|
root |
The package or workspace root | . |
out.html |
Where to write the page | <root>/build/dependency_graph/index.html |
-h, --help |
Print usage information |
Run dart pub get first, so pubspec.lock lists the external libraries. The page loads Cytoscape.js and d3 from a CDN, so it needs a network connection to open.
Configuration
Defaults can be changed in the root pubspec.yaml (the workspace root, or the package itself) under a dependency_graph: key. Every key is optional; the values below are the built-in defaults:
dependency_graph:
output: build/dependency_graph/index.html # relative to root; the out.html argument wins
physics_nodes: 600 # views above this many nodes keep still
forces: # the Reset baseline of the Forces panel
center: 0.02
repel: 1
link: 0.15
distance: 1
damping: 0.5
| Key | Description | Default | Min | Max |
|---|---|---|---|---|
output |
Where to write the page, relative to root |
build/dependency_graph/index.html |
β | β |
physics_nodes |
Views with more nodes than this keep still until physics is ticked | 600 |
0 |
β |
forces.center |
Pull towards the middle | 0.02 |
0 |
0.2 |
forces.repel |
How hard nodes push each other away | 1 |
0 |
3 |
forces.link |
Stiffness of the edges | 0.15 |
0 |
1 |
forces.distance |
Length of the edges | 1 |
0.2 |
3 |
forces.damping |
How fast the motion settles | 0.5 |
0.05 |
0.9 |
The forces ranges are the ranges of the Forces sliders.
Forces changed in the browser are kept in localStorage and win over the pubspec; Reset goes back to the pubspec values.
π― Views
Packages
One node per package, sized by its file count. Packages are coloured by the folder they sit in (apps, packages), split by a name prefix several packages share (feature_*). Tick external libraries to add the pub packages the code imports.
What it shows:
- π How many directives go from one package to another
- π΄ Packages that import each other
- π Every downloaded library, and the ones the code actually imports
Package
Double-click a package to open it: its files boxed by folder, and each package it touches as one node.

What it shows:
- β‘οΈ What the package depends on, and how much
- β¬ οΈ Who uses it
- π Which external libraries it imports
Click any node to highlight its edges: outgoing in orange, incoming in blue. Dashed edges are export, dotted are part. Tick hide links in its panel to switch its edges off in every view β handy for a package everything imports.
Forces
Open the Forces panel to tune the physics. The settings are kept in the browser; Reset brings back the defaults from pubspec.yaml (see Configuration).

| Slider | Effect |
|---|---|
| Center | Pull towards the middle |
| Repel | How hard nodes push each other away |
| Link force | Stiffness of the edges β lower is softer |
| Link distance | Length of the edges |
| Damping | How fast the motion settles |
Views above 600 nodes keep still; untick and tick physics to run it there anyway.
π‘ As a library
import 'dart:io';
import 'package:dependency_graph/dependency_graph.dart';
void main() {
final graph = scan(Directory('.'));
File('graph.html').writeAsStringSync(render(graph));
}
scan returns plain data β packages, files, edges, external, uses β if you'd rather feed it to something else.