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

d3-blueprint

v0.1.5

Published

A modern micro-framework for building reusable, composable D3 charts

Readme

| | Status | | ---: | :--- | | CI checks | Github Actions | | Latest version | Latest version | | Release date | Release date | | Open issues | Open issues | | Documentation | Guide API |

Features

  • Composable Layers: Each layer owns its D3 data-join lifecycle (enter, merge, exit, and transitions). Combine layers freely to build complex visualizations from simple building blocks.
  • Reactive Config: Define typed config properties with getter/setter transforms and default values. Change a config, call draw(), and watch everything update.
  • Plugin System: Encapsulate cross-cutting behavior like tooltips, crosshairs, and responsive resize into reusable plugins that hook into the chart lifecycle automatically.
  • Nested Attachments: Compose charts from smaller charts. Attach reusable sub-components like axes or legends that draw in sync with the parent.
  • Built-in Transitions: Layers support transition events out of the box. Animate enter, merge, and exit phases with d3-transition with no manual wiring needed.
  • Tiny & Dependency-Free: Only peer-depends on d3-selection and d3-transition. Bring your own scales, shapes, and layouts with no monolithic D3 bundle required.

Quickstart

Install d3-blueprint from NPM:

npm install d3-blueprint d3-selection

Then create your first chart:

import { D3Blueprint } from 'd3-blueprint';
import { select } from 'd3-selection';

class BarChart extends D3Blueprint {
  initialize() {
    const svg = this.base.append('svg').attr('width', 400).attr('height', 200);
    const group = svg.append('g');

    this.layer('bars', group, {
      dataBind(selection, data) {
        return selection.selectAll('rect').data(data);
      },
      insert(selection) {
        return selection.append('rect');
      },
      events: {
        merge(selection) {
          selection
            .attr('x', (d, i) => i * 45)
            .attr('y', (d) => 200 - d.value * 4)
            .attr('width', 40)
            .attr('height', (d) => d.value * 4)
            .attr('fill', '#6878E8');
        },
      },
    });
  }
}

const chart = new BarChart(select('#app'));

chart.draw([
  { label: 'A', value: 30 },
  { label: 'B', value: 45 },
  { label: 'C', value: 20 },
  { label: 'D', value: 50 },
]);

Draw Lifecycle

When you call chart.draw(data), the following sequence executes:

constructor(selection)
  └── initialize()

draw(data)
  ├── transform(data) → transformedData
  ├── preDraw(transformedData)
  ├── emit "preDraw" event
  ├── layers.draw(transformedData)       ← each layer runs its data-join lifecycle
  ├── attachments.draw(transformedData)
  ├── postDraw(transformedData)
  ├── emit "postDraw" event
  ├── await all transitions
  ├── postTransition(transformedData)
  └── emit "postTransition" event

Plugins

Encapsulate reusable behavior with the plugin system:

import { D3Blueprint } from 'd3-blueprint';

const tooltipPlugin = {
  name: 'tooltip',
  install(chart) {
    chart.tooltipEl = chart.base.append('div').attr('class', 'tooltip');
  },
  postDraw(chart, data) {
    // Wire tooltip events after each draw
  },
  destroy(chart) {
    chart.tooltipEl?.remove();
  },
};

class MyChart extends D3Blueprint {
  initialize() {
    this.use(tooltipPlugin);
  }
}

See the Plugins Documentation for built-in plugins and custom plugin guides.

Next Steps

Find out more about how to use d3-blueprint on the official documentation.