Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

madge

pahen1.9mMIT8.0.0TypeScript support: definitely-typed

Create graphs from module dependencies.

ES6, ES7, AMD, RequireJS, require, module, circular, dependency, dependencies, graphviz, graph

readme

madge

Last version Donate

Madge is a developer tool for generating a visual graph of your module dependencies, finding circular dependencies, and giving you other useful info. Joel Kemp's awesome dependency-tree is used for extracting the dependency tree.

  • Works for JavaScript (AMD, CommonJS, and ES6 modules)
  • Also works for CSS preprocessors (Sass, Stylus, and Less)
  • NPM installed dependencies are excluded by default (can be enabled)
  • All core Node.js modules (assert, path, fs, etc) are excluded
  • Will traverse child dependencies automatically

Read the changelog for latest changes.

I've worked with Madge on my free time for the last couple of years and it's been a great experience. It started as an experiment but turned out to be a very useful tool for many developers. I have many ideas for the project and it would definitely be easier to dedicate more time to it with some financial support 🙏

Regardless of your contribution, thanks for your support!

Examples

Graph generated from madge's own code and dependencies.

graph

A graph with circular dependencies. Blue has dependencies, green has no dependencies, and red has circular dependencies.

graph-circular

See it in action

in-action

Installation

npm -g install madge

Graphviz (optional)

Graphviz is only required if you want to generate visual graphs (e.g. in SVG or DOT format).

Mac OS X

brew install graphviz || port install graphviz

Ubuntu

apt-get install graphviz

API

madge(path: string|array|object, config: object)

path is a single file or directory, or an array of files/directories to read. A predefined tree can also be passed in as an object.

config is optional and should be the configuration to use.

Returns a Promise resolved with the Madge instance object.

Functions

.obj()

Returns an Object with all dependencies.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.obj());
});

.warnings()

Returns an Object of warnings.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.warnings());
});

.circular()

Returns an Array of all modules that have circular dependencies.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.circular());
});

.circularGraph()

Returns an Object with only circular dependencies.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.circularGraph());
});

.depends()

Returns an Array of all modules that depend on a given module.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.depends('lib/log.js'));
});

.orphans()

Return an Array of all modules that no one is depending on.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.orphans());
});

.leaves()

Return an Array of all modules that have no dependencies.

const madge = require('madge');

madge('path/to/app.js').then((res) => {
    console.log(res.leaves());
});

.dot([circularOnly: boolean])

Returns a Promise resolved with a DOT representation of the module dependency graph. Set circularOnly to only include circular dependencies.

const madge = require('madge');

madge('path/to/app.js')
    .then((res) => res.dot())
    .then((output) => {
        console.log(output);
    });

.image(imagePath: string, [circularOnly: boolean])

Write the graph as an image to the given image path. Set circularOnly to only include circular dependencies. The image format to use is determined from the file extension. Returns a Promise resolved with a full path to the written image.

const madge = require('madge');

madge('path/to/app.js')
    .then((res) => res.image('path/to/image.svg'))
    .then((writtenImagePath) => {
        console.log('Image written to ' + writtenImagePath);
    });

.svg()

Return a Promise resolved with the XML SVG representation of the dependency graph as a Buffer.

const madge = require('madge');

madge('path/to/app.js')
    .then((res) => res.svg())
    .then((output) => {
        console.log(output.toString());
    });

Configuration

Property Type Default Description
baseDir String null Base directory to use instead of the default
includeNpm Boolean false If shallow NPM modules should be included
fileExtensions Array ['js'] Valid file extensions used to find files in directories
excludeRegExp Array false An array of RegExp for excluding modules
requireConfig String null RequireJS config for resolving aliased modules
webpackConfig String null Webpack config for resolving aliased modules
tsConfig String|Object null TypeScript config for resolving aliased modules - Either a path to a tsconfig file or an object containing the config
layout String dot Layout to use in the graph
rankdir String LR Sets the direction of the graph layout
fontName String Arial Font name to use in the graph
fontSize String 14px Font size to use in the graph
backgroundColor String #000000 Background color for the graph
nodeShape String box A string specifying the shape of a node in the graph
nodeStyle String rounded A string specifying the style of a node in the graph
nodeColor String #c6c5fe Default node color to use in the graph
noDependencyColor String #cfffac Color to use for nodes with no dependencies
cyclicNodeColor String #ff6c60 Color to use for circular dependencies
edgeColor String #757575 Edge color to use in the graph
graphVizOptions Object false Custom Graphviz options
graphVizPath String null Custom Graphviz path
detectiveOptions Object false Custom detective options for dependency-tree and precinct
dependencyFilter Function false Function called with a dependency filepath (exclude subtrees by returning false)

You can use configuration file either in .madgerc in your project or home folder or directly in package.json. Look here for alternative locations for the file.

.madgerc

{
  "fontSize": "10px",
  "graphVizOptions": {
    "G": {
      "rankdir": "LR"
    }
  }
}

package.json

{
  "name": "foo",
  "version": "0.0.1",
  ...
  "madge": {
    "fontSize": "10px",
    "graphVizOptions": {
      "G": {
        "rankdir": "LR"
      }
    }
  }
}

CLI

Examples

List dependencies from a single file

madge path/src/app.js

List dependencies from multiple files

madge path/src/foo.js path/src/bar.js

List dependencies from all *.js files found in a directory

madge path/src

List dependencies from multiple directories

madge path/src/foo path/src/bar

List dependencies from all *.js and *.jsx files found in a directory

madge --extensions js,jsx path/src

Finding circular dependencies

madge --circular path/src/app.js

Show modules that depends on a given module

madge --depends wheels.js path/src/app.js

Show modules that no one is depending on

madge --orphans path/src/

Show modules that have no dependencies

madge --leaves path/src/

Excluding modules

madge --exclude '^(foo|bar)\.js$' path/src/app.js

Save graph as a SVG image (requires Graphviz)

madge --image graph.svg path/src/app.js

Save graph with only circular dependencies

madge --circular --image graph.svg path/src/app.js

Save graph as a DOT file for further processing (requires Graphviz)

madge --dot path/src/app.js > graph.gv

Using pipe to transform tree (this example will uppercase all paths)

madge --json path/src/app.js | tr '[a-z]' '[A-Z]' | madge --stdin

Debugging

To enable debugging output if you encounter problems, run madge with the --debug option then throw the result in a gist when creating issues on GitHub.

madge --debug path/src/app.js

Running tests

npm install
npm test

Creating a release

npm run release

FAQ

Missing dependencies?

It could happen that the files you're not seeing have been skipped due to errors or that they can't be resolved. Run madge with the --warning option to see skipped files. If you need even more info run with the --debug option.

Using both Javascript and Typescript in your project?

Madge uses dependency-tree which uses filing-cabinet to resolve modules. However it requires configurations for each file type (js/jsx) and (ts/tsx). So provide both webpackConfig and tsConfig options to madge.

Using mixed import syntax in the same file?

Only one syntax is used by default. You can use both though if you're willing to take the degraded performance. Put this in your madge config to enable mixed imports.

For ES6 + CommonJS:

{
  "detectiveOptions": {
    "es6": {
      "mixedImports": true
    }
  }
}

For TypeScript + CommonJS:

{
  "detectiveOptions": {
    "ts": {
      "mixedImports": true
    }
  }
}

How to ignore import type statements in ES6 + Flow?

Put this in your madge config.

{
  "detectiveOptions": {
    "es6": {
      "skipTypeImports": true
    }
  }
}

How to ignore import in type annotations in TypeScript?

Put this in your madge config.

{
  "detectiveOptions": {
    "ts": {
      "skipTypeImports": true
    }
  }
}

How to ignore dynamic imports in Typescript?

Put this in your madge config.

{
  "detectiveOptions": {
    "ts": {
      "skipAsyncImports": true
    },
    "tsx": {
      "skipAsyncImports": true
    }
  }
}

Note: tsx is optional, use this when working with JSX.

Mixing TypesScript and Javascript imports?

Ensure you have this in your .tsconfig file.

{
  "compilerOptions": {
    "module": "commonjs",
    "allowJs": true
  }
}

What's the "Error: write EPIPE" when exporting graph to image?

Ensure you have installed Graphviz. If you're running Windows, note that Graphviz is not added to the PATH variable during install. You should add the folder of gvpr.exe (typically %Graphviz_folder%/bin) to the PATH variable manually.

How do I fix the "Graphviz not built with triangulation library" error when using sfdp layout?

Homebrew doesn't include GTS by default. Fix this by doing:

brew uninstall graphviz
brew install gts
brew install graphviz

The image produced by madge is very hard to read, what's wrong?

Try running madge with a different layout, here's a list of the ones you can try:

  • dot "hierarchical" or layered drawings of directed graphs. This is the default tool to use if edges have directionality.

  • neato "spring model'' layouts. This is the default tool to use if the graph is not too large (about 100 nodes) and you don't know anything else about it. Neato attempts to minimize a global energy function, which is equivalent to statistical multi-dimensional scaling.

  • fdp "spring model'' layouts similar to those of neato, but does this by reducing forces rather than working with energy.

  • sfdp multiscale version of fdp for the layout of large graphs.

  • twopi radial layouts, after Graham Wills 97. Nodes are placed on concentric circles depending their distance from a given root node.

  • circo circular layout, after Six and Tollis 99, Kauffman and Wiese 02. This is suitable for certain diagrams of multiple cyclic structures, such as certain telecommunications networks.

Credits

Contributors

This project exists thanks to all the people who contribute. Contributors

Donations ❤️

Thanks to the awesome people below for making donations! 🙏Donate

BeroBurny

olejorgenb

RxDB

Ziriax

landonalder

License

MIT License

changelog

Changelog

All notable changes to this project will be documented in this file. Dates are displayed in UTC.

v8.0.0

v7.0.0

8 April 2024

  • devDeps: release-it@^15.6.0->^16.2.1 #393
  • ci: Run build & test scripts on GitHub Actions #394
  • chore: bump and align dependencies; dedupe typescript #379
  • Adding option to not print the circular file count #387
  • Update README, explaining to how ignore typed imports on .tsx files #389
  • docs: update README to include ignore dynamic imports FAQ #360
  • docs: fix donate anchor #362
  • Release 6.1.0 #378
  • chore: check in package-lock.json 2137846
  • devDeps: release-it@^16.1.5->^16.2.1 1bcdc12
  • ci: add build/test workflow for GitHub Actions fa34634

v6.1.0

4 June 2023

  • constrain and bump typescript versions #376
  • Disable spinner when running in CI #356
  • Remove deploy to NPM from Travis build #354
  • feat: support for rankdir in CLI #311
  • Move typescript to peer dependencies #350
  • Release 6.0.0 #352
  • Release 6.1.0 66bb0c3
  • install and use ci-info c35da47
  • remove ci-info and change isEnabled setting a771115

v6.0.0

29 January 2023

  • Handle collect tsconfig's extends fileds #349
  • Update packages detective-* to latest #348
  • chore: bump 'detective-typescript' package to allow newer TS versions #321
  • Replace to ts-graphviz package #341
  • chore: bump detective-postcss to v6 #319
  • Drop support Node.js EOL versions(<14) #342
  • handle collect tsconfig's extends fileds #323
  • Changed to depend on the ts-graphviz package 9b9ae87
  • Release 6.0.0 2aa75b2
  • update packages detective-* to latest 60b6557

v5.0.2

27 January 2023

  • Add NPM task and docs for creating a release #346
  • Fix broken link to Travis in README #345
  • docs: fix subtrees typo in README #325
  • minor typo in README.md #300
  • Release 5.0.2 614d44d
  • minor typos in README.md edc27c8
  • minor type in README.md 9f5514c

v5.0.1

23 June 2021

  • Fix issue with command line options stopped working 512c2cb
  • Update README 8e98136

v5.0.0

22 June 2021

  • Improve Graphviz support detection #274
  • Update list of donations aa49a0a
  • Update deps 820c9b8

v4.0.2

8 March 2021

  • Bump detective-typescript e6985d2

v4.0.1

5 March 2021

  • Fix potential command injection vulnerability da5cbc9

v4.0.0

5 January 2021

  • Upgrade dependencies & raise minimum Node.js version #269
  • Upgrade core dependencies fe8a186
  • Upgrade commander to version 6 5ca410c
  • Require Node.js 10.13 eee3dc0

v3.12.0

2 November 2020

  • Remove pify again #264
  • Update ora to version 5 #262
  • Replace pify with util.promisify #263
  • Update README e4be868
  • Bump dependency-tree to 7.2.2 0eaccb7

v3.11.0

1 October 2020

  • Add support for combining --circular and --dot d2ce3f7

v3.10.0

14 September 2020

  • Add support for combining --image and --circular 7a4bd3b

v3.9.2

16 June 2020

v3.9.1

8 June 2020

  • chore: significant speedup by skipping filing-cabinet ts-config parsing #237
  • Clarification for mixed projects (with JS and TS) #246

v3.9.0

7 May 2020

  • Remove info about Patreon and Open Collective a57eeff
  • Update list of backers 545be08
  • Update dependencies ffa4fdd

v3.8.0

9 March 2020

  • Add leaves option to show modules that do not have dependencies 97ed27f
  • Update README 9c1f7d2
  • Updated list of donations 899f15f

v3.7.0

30 January 2020

v3.6.0

11 November 2019

  • Add test for TypeScript with mixed import syntax 50c1c10
  • Update deps f1125d0

v3.5.1

7 November 2019

  • Add funding to package.json 8ee9126

v3.5.0

28 October 2019

  • Add an .svg public method to the API #171
  • Respect graphVizOptions in DOT output 4edf82a
  • Added credits to README 9287c3c
  • Add .svg() in API to export the svg as a Buffer d01f6f3

v3.4.4

12 February 2019

  • [Fixes #203] Exclude test folder from npm registry #205
  • Merge pull request #205 from SethDavenport/chore(exclude-test-folder-from-npm) #203
  • Add NPM releasing from Travis 97f060b
  • Exclude test folder from npm registry 41f94f2

v3.4.3

17 January 2019

  • Add link to my Patreon page in README 9ee722a
  • Add info about --orphans to CLI docs 925c57e
  • Bump dependency-tree c2ce2ac

v3.4.2

10 January 2019

  • Eslint should not be a dev dependency 3165988

v3.4.1

10 January 2019

  • Update eslint (peer dependency for typescript-eslint-parser) 2e6643a

v3.4.0

7 January 2019

  • Support .tsx files and specifying a tsconfig #193
  • README: improve instructions related to Graphviz #183

v3.3.0

31 October 2018

  • Update dependencies & test on Node.js 10 #176
  • Add --no-spinner option b1ad3eb
  • Update dependencies 9b1293e
  • Update dev dependencies 2260b61

v3.2.0

26 June 2018

  • Plot nodes as boxes #165
  • Document new graph settings c6e742f
  • aesthetic changes: plot rounded boxes, prefer left to right. 7a7ed8c
  • fix incorrect hex. 5 -> 6 digits. e8e330c

v3.1.1

24 May 2018

v3.1.0

22 May 2018

  • Bind all dependencies to latest version #161
  • Update ora to version 2 #155
  • Remove mz as a production dependency. Instead use pify for promisifying. #154
  • Remove package-lock.json 8fd1859
  • Bind all dependencies to latest version, It fixes security issue in rc => deep-extend library. And added .idea project files to gitignore 147d431
  • Use caret ranges for all dependencies b0e334a

v3.0.1

5 February 2018

  • Fix broken link #149
  • Update deps 3ba103c
  • Fix issue with short CLI options not working properly f73704d

v3.0.0

22 January 2018

  • chore: upgrade dependency-tree to 6.0.0 to address warning #147
  • Update dev-dependencies #144
  • Use caret ranges for all dependencies #141
  • Update chalk to 2.3.0 #140
  • Updates dependencies (not dev-dependencies) #134
  • deps: Update debug to fix security issue #130
  • Regenerate package-lock.json 5d26187
  • dependency-tree@5.11.1 c35174c
  • Updat eslint to 4.13.0 and @aptoma/eslint-config to 7.0.1. b184021

v2.2.0

29 August 2017

v2.1.0

26 August 2017

v2.0.0

15 July 2017

  • Add —-orphans to show modules that no one is depending on #121
  • Fix typo #119
  • fix typo in .image() example #113
  • Always include file extension b6cac48
  • Fix bug with --extensions not working fc4acce
  • Support for Less d2d4b96

v1.6.0

8 February 2017

  • Show CLI spinner with the currently processed file f57480a
  • Add support for dependencyFilter function eac8591
  • Add script for testing output e74df55

v1.5.0

13 January 2017

  • Tweak output colors and error messages 60d59a6
  • Support running —circular with —-warning b8a0371
  • Update changelog fa7cc99

v1.4.6

9 January 2017

v1.4.5

7 January 2017

  • Keep file extension in module paths until we output the graph bd980cf
  • Update changelog 0492763

v1.4.4

4 January 2017

  • Add tests for resolving using webpack resolve.root 8452575
  • Update changelog 13648c7
  • Bump dependencies c9b1795

v1.4.3

12 October 2016

  • Fix bug with CLI —-require-config and --webpack-config not working 386d710
  • Update changelog cc4cb9e
  • Update changelog 97ba4c2

v1.4.2

6 October 2016

  • Rename —-show-skipped to —-warning a2d7c99

v1.4.1

6 October 2016

  • Don’t show warnings about skipped files by default 2cfa8d7

v1.4.0

6 October 2016

  • Show skipped files as warnings (disable with —-no-warning) #108
  • Update changelog 4cb2c4c

v1.3.2

3 October 2016

v1.3.1

1 October 2016

  • Allow to pass options to detectives #105
  • Bump dependency-tree to 5.7.0 d5c5de2

v1.3.0

6 September 2016

  • Improve performance on large codebase #104
  • Cache paths when converting tree for better performance fc67d00
  • Rename commonjs to cjs 8c56037
  • Remove unnecessary mapping of CLI args to config 93f19da

v1.2.0

1 September 2016

  • Add option —-stdin for piping predefined tree #103
  • Cleanup in tests 75dce71
  • Add missing test file 1ce0c01

v1.1.0

23 August 2016

  • Fix failing tests on Windows #98
  • Support for setting custom GraphViz options. Fixes #94 #94
  • Replace parsers with dependency-tree module 4be7db2
  • Use promises in API dbad4b6
  • Move tree generation to tree.js and add support folders 07a36ed

v1.0.0

19 August 2016

  • Version 1.0 #96

0.6.0

6 July 2016

0.5.5

3 July 2016

  • Fix matching absolute path #80
  • Support for es6 re-export syntax #91
  • AMD: Support files with embedded es6 #90
  • Improve readme circular return object #85
  • AMD: Support files with embedded es6 (#90) #84
  • Update code to pass ESLint rules. e0866d5
  • Remove react-tools since detective-es6 handles it now. b16f946
  • Move RequireJS specific code into amd.js 374d14c

0.5.4

13 June 2016

  • Bump detective-es6 for JSX and ES7 support #83
  • Don't use sudo to install the package #76
  • Correct CLI API for mainRequireModule #72
  • Bump detective-es6 for JSX and ES7 support #81 #61
  • Update status icons in README. 61429de
  • Update releasenotes. bf0e987
  • Bump to version 0.5.4 38c40ac

0.5.3

25 November 2015

  • Correct regex on CommonJS parser to detect a core module #71
  • Update README.md #70
  • List "es6" format in CLI help #66
  • Update releasenotes. 153235d
  • Bump to version 0.5.3 c00dd70
  • Correct regex on CJS parser to detect a core module 67a449a

0.5.2

16 October 2015

  • Update resolve to latest version. 21f787c
  • Bump to version 0.5.2 95faed0

0.5.1

15 October 2015

  • Update modules without any change to the code #65
  • Update all dependencies that will not break tests 65dcaf3
  • Update shrinkwrap 08ad266
  • Update releasenotes. 774f8d8

0.5.0

2 April 2015

  • Add 'comma separated' to -p usage for clarity #49
  • Add ES6 module support d5b0b60
  • Use npm-shrinkwrap instead of “npm shrinkwrap” to get consistent “resolved” fields. 082abcb
  • Cleanup after PL. a0d18ff

0.4.1

19 December 2014

  • Move method to proper file. f17a64a
  • Fix bug with absolute paths for module IDs in Windows. f64697a
  • Fix issues with absolute paths for modules IDs in Windows (all tests should now pass on Windows too). 9d524e4

0.4.0

19 December 2014

  • Update NPM shrinkwrap file. a23178c
  • Resolve the module IDs from the RequireJS paths-config properly. 41b54e2
  • Add support for JSX (React) and additional module paths. 858cd72

0.3.5

22 September 2014

  • IMPROVED: correctly detect circular dependencies when using path aliases (amd) 324b12b
  • Clear generated graph nodes on each render of a graph. 4bd4f00
  • Update releasenotes. d3df3ab

0.3.3

11 July 2014

  • Use path.resolve() to resolve relative paths in AMD dependencies instead of substack’s resolve lib since it works as expected (fixes #33). #33
  • Use amdetective infavor of parse.js for parsing AMD dependencies. 28e462d
  • Bump to version 0.3.3 dc35cf4

0.3.2

25 June 2014

  • convert spaces to tabs #30
  • Code cleanup. a235a00
  • Added failing test cases. d095e6a
  • Added code to pass the tests. b2276f5

0.3.1

3 June 2014

  • Apply exclude to RequireJS shim dependencies 02f3d28
  • Update releasenotes. 8dd4fb2
  • Bump to version 0.3.1 c41987b

0.3.0

26 May 2014

  • Lock down dependencies. 9dcc9b7
  • make pluggbable by adding onParseFile and onAddModule options that hook into these events with returned madge as the bound context ee04d41
  • Add some documentation about onParseFile and onAddModule options. dfa9c2b

0.2.0

18 April 2014

  • Update README.md #13
  • Using require() to get version number instead of version.js #11
  • Complete path in circular dependencies is now printed (and marked as red in image graphs). Fixes #4 #4
  • Fixed Node.js v0.8 issues. Closes #2 #2
  • first commit c730a52
  • Added support for CoffeeScript. Files with extension .coffee will automatically be compiled on-the-fly. 67fa4ec
  • Some code cleanup. d976942