npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

knotsjs

v1.0.0

Published

Untie the knots in your source code

Readme

knotsjs

Untie the knots in your source code ⛓

NPM version Dependency Status

Have you ever found yourself staring at a file someone else had written, wondering where it all starts ? You pick a place at random and look for a function that's calling it, and slowly you painstakingly retrace the path the code takes. What if you had a map 🗺 to follow that path ?

What knotsjs does

knotsjs will parse through the javascript code for you and identify all the functions and the links between them. Which function calls which others ? How many dependencies does this function have ? What about the transitive dependencies, how many functions do my dependencies call ? knotsjs can help you see them.

Why only functions ? Because the function is the atom of code. Ultimately, it's all functions calling other functions.

knotsjs is meant to be used with other programs to display the graph of function calls. For the moment, there is only one program: knots-electron which uses electron to run on any platform and display the graph as an interactive D3.js graph.

Screenshot from knots-electron

Of course feel free to use it in your own program ! See the Usage section below.

Installation

$ npm install --save knotsjs

Usage

var knots = require('knotsjs');

// Parse a file
knots.parse(file_path).then(function (dependencies) {
  console.log(dependencies);
});

// Parse multiple files
knots.parseFiles(file_paths).then(function (dependencies) {
  console.log(dependencies);
});

// Parse all .js files in a directory and all its subdirectories
knots.parseDirectory(directory_path).then(function (dependencies) {
  console.log(dependencies);
});

dependencies will be a javascript object with the following format:

{
  /**
   * A DirectedGraph created by jsgraph.
   * Allows you to make queries and walk the graph
   */
  directed_graph: DirectedGraph
  edges: Array, // An array of jsgraph edges
  /**
   * An object representing vertices (functions) ordered from functions least
   * depended upon (functions not called by anything) at level 0 to functions
   * most depended upon (functions called by many other functions) at the
   * highest level. It is used by knots-electron to dislay the visual representation.
   */
  ordered_vertices: {
    0: Array,
    1: Array,
    ...
  },
  /**
   * A map of all the jsgraph vertices (functions) found in the parsed source
   * code. The key is the function's name.
   */
  vertices: Object
}

Example of result

For example, say you have the following code:

function baz() {
  // nothing
}

function bar() {
  baz();
}

function foo() {
  bar();
}

After running knotsjs, you will have:

  • two edges (there are only two calls):
{
  edges: [
    {
      e: {
        source: "bar",
        target: "baz", // bar calls baz()
        u: "bar",
        v: "baz"
      },
      p: {
        type: null
      }
    },
    {
      e: {
        source: "foo",
        target: "bar", // source and target are added by knotsjs to make it easier to use
        u: "foo",
        v: "bar" // u and v are built-in jsgraph
      },
      p: {
        type: null // This becomes "reverse" for reverse edges present in circular dependencies.
      }
    }
  ]
}
  • three vertices (there are three functions):
{
  vertices: {
    "bar": {
      name: "bar",
      p: {
        max_dependency_depth: 1, // bar calls one function, which does not call another
        max_dependent_depth: 1, // bar is called by one function, which is itself never called
        sum_transitive_dependencies: 1,
        sum_transitive_dependents: 1
      },
      u: "bar"
    },
    "baz": {
      name: "baz", // name is added by knotsjs to make it easier to use
      p: {
        max_dependency_depth: 0, // baz calls nothing
        max_dependent_depth: 2, // bar is called by baz which is itself called by foo
        sum_transitive_dependencies: 0,
        sum_transitive_dependents: 2
      },
      u: "baz" // u is built-in jsgraph
    },
    "foo": {
      name: "foo",
      p: {
        max_dependency_depth: 2, // foo calls bar which calls baz
        max_dependent_depth: 0, // This property is used to build ordered_vertices (see below)
        sum_transitive_dependencies: 2,
        sum_transitive_dependents: 0
      },
      u: "foo"
    }
  }
}
  • and three levels in ordered_vertices:
{
  0: [
    {
      name: "foo", // foo is first because it's not called by anyone, it will go on top on the rendered graph
      p: {...},
      u: "foo"
    }
  ],
  1: [
    {
      name: "bar", // bar is second, it's called by one function and calls another one
      ...
    }
  ],
  2: [
    {
      name: "baz", // bar goes at the bottom, it has the highest max_dependent_depth
      ...
    }
  ]
}

This is what the rendered graph looks like:

Rendered graph

Limitations

  • As knotsjs is still a work in progress, it currently only supports Javascript ES5. I plan to support other versions of javascript (ES 2015, Typescript) but it's just a plan right now. I also want to provide a plugin system for other languages that I use, typically PHP. For those interested in Java, the inspiration for knotsjs has been Spoiklin Soice, written in Java.
  • The v1.0 of this program works best on single files. For example, when using it to parse its own source code, It did not link together the functions get and dependencies.get which is how it is used in other files.
  • It auto-ignores files with the extension *_test.js. I'll work on a way to provide options as parameter, including a glob to ignore, which will prove useful for projects that mix production and test files.

License

GPL v3 © Joris "Hyzual" MASSON