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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@api-client/graph

v0.3.10

Published

A set of libraries helping working with graphs.

Readme

@api-client/graph

A powerful and flexible library for working with graphs in JavaScript and TypeScript.

Introduction

@api-client/graph provides a robust set of tools for creating, manipulating, and analyzing graphs. Whether you're building a social network, a dependency tree, or a complex workflow, this library offers the core functionality you need. It's designed to be intuitive for beginners while offering advanced features for experienced developers.

This library is inspired by and builds upon the solid foundation of the dagrejs/graphlib library.

Key Features

  • Directed and Undirected Graphs: Create both directed and undirected graphs to model various relationships.
  • Node and Edge Management: Easily add, remove, and query nodes and edges.
  • Graph Attributes: Store metadata about your graph, nodes, and edges.
  • Path Operations: Efficiently work with paths within your graph.
  • Layout Algorithms: Built-in support for graph layout, making it easy to visualize your data.
  • TypeScript Support: Fully typed for a seamless development experience.
  • Compound Graphs: Create graphs with subgraphs.

Getting Started

Installation

Install the library using npm:

npm install --save @api-client/graph

Basic Usage

Here's how to create a simple graph, add nodes and edges, and set some attributes:

import { Graph } from '@api-client/graph';

// Create a new directed graph
const g = new Graph({ directed: true });

// Set a graph label (optional)
g.setGraph({ label: "My First Graph" });

// Add nodes with data
g.setNode("a", { label: "Node A", value: 123 });
g.setNode("b", { label: "Node B", value: 456 });
g.setNode("c", { label: "Node C", value: 789 });

// Add edges between nodes with data
g.setEdge("a", "b", { label: "Edge AB", weight: 1 });
g.setEdge("b", "c", { label: "Edge BC", weight: 2 });
g.setEdge("a", "c", { label: "Edge AC", weight: 3 });

// Access node and edge data
console.log(g.node("a")); // Output: { label: "Node A", value: 123 }
console.log(g.edge("a", "b")); // Output: { label: "Edge AB", weight: 1 }
console.log(g.graph()); // Output: { label: "My First Graph" }

// Check if a node or edge exists
console.log(g.hasNode("a")); // Output: true
console.log(g.hasEdge("a", "c")); // Output: true

// Iterate over nodes
g.nodes().forEach(nodeId => {
  console.log(`Node ID: ${nodeId}`);
});

// Iterate over edges
g.edges().forEach(edge => {
  console.log(`Edge from ${edge.v} to ${edge.w}`);
});

Working with Paths

You can easily define paths within your graph:

import { Graph } from '@api-client/graph';

const g = new Graph({ directed: true });

// Set a path of nodes
g.setPath(["a", "b", "c", "d"]);

// This will create the following edges:
// a -> b
// b -> c
// c -> d

console.log(g.hasEdge("a", "b")); // Output: true
console.log(g.hasEdge("b", "c")); // Output: true
console.log(g.hasEdge("c", "d")); // Output: true

Graph Layout

The library includes a powerful layout engine to automatically arrange your graph for visualization:

import { Graph, layout } from '@api-client/graph';

const g = new Graph({ directed: true });
g.setNode('a', { width: 30, height: 20 });
g.setNode('b', { width: 40, height: 30 });
g.setNode('c', { width: 50, height: 25 });
g.setEdge('a', 'b', {});
g.setEdge('b', 'c', {});

layout(g);

// Now the graph 'g' has layout information.
console.log(g.node('a')); // Output: { width: 30, height: 20, x: ..., y: ... }
console.log(g.edge('a', 'b')); // Output: { points: [ { x: ..., y: ... }, { x: ..., y: ... } ] }

Compound Graphs

You can create graphs with subgraphs:

import { Graph } from '@api-client/graph';
import layout from '@api-client/graph/layout';

const g = new Graph({ directed: true, compound: true });
g.setNode('a', { width: 100, height: 100 });
g.setNode('b', { width: 40, height: 30 });
g.setNode('c', { width: 50, height: 25 });
g.setParent('b', 'a');
g.setParent('c', 'a');

layout(g);

console.log(g.node('a')); // Output: { width: 100, height: 100, x: ..., y: ... }
console.log(g.node('b')); // Output: { width: 40, height: 30, x: ..., y: ... }
console.log(g.node('c')); // Output: { width: 50, height: 25, x: ..., y: ... }

Undirected Graphs

Here are things to keep in mind when working with undirected graphs:

  • Double Edges: Whenever an edge between two different nodes is set, a reverse edge is also set.
    • Self-reference Exception: When setting an edge to the same node, a reverse edge is never set.
    • Examples:
      • When setting edge from a to b then another edge from b to a is always set
      • When setting edge from a to a then no other edges are set.
  • Referenced Values: When an edge value is set, and the value is an object, both set edges will have a reference to the same value. This also includes generated by the default edge function.
  • Non-object Values: When setting primitives as an edge value, it is your responsibility to update both edges.

Development

Cloning the Repository

git clone https://github.com/api-client/graph
cd graph

Installing Dependencies

npm install

Running Tests

npm test

Design Choices

  • Node/Edge keys - Node and edge keys are always string. This is a performance optimization. If your keys use numbers, translate them to strings first.