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

@crossplatformai/dependency-graph

v0.12.0

Published

Workspace dependency graph tooling for CrossPlatform.ai projects.

Readme

@crossplatformai/dependency-graph

Workspace dependency graph tooling for CrossPlatform.ai projects.

This package provides workspace discovery, graph building, traversal, and analysis utilities for developer tooling, CI, release workflows, and repository maintenance.

Package Role

@crossplatformai/dependency-graph belongs in the developer tooling layer.

It is intended for:

  • workspace analysis
  • affected package detection
  • release and CI automation
  • dependency health checks
  • repository tooling

It is not an app runtime capability.

Installation

pnpm add @crossplatformai/dependency-graph

Usage

Discovering Workspaces

import { discoverWorkspaces } from '@crossplatformai/dependency-graph';
import { readFile } from 'node:fs/promises';
import { glob } from 'glob';
import { parse } from 'yaml';

const packages = await discoverWorkspaces(process.cwd(), {
  fs: {
    readFile: async (path, encoding) => readFile(path, encoding),
    exists: async (path) => {
      try {
        await readFile(path);
        return true;
      } catch {
        return false;
      }
    },
  },
  glob: {
    glob: async (pattern, options) => glob(pattern, options),
  },
  yaml: {
    parse: (content) => parse(content),
  },
});

Building Dependency Graph

import { buildDependencyGraph } from '@crossplatformai/dependency-graph';

const graph = buildDependencyGraph(packages);

Finding Affected Packages

import { findAffectedPackages } from '@crossplatformai/dependency-graph';

const affected = findAffectedPackages(graph, 'my-package', {
  includeSelf: true,
});

Detecting Cycles

import { detectCycles } from '@crossplatformai/dependency-graph';

const cycles = detectCycles(graph);
if (cycles.length > 0) {
  console.error('Circular dependencies detected:', cycles);
}

Mapping Files to Packages

import { mapFilesToPackages } from '@crossplatformai/dependency-graph';

const changedFiles = ['apps/web/src/index.ts', 'packages/ui/src/button.tsx'];
const fileMap = mapFilesToPackages(changedFiles, packages);

console.log(fileMap);
// Map { 'web' => ['apps/web/src/index.ts'], '@repo/shared' => ['packages/ui/src/button.tsx'] }

API

Types

  • WorkspacePackage - Package metadata from package.json
  • DependencyGraph - Graph representation of package dependencies
  • DependencyNode - Node in the dependency graph
  • GraphStats - Statistics about the dependency graph

Client Interfaces (Dependency Injection)

  • FileSystemClient - File system operations interface
  • GlobClient - Glob pattern matching interface
  • YamlClient - YAML parsing interface

Functions

Workspace Discovery

  • discoverWorkspaces(rootDir, config) - Discover all workspace packages

Graph Building

  • buildDependencyGraph(packages) - Build dependency graph from packages

Graph Traversal

  • findAffectedPackages(graph, packageName, options) - Find all packages affected by changes
  • findDependencyPath(graph, from, to) - Find shortest path between packages
  • findAllPaths(graph, from, to) - Find all paths between packages

Graph Analysis

  • analyzeGraph(graph) - Get comprehensive graph statistics
  • detectCycles(graph) - Detect circular dependencies
  • getTransitiveDependencies(graph, packageName) - Get all transitive dependencies
  • getTransitiveDependents(graph, packageName) - Get all transitive dependents

File Mapping

  • findPackageForFile(filePath, packages) - Find which package owns a file
  • mapFilesToPackages(files, packages) - Map array of files to their packages

Dependency Injection Pattern

This package accepts clients supplied by the calling tool or script:

import type { WorkspaceDiscoveryConfig } from '@crossplatformai/dependency-graph';
import { readFile } from 'node:fs/promises';
import { glob } from 'glob';
import { parse as parseYaml } from 'yaml';

// Create config with real implementations
const config: WorkspaceDiscoveryConfig = {
  fs: {
    readFile: (path, encoding) => readFile(path, encoding),
    exists: async (path) => {
      try {
        await readFile(path);
        return true;
      } catch {
        return false;
      }
    },
  },
  glob: {
    glob: (pattern, options) => glob(pattern, options),
  },
  yaml: {
    parse: (content) => parseYaml(content),
  },
};

// Use with dependency injection
const packages = await discoverWorkspaces(process.cwd(), config);

Testing

For testing, provide mock implementations:

import { describe, it, expect, vi } from 'vitest';

const mockConfig = {
  fs: {
    readFile: vi.fn(),
    exists: vi.fn(),
  },
  glob: {
    glob: vi.fn(),
  },
  yaml: {
    parse: vi.fn(),
  },
};

// Mock implementations
mockConfig.fs.readFile.mockResolvedValue('{}');
mockConfig.glob.glob.mockResolvedValue(['apps/web', 'packages/ui']);
mockConfig.yaml.parse.mockReturnValue({ packages: ['apps/*', 'packages/*'] });

const packages = await discoverWorkspaces('/fake/root', mockConfig);

Design Approach

This package prefers host-provided implementations for filesystem, globbing, and YAML parsing when flexibility matters.

That keeps the graph logic:

  • testable
  • environment-agnostic
  • reusable across scripts and CI contexts
  • decoupled from any one file access strategy

License

Apache-2.0