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

@dtgraph/viewer

v0.1.0

Published

Interactive WebGL explorer for DTCG token graphs: zoomable map, clusters, search, focus

Readme

@dtgraph/viewer

An interactive, WebGL-rendered map of a DTCG token graph. Tokens cluster by what they reference, are sized by how many tokens depend on them, and are labeled progressively as you zoom. Hover a token to spotlight what it relates to, click it for details, search to jump anywhere. Built on @dtgraph/core, Sigma.js and graphology.

Framework-agnostic: one mount function, one container element, no React required. It powers the playground, the Storybook addon and the <TokenGraph interactive /> MDX component.

Install

npm install @dtgraph/viewer @dtgraph/core

Usage

import {
  buildTokenGraph,
  flattenTokenTree,
  parseTokenTree,
  resolveAliasEdgesAcrossFiles,
} from '@dtgraph/core';
import { mountTokenGraphViewer } from '@dtgraph/viewer';
import '@dtgraph/viewer/style.css';

const tree = parseTokenTree(tokensJson);
const named = [{ source: 'tokens.json', tree }];
const graph = buildTokenGraph(flattenTokenTree(tree), resolveAliasEdgesAcrossFiles(named));

const viewer = mountTokenGraphViewer(document.getElementById('map'), graph, { theme: 'dark' });

// later
viewer.select(['color', 'brand']);
viewer.fit();
viewer.destroy();

The container must have a non-zero width and height (give it a height), and the browser needs WebGL. If either is missing, mountTokenGraphViewer throws an error that says so and leaves the container untouched.

If your host cannot import CSS files (Storybook's manager, a plain <script> tag, ...), inject the stylesheet instead:

import { injectViewerStyles } from '@dtgraph/viewer';

injectViewerStyles(); // idempotent; adds one <style id="dtgraph-viewer-styles"> to <head>

Options

| Option | Type | Default | Description | | ---------- | -------------------------------------- | --------- | ---------------------------------------------------------------------------------------- | | theme | 'dark' \| 'light' | 'dark' | Canvas and overlay colors. | | colorBy | 'group' \| 'type' | 'group' | Color tokens by top-level group (color.*, button.*, ...) or by DTCG $type. | | chrome | boolean | true | Show the search box, legend and detail panel. false gives the bare map. | | layout | { iterations?, settings? } | | ForceAtlas2 iteration count and setting overrides, for graphs above the small threshold. | | onSelect | (token: TokenNode \| undefined) => void | | Called whenever the selection changes. |

Handle

mountTokenGraphViewer returns:

| Member | Description | | ------------------ | ------------------------------------------------------------------------------------ | | select(path) | Select a token (dotted path or segments): spotlight its chains, open its details. | | clearSelection() | Clear the selection and close the panel. | | selected | The selected token's dotted path, or undefined. | | zoomTo(path) | Animate the camera onto a token. | | fit() | Animate the camera back to the whole graph. | | destroy() | Tear down the renderer and remove everything the viewer added to the container. | | graph, sigma | The laid-out graphology graph and the Sigma instance — escape hatches for extension. |

Interaction

  • Drag to pan, scroll / pinch to zoom, double-click a token to dive onto it.
  • Hover a token: it and its direct neighbors stay lit and labeled, everything else fades.
  • Click a token: its whole upstream chain (what it resolves through) and downstream set (everything that changes if it changes) stay lit; the detail panel shows type, group, source file, description, the raw $value, what it resolves to (with a swatch for colors), and clickable "Depends on" / "Used by" lists. Click the background or press Esc to clear.
  • Legend: click a group or type to show only it; click again to clear.
  • Keyboard: / or Ctrl/Cmd+K focuses search (arrows + Enter pick a result), Esc clears, f fits.

How it reads

  • Size is blast radius: a square-root scale of how many tokens depend on a token, directly or transitively. Heavily-used primitives are the big dots.
  • Color is the top-level group by default (or $type), from a 20-hue palette tuned for each theme; edges take their source token's color.
  • Layout is deterministic. Up to 24 tokens: a layered diagram, primitives on the left and each consumer one column right of the deepest token it references. Larger graphs: ForceAtlas2 (LinLog, size-aware) so tokens that reference each other cluster, with tokens that reference nothing packed into one small satellite disc per group around the core.
  • A token's effective $type follows its alias chain, so {semantic.primary}-style tokens color and filter as color even without repeating $type.

Theming

Overlay colors are CSS custom properties on .dtgraph-viewer (see style.css): --dtgraph-viewer-bg, --dtgraph-viewer-fg, --dtgraph-viewer-font, --dtgraph-viewer-radius, and the --dtgraph-viewer-panel-* / --dtgraph-viewer-accent / --dtgraph-viewer-code-bg set for panels. The canvas itself is painted from THEMES in theme.ts, exported for hosts that want to match it.

Security model

Token content is untrusted input. The viewer draws token text only through canvas fillText (labels) and builds every panel, result row and chip from DOM nodes with textContent — no HTML is ever built from token content, the same guarantee as renderTokenGraphToSvg in core.

Examples