Package Exports
- skott
- skott/filesystem/file-reader
- skott/filesystem/file-writer
- skott/modules/resolvers/base-resolver
- skott/modules/resolvers/ecmascript/resolver
- skott/modules/walkers/common
- skott/modules/walkers/ecmascript/index
- skott/modules/walkers/ecmascript/javascript/cjs
- skott/modules/walkers/ecmascript/javascript/walker
- skott/modules/walkers/ecmascript/module-declaration
- skott/modules/walkers/ecmascript/typescript/path-alias
- skott/modules/walkers/ecmascript/typescript/walker
Readme
How to use skott
Install
You can install skott either locally or globally
npm install skott
// or
npm install skott -g
Embedded Web Application
skott now embeds a new display mode "skott --displayMode=webapp" allowing you to visualize more precisely dependencies and the links between them. Here is an overview of a subset from the graph generated for fastify
:

As shown above Third-party and Built-in dependencies can be toggled when they are tracked (by providing --trackThirdPartyDependencies
and --trackBuiltinDependencies
to the CLI).
When Circular dependencies
are found in the graph, they can also be toggled via the Node visualization options as shown below:

JavaScript API
import skott from "skott";
const { getStructure, findCircularDependencies, findParentsOf, findLeaves } = await skott({
/**
* (Optional) Entrypoint of the project. If not provided, `skott` will search for all
* supported files starting from the current working directory.
* Defaults to `""`
*/
entrypoint: "src/index.ts",
/**
* (Optional) Whether to run Skott using the incremental pattern. By setting "true",
* Skott will create a `.skott/cache.json` file to only detect and re-process what
* changed since the last analysis.
* Defaults to `true`;
*/
incremental: true,
/**
* (Optional) restricts file discovering when building the graph.
* Defaults to `[".js", ".mjs", ".cjs", ".jsx", ".ts", ".tsx"]`
*/
fileExtensions: [".ts", ".tsx"],
/**
* (Optional) Max depth search for circular dependencies. This can be useful for
* performance purposes.
* Defaults to `POSITIVE_INFINITY`.
*/
circularMaxDepth: 20,
/**
* (Optional) Whether the base directory of the entrypoint should be included in relative
* file paths. For the specified `src/index.ts` above, it would consider the
* root path to be `./` consequently `src/` would never appear in any file paths.
* Defaults to `false`.
*/
includeBaseDir: false,
/**
* (Optional) Whether third-party dependencies (npm) and/or builtin (Node.js core modules)
* should be added in the graph and/or Typescript type-only import should be followed.
* Defaults to `thirdParty=false`, `builtin=false`, and `typeOnly=true`.
*/
dependencyTracking: {
thirdParty: true,
builtin: true,
typeOnly: true
};
/**
* (Optional) Provide a custom tsconfig file to help skott resolve path aliases.
* When extending some other tsconfig files, skott will be able to parse
* all the way up all the path aliases referenced.
* Defaults to `tsconfig.json`.
*/
tsConfigPath: "./tsconfig.json",
/**
* (Optional) Provide a path to the package.json that should be used to detect
* unused third-party dependencies.
* Defaults to `package.json`.
*/
manifestPath: "./package.json",
/**
* (Optional) Provide custom dependency resolvers to take full control over the
* content that will be added to the graph nodes.
* Defaults to `EcmaScriptModuleResolver` which is used a standard dependency
* resolver for ECMAScript projects.
*/
dependencyResolvers: [new TurborepoResolver()]
});
Command line interface
skott exposes a CLI directly using features from the core library.
When the library installed locally you can run:
Providing an entrypoint:
$ ./node_modules/.bin/skott src/index.js
When the library is installed globally:
$ skott src/index.js
Note: The CLI output might be massive, so don't hesitate to pipe the stdout into a file:
$ skott --displayMode=file-tree > skott.txt
Run a global analysis from the current working directory:
Using this command, skott will deeply search for all ".ts" and ".tsx" files starting from cwd
$ skott --fileExtensions=.ts,.tsx
Skott can be used to generate static files from the project graph structure (.svg, .png, .md, .json)
$ skott src/index.js --staticFile=svg
For Skott itself, the following .svg file is generated:
On the CLI side, here are some examples of output generated:
Example targetting Fastify using "graph" display mode:
Using "file-tree" display mode:
When asking for circular dependencies to be found (using the --showCircularDependencies
option):
See all the options of the CLI running:
$ skott --help
Examples
To initialize the dependency graph, the default exported function must be used first. Once executed, the default function returns a set of functions to retrieve some information about the graph just built.
import skott from "skott";
const { getStructure } = await skott({
entrypoint: "index.js",
// ...rest of the config
});
const { graph, files } = getStructure();
console.log(graph); // logs { "index.js": { id: "index.js", adjacentTo: [], body: {...} } };
console.log(files); // logs [ "index.js" ]
Search for circular dependencies
import skott from "skott";
const { findCircularDependencies, hasCircularDependencies } = await skott({
entrypoint: "index.js",
// ...rest of the config
});
// Imagine that starting from "index.js" skott detects a circular dependency
// between "core.js" and "utils.js" files
console.log(findCircularDependencies()); // logs [ [ "core.js", "utils.js" ] ]
console.log(hasCircularDependencies()); // logs "true"
Search for unused dependencies using the graph generated
import skott from "skott";
const { findUnusedDependencies } = await skott({
entrypoint: "index.tsx",
// ...rest of the config
});
const { thirdParty } = await findUnusedDependencies();
console.log(thirdParty); // logs [ "rxjs", "lodash.difference" ]
Search for leaves (nodes with no children)
leaf.js
console.log("I'm a leaf because I have no dependency");
index.js
import skott from "skott";
const { findLeaves } = await skott({
entrypoint: "leaf.js",
// ...rest of the config
});
console.log(findLeaves()); // logs [ "leaf.js" ]
Deeply search for parent dependencies of a given node
children.js
export const childrenFunction = () => {};
parent.js
import { childrenFunction } from "./children.js";
childrenFunction();
index.js
import skott from "skott";
const { findParentsOf } = await skott({
entrypoint: "parent.js",
// ...rest of the config
});
console.log(findParentsOf("children.js")); // logs [ "parent.js" ]
Explore file node metadata
Take for instance lib.js
with the following content:
lib.js
import * as fs from "node:fs";
import { parseScript } from "meriyah";
And given the entrypoint main.js
module below:
main.js
import skott from "skott";
const { getStructure } = await skott({
entrypoint: "lib.js",
dependencyTracking: {
builtin: true,
thirdParty: true,
typeOnly: true
}
});
const { graph } = getStructure();
console.log(graph["lib.js"].body);
// Prints
{
size: 70,
thirdPartyDependencies: ["meriyah"],
builtinDependencies: ["node:fs"]
}