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

vizcraft

v0.2.2

Published

A fluent, type-safe SVG scene builder for composing nodes, edges, animations, and overlays with incremental DOM updates and no framework dependency.

Readme

VizCraft

npm version npm downloads CI Release Snapshot license

📖 Full documentation: docs here

A declarative, builder-based library for creating animated SVG network visualizations and algorithm demos.

VizCraft is designed to make creating beautiful, animated node-link diagrams and complex visualizations intuitive and powerful. Whether you are building an educational tool, explaining an algorithm, or just need a great looking graph, VizCraft provides the primitives you need.

✨ Features

  • Fluent Builder API: Define your visualization scene using a readable, chainable API.
  • Grid System: Built-in 2D grid system for easy, structured layout of nodes.
  • Two Animation Systems: Lightweight registry/CSS animations (e.g. edge flow) and data-only timeline animations (AnimationSpec).
  • Framework Agnostic: The core logic is pure TypeScript and can be used with any framework or Vanilla JS.
  • Custom Overlays: Create complex, custom UI elements that float on top of your visualization.

📦 Installation

npm install vizcraft
# or
pnpm add vizcraft
# or
yarn add vizcraft

🚀 Getting Started

You can use the core library directly to generate SVG content or mount to a DOM element.

import { viz } from 'vizcraft';

const builder = viz().view(800, 600);

builder
  .node('a')
  .at(100, 100)
  .circle(15)
  .label('A')
  .node('b')
  .at(400, 100)
  .circle(15)
  .label('B')
  .edge('a', 'b')
  .arrow();

const container = document.getElementById('viz-basic');
if (container) builder.mount(container);

More walkthroughs and examples: docs here.

📚 Documentation (Topics)

Full documentation site: docs here

Docs topics (same as the sidebar):

Run the docs locally (monorepo):

pnpm install
pnpm -C packages/docs start

📖 Core Concepts

The Builder (VizBuilder)

The heart of VizCraft is the VizBuilder. It allows you to construct a VizScene which acts as the blueprint for your visualization.

b.view(width, height) // Set the coordinate space
  .grid(cols, rows) // (Optional) Define layout grid
  .node(id) // Start defining a node
  .edge(from, to); // Start defining an edge

Nodes

Nodes are the primary entities in your graph. They can have shapes, labels, and styles.

b.node('n1')
 .at(x, y)               // Absolute position
 // OR
 .cell(col, row)         // Grid position
 .circle(radius)         // Shape definition
 .label('Text', { dy: 5 }) // Label with offset
 .class('css-class')     // Custom CSS class
 .data({ ... })          // Attach custom data

Edges

Edges connect nodes and can be styled, directed, or animated.

b.edge('n1', 'n2')
  .arrow() // Add an arrowhead
  .straight() // (Default) Straight line
  .label('Connection')
  .animate('flow'); // Add animation

Animations

See the full Animations guide docs here.

VizCraft supports two complementary animation approaches:

  1. Registry/CSS animations (simple, reusable effects)

Attach an animation by name to a node/edge. The default core registry includes:

  • flow (edge)
import { viz } from 'vizcraft';

const b = viz().view(520, 160);

b.node('a')
  .at(70, 80)
  .circle(18)
  .label('A')
  .node('b')
  .at(450, 80)
  .rect(70, 44, 10)
  .label('B')
  .edge('a', 'b')
  .arrow()
  .animate('flow', { duration: '1s' })
  .done();
  1. Data-only timeline animations (AnimationSpec) (sequenced tweens)
  • Author with builder.animate((aBuilder) => ...).
  • VizCraft stores compiled specs on the scene as scene.animationSpecs.
  • Play them with builder.play().
import { viz } from 'vizcraft';

const b = viz().view(520, 240);

b.node('a')
  .at(120, 120)
  .circle(20)
  .label('A')
  .node('b')
  .at(400, 120)
  .rect(70, 44, 10)
  .label('B')
  .edge('a', 'b')
  .arrow()
  .done();

b.animate((aBuilder) =>
  aBuilder
    .node('a')
    .to({ x: 200, opacity: 0.35 }, { duration: 600 })
    .node('b')
    .to({ x: 440, y: 170 }, { duration: 700 })
    .edge('a->b')
    .to({ strokeDashoffset: -120 }, { duration: 900 })
);

const container = document.getElementById('viz-basic');
if (container) {
  b.mount(container);
  b.play();
}

Animating edges with custom ids

If you create an edge with a custom id (third arg), target it explicitly in animations:

const b = viz().view(520, 240);
b.node('a')
  .at(120, 120)
  .circle(20)
  .node('b')
  .at(400, 120)
  .rect(70, 44, 10)
  .edge('a', 'b', 'e1')
  .done();

b.animate((aBuilder) =>
  aBuilder
    .edge('a', 'b', 'e1')
    .to({ strokeDashoffset: -120 }, { duration: 900 })
);

Custom animatable properties (advanced)

Specs can carry adapter extensions so you can animate your own numeric properties:

b.animate((aBuilder) =>
  aBuilder
    .extendAdapter((adapter) => {
      adapter.register?.('node', 'r', {
        get: (target) => adapter.get(target, 'r'),
        set: (target, v) => adapter.set(target, 'r', v),
      });
    })
    .node('a')
    .to({ r: 42 }, { duration: 500 })
);

Playback controls

builder.play() returns a controller with pause(), play() (resume), and stop().

const controller = b.play();
controller?.pause();
controller?.play();
controller?.stop();

Supported properties (core adapter)

Out of the box, timeline playback supports these numeric properties:

  • Node: x, y, opacity, scale, rotation
  • Edge: opacity, strokeDashoffset

🎨 Styling

VizCraft generates standard SVG elements with predictable classes, making it easy to style with CSS.

/* Custom node style */
.viz-node-shape {
  fill: #fff;
  stroke: #333;
  stroke-width: 2px;
}

/* Specific node class */
.my-node .viz-node-shape {
  fill: #ff6b6b;
}

/* Edge styling */
.viz-edge {
  stroke: #ccc;
  stroke-width: 2;
}

🤝 Contributing

Contributions are welcome! This is a monorepo managed with Turbo.

  1. Clone the repo
  2. Install dependencies: pnpm install
  3. Run dev server: pnpm dev

📄 License

MIT License