| title |
|---|
@vltpkg/graph |
This is the graph library responsible for representing the packages that are involved in a given install.
Overview · Concepts · Architecture · API · Usage · Related Workspaces · References
The @vltpkg/graph workspace models a project's dependency
relationships and drives npm-compatible installs by computing how
node_modules should be structured. It exposes a public API through
src/index.ts that re-exports core types and workflows.
At a glance:
Graphencapsulates the full dependency graph for a project (including monorepo workspaces), and is the source of truth for how to lay outnode_modules.Noderepresents a unique package instance (uniqueness provided by@vltpkg/dep-id).Edgerepresents a dependency relationship from a dependent to a dependency (eg.dependencies,devDependencies,peerDependencies, etc.).Diffdescribes the minimal set of changes required to transform an Actual graph (disk) into an Ideal graph (desired outcome), which is then applied by thereifysubsystem.
- Importers: Root-level nodes used as starting points of the graph.
The
mainImporteris the project root (itspackage.json), and the remaining importers are workspaces discovered by@vltpkg/workspaces. - Hidden Lockfile: A performance optimization stored at
node_modules/.vlt-lock.jsonmirroring the current on-disk state to accelerate subsequent loads of the Actual graph. - Modifiers: Configuration for selectively altering dependency
resolution via DSS queries in
vlt.json. - Peer Contexts: Isolation mechanism for peer dependencies that allows multiple versions of the same package when peer requirements differ.
Recursively loads the node_modules folder found at projectRoot in
order to create a graph representation of the current installed
packages.
Builds the ideal dependency graph by loading from lockfile (preferred)
or actual graph, then expanding dependencies by fetching manifests.
Requires packageInfo and remover in addition to standard options.
Loads the lockfile file found at projectRoot and returns the graph.
Saves the graph to vlt-lock.json.
Computes a Diff between the Actual and Ideal graphs and applies the
minimal filesystem changes (creating/deleting links, writing
lockfiles, hoisting, lifecycle scripts) to make the on-disk install
match the Ideal graph. Returns { diff, buildQueue }.
High-level install orchestration that handles graph building, reify,
and lockfile management. Supports --frozen-lockfile,
--clean-install, and --lockfile-only modes.
Generates Mermaid flowchart syntax from graph data.
Generates ASCII tree output with optional colors. Used in vlt ls.
Returns array of {name, fromID, spec, type, to, overridden} items.
import { install } from '@vltpkg/graph'
const { graph, diff, buildQueue } = await install({
projectRoot: process.cwd(),
packageInfo,
packageJson,
scurry,
allowScripts: '*',
})import { actual, ideal, reify } from '@vltpkg/graph'
import { RollbackRemove } from '@vltpkg/rollback-remove'
const remover = new RollbackRemove()
// Load current on-disk state
const from = actual.load({
projectRoot: process.cwd(),
packageJson,
scurry,
loadManifests: true,
})
// Build intended end state (may start from lockfile or actual)
const to = await ideal.build({
projectRoot: process.cwd(),
packageInfo,
packageJson,
scurry,
remover,
})
// Apply minimal changes to match Ideal
const { diff, buildQueue } = await reify({
graph: to,
actual: from,
packageInfo,
packageJson,
scurry,
remover,
allowScripts: '*',
})import { lockfile } from '@vltpkg/graph'
// Load virtual graph from vlt-lock.json
const graph = lockfile.load({
projectRoot,
mainManifest,
packageJson,
})
// Save to vlt-lock.json
lockfile.save({ graph })import {
mermaidOutput,
humanReadableOutput,
jsonOutput,
} from '@vltpkg/graph'
// Mermaid flowchart (for docs, dashboards)
const mermaid = mermaidOutput({
edges: [...graph.edges],
nodes: [...graph.nodes.values()],
importers: graph.importers,
})
// ASCII tree with colors (used in `vlt ls`)
const tree = humanReadableOutput(
{
edges: [...graph.edges],
nodes: [...graph.nodes.values()],
importers: graph.importers,
},
{ colors: true },
)
// JSON array of dependency items
const json = jsonOutput({
edges: [...graph.edges],
nodes: [...graph.nodes.values()],
importers: graph.importers,
})Graph construction modes supported by the library:
-
Virtual Graphs (lockfile-based)
- Load and save via
src/lockfile/load.tsandsrc/lockfile/save.ts - Hidden lockfile:
node_modules/.vlt-lock.jsonfor faster loads - 📖 Lockfile README
- Load and save via
-
Actual Graphs (filesystem-based)
- Loaded by traversing
node_modulesviasrc/actual/load.ts - May shortcut to Hidden Lockfile if present and valid
- File layout changes are performed by
src/reify/
- Loaded by traversing
-
Ideal Graphs (desired end state)
- Entry:
src/ideal/build.ts - Starts from Virtual (preferred) or falls back to Actual
- Merges
add/removeinput with importer manifests usingsrc/ideal/get-importer-specs.ts - Fetches and expands manifests using
@vltpkg/package-info, reuses existing nodes that satisfy specs - 📖 Ideal README
- Entry:
Finally, src/diff.ts computes changes and src/reify/ applies them
to the filesystem.
@vltpkg/dep-id: Unique IDs for packages, ensuringNodeidentity@vltpkg/spec: Parse/normalize dependency specifiers and registry semantics@vltpkg/semver: Semantic version parsing/comparison@vltpkg/satisfies: Check if a DepID satisfies a Spec@vltpkg/package-info: Fetch remote manifests and artifacts (registry, git, tarball)@vltpkg/package-json: Read and cache localpackage.jsonfiles@vltpkg/workspaces: Monorepo workspace discovery and grouping@vltpkg/rollback-remove: Safe file removal with rollback capability@vltpkg/vlt-json: Loadvlt.jsonconfiguration (modifiers, etc.)
- package.json format and behavior: https://docs.npmjs.com/cli/v11/configuring-npm/package-json
- Semantic Versioning: https://semver.org/spec/v2.0.0.html
- Monorepos: https://monorepo.tools
