Skip to main content
Scanners

Dependency Graph Scanner

Lockfile analysis for duplicate packages, phantom dependencies, and workspace graphs.

The Dependency Graph scanner parses lockfiles to build a complete workspace-wide dependency graph. It identifies supply chain risks like duplicate packages, phantom dependencies, and lockfile inconsistencies that can cause "works on my machine" issues.


Supported Lockfiles

Package ManagerLockfileDetection
pnpmpnpm-lock.yamlFull graph with workspace support
npmpackage-lock.jsonFull graph
Yarn Classicyarn.lockFull graph
Yarn Berryyarn.lock (v2+)Full graph
.NETpackages.lock.jsonNuGet dependency tree
Pythonpoetry.lock, Pipfile.lockFull graph

Tip: Always commit lockfiles to version control. Vibgrate uses lockfiles for accurate dependency counts—without them, only direct dependencies are analyzed.


Analysis Categories

Package Counts

MetricDescription
Total UniqueDistinct package names in the graph
Total InstalledAll package instances (including duplicates)
DirectDependencies declared in package.json
TransitiveDependencies of dependencies

Duplicate Detection

Multiple versions of the same package can cause:

  • Increased bundle size
  • Runtime conflicts (especially for stateful packages like React)
  • Harder debugging
{
  "duplicates": [
    {
      "name": "lodash",
      "versions": ["4.17.21", "4.17.15", "3.10.1"],
      "instances": 3,
      "impact": "high",
      "recommendation": "Use pnpm dedupe or npm dedupe to resolve"
    },
    {
      "name": "semver",
      "versions": ["7.5.4", "7.5.3"],
      "instances": 2,
      "impact": "low",
      "recommendation": "Minor version difference, likely safe"
    }
  ]
}

Phantom Dependencies

Packages used in code but not declared in package.json:

{
  "phantomDependencies": [
    {
      "name": "debug",
      "usedIn": ["src/logger.ts", "src/api/client.ts"],
      "availableFrom": "express",
      "risk": "medium",
      "recommendation": "Add to dependencies or devDependencies"
    }
  ]
}

Warning: Phantom dependencies can break unexpectedly when other packages update or change their dependency trees.


Use Cases

Bundle Size Optimization

# Find packages with the most duplicates
vg scan --format json | jq '.dependencyGraph.duplicates | sort_by(-.instances) | .[0:10]'

Supply Chain Audit

This data feeds directly into vg sbom export for:

  • CycloneDX SBOM generation
  • SPDX compliance reporting
  • Dependency-Track integration

Monorepo Analysis

For workspaces, the scanner aggregates across all packages:

{
  "workspaces": {
    "packages/api": { "dependencies": 45, "devDependencies": 23 },
    "packages/web": { "dependencies": 89, "devDependencies": 34 },
    "packages/shared": { "dependencies": 12, "devDependencies": 8 }
  },
  "sharedDependencies": ["typescript", "zod", "react"]
}

Example Output

{
  "dependencyGraph": {
    "totalUnique": 245,
    "totalInstalled": 892,
    "directDependencies": 34,
    "transitiveDependencies": 858,
    "lockfilePresent": true,
    "lockfileType": "pnpm-lock.yaml",
    "duplicates": [
      {
        "name": "lodash",
        "versions": ["4.17.21", "4.17.15"],
        "instances": 2,
        "impact": "medium"
      }
    ],
    "phantomDependencies": [
      {
        "name": "debug",
        "usedIn": ["src/logger.ts"],
        "availableFrom": "express"
      }
    ],
    "deepestPath": {
      "depth": 12,
      "path": "next → @next/env → ... → ms"
    }
  }
}

Remediation

Fixing Duplicates

# pnpm
pnpm dedupe

# npm
npm dedupe

# yarn
yarn dedupe

Fixing Phantom Dependencies

# Add the missing dependency explicitly
npm install debug --save

Related Documentation