sigma.js

A WebGL-powered JavaScript library for rendering graphs of thousands of nodes and edges directly from graphology data.

Library
npm
v3.0.3
12,161stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
66/100Good
Development Activity40
Maintenance32
Community92
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
85/100Excellent
Architecture85
Code Quality88
Innovation78
Learning Curve90

Sigma.js is a browser rendering engine for network graphs, built specifically on top of the graphology graph data structure. Rather than reinventing graph storage or algorithms, it focuses on one job: drawing large graphs fast, using WebGL shader programs instead of the DOM or canvas 2D drawing calls that choke past a few hundred elements.

A Sigma instance wraps a graphology Graph, a container element, and a settings object, then manages the camera, mouse/touch interaction, and per-frame rendering through pluggable node and edge “programs” — small, swappable shader-backed renderers for circles, points, lines, arrows, and curved or clamped edges. Because it reads graphology’s data model directly, any layout algorithm, generator, or metric from the graphology ecosystem plugs straight in with no adapter step.

The core package ships a minimal, sensible default renderer, while a family of companion packages (@sigma/edge-curve, @sigma/node-border, @sigma/node-image, @sigma/node-piechart, @sigma/layer-leaflet, @sigma/layer-maplibre, @sigma/export-image, and others) add optional node/edge shapes, geographic map layers, and PNG/SVG export without bloating the base bundle.

What You Get

  • A Sigma class that renders a graphology Graph into a container element with a managed camera, mouse/touch captors, and an animation loop
  • Swappable node and edge “programs” — WebGL shader renderers for circles, points, straight/curved/clamped/arrow/double-arrow edges — so custom visual styles don’t require touching the render loop
  • A reducer pattern (nodeReducer / edgeReducer) for computing per-frame display attributes (color, size, hidden, label) without mutating the underlying graph data
  • A quad-tree based label placement system (LabelGrid) that avoids overlapping labels at scale
  • An official extension ecosystem for optional capabilities: extra node/edge shapes, Leaflet/MapLibre geographic layers, and image export — installed only when needed
  • TypeScript-first API with generics over node/edge/graph attribute types, matching graphology’s own typing conventions

Common Use Cases

  • Exploring large network datasets (social graphs, citation networks, knowledge graphs) directly in the browser without server-side image rendering
  • Building interactive graph-analysis tools where users pan, zoom, and click nodes/edges to inspect data
  • Rendering geographic network overlays on Leaflet or MapLibre basemaps via the layer extension packages
  • Embedding a lightweight graph viewer in a dashboard or admin panel where a heavier graph-database UI would be overkill
  • Prototyping layout algorithms from the graphology ecosystem (ForceAtlas2, circular, random) with immediate visual feedback

Under The Hood

Architecture The core Sigma class (packages/sigma/src/sigma.ts) is the orchestration hub: it owns a Camera (pan/zoom/animated transitions), MouseCaptor and TouchCaptor instances for input handling, a LabelGrid for collision-aware label placement, and a settings object resolved and validated through resolveSettings/validateSettings. Rendering is delegated to a registry of AbstractNodeProgram/AbstractEdgeProgram implementations under rendering/programs/ (node-circle, node-point, edge-line, edge-arrow, edge-clamped, edge-triangle, edge-double-arrow, edge-rectangle, edge-arrow-head, edge-double-clamped), each a self-contained WebGL shader program keyed by the node/edge type attribute — new visual styles are added by writing a new program rather than modifying the renderer. A nodeReducer/edgeReducer layer computes final per-frame display data (color, size, hidden, z-index) without mutating the graphology graph itself, keeping the visualization layer cleanly separate from the data layer. The repo itself is a Lerna + npm-workspaces monorepo (packages/*), with the base renderer and each optional capability (map layers, extra shapes, export) shipped as independently versioned, independently installable packages built through @preconstruct/cli.

Tech Stack Written in TypeScript, compiled and bundled per-package via Vite (vite build in packages/sigma) with multiple entrypoints (index, types, settings, rendering, utils) managed through Preconstruct so consumers can import subpaths like sigma/utils directly. The only runtime dependencies are graphology-utils and a small events polyfill — the graph data model itself comes from the separately maintained graphology package, an explicit design choice to avoid duplicating graph storage/algorithms. Companion packages add their own scoped dependencies (Leaflet, MapLibre GL) only when that specific layer is installed. The monorepo is orchestrated with Lerna, linted with ESLint (flat config) plus Prettier with import sorting, and documented via a Docusaurus-based website (packages/website) with a live Storybook (packages/storybook) for interactive examples.

Code Quality Testing is split across @sigma/test: unit tests run under Vitest (including browser-mode tests for WebGL-dependent code), end-to-end tests run under Playwright against the built Storybook, and a separate benchmark suite (vitest bench) tracks rendering performance regressions. Tests are organized per companion package (unit/layer-leaflet, unit/layer-maplibre, unit/sigma, unit/utils), each with lifecycle tests that instantiate a real Sigma instance and assert clean setup/teardown. CI (GitHub Actions, tests.yml) runs the full unit + e2e suite on every push and pull request, with dependency and Playwright-binary caching. TypeScript is used throughout with generics constraining node/edge/graph attribute shapes, and ESLint plus Prettier enforce consistent style across the monorepo.

API Design The public surface is deliberately small: construct a Sigma with a graphology graph, a container, and optional settings, then read/write display state through reducers rather than a large imperative API. This keeps boilerplate low for the common case (a handful of lines to get a graph on screen) while still exposing lower-level primitives (Camera, the program classes, createNormalizationFunction) for consumers who need to extend rendering behavior. The tradeoff is that some setup — instantiating a graphology graph, applying a layout algorithm, wiring reducers for dynamic styling — is left to the consumer rather than bundled into the core package, which keeps the library focused but means new users need to understand graphology’s model alongside sigma’s own settings and program system.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search