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

ggaction

v0.0.10

Published

Build charts through immutable, traceable graphical actions.

Readme

ggaction

npm version CI license documentation

A grammar for how charts are made.

Most visualization grammars describe a finished chart. ggaction represents chart authoring itself as an immutable, traceable sequence of graphical actions.

Build, inspect, select, and revise charts one meaningful action at a time.

Every frame is rendered from an immutable ChartProgram. The final R² label is a traceable action built from public extension primitives.

A grammar of graphical action

Actions are verbs:

create · transform · encode · edit · select · compose

Chart resources are nouns:

data · marks · scales · coordinates · guides

A ChartProgram is the immutable sentence they produce.

The following fragment assumes cars is an array of row objects:

import { chart } from "ggaction";

const program = chart()
  .createCanvas()
  .createData({ values: cars })
  .createScatterPlot({
    id: "points",
    x: "Displacement",
    y: "Acceleration",
    color: "Origin",
    guides: false
  })
  .createRegression()
  .createGuides();

Why actions?

  • Progressive — build and revise a chart one meaningful operation at a time.
  • Traceable — retain high-level actions and the wrapped actions they invoke.
  • Materialized — actions create concrete backend-neutral graphics; rendering does not perform hidden semantic compilation.

MCP server for LLM

ggaction includes a local, read-only MCP server that gives coding assistants current action names, exact call shapes, and task-specific authoring steps without loading the complete documentation.

Across a fixed 576-run evaluation, MCP-first authoring with bounded fallback improved strict task success while using fewer tokens and model calls for all three model sizes. The server runs locally over stdio and does not execute chart code, access arbitrary files, make network requests, require an account, or collect telemetry.

Set up the local MCP server · Inspect the benchmark record · Read the complete evaluation report

Quick start

Install the current public release:

npm install ggaction

Add the Canvas element that the rendering code targets. Its accessible name and fallback text summarize the chart for contexts where Canvas pixels are not available:

<canvas id="chart" aria-label="Scatterplot of displacement versus acceleration by origin">
  Scatterplot of displacement versus acceleration by origin.
</canvas>
import { chart, render } from "ggaction/basic";

const observations = [
  { displacement: 97, acceleration: 14.5, origin: "Japan" },
  { displacement: 140, acceleration: 15.5, origin: "USA" },
  { displacement: 86, acceleration: 16.4, origin: "Japan" }
];

const program = chart()
  .createCanvas({
    width: 640,
    height: 400,
    margin: { top: 30, right: 130, bottom: 60, left: 70 }
  })
  .createData({ values: observations })
  .createScatterPlot({
    x: "displacement",
    y: "acceleration",
    color: "origin",
    shape: "origin"
  });

const context = document.querySelector("#chart").getContext("2d");
render(program, context);

Matching color and shape encodings give each origin a redundant visual cue and create a labeled categorical legend automatically.

The Quick Start uses the smaller ggaction/basic entry for the common creation path. Import from ggaction when you need editing, selection, composition, alternative coordinates, or statistical layers.

Branch revisions without mutation

Start a separate program without a shape encoding, then derive alternatives without changing the checkpoint:

import { chart as editableChart } from "ggaction";

const checkpoint = editableChart()
  .createCanvas({ width: 640, height: 400 })
  .createData({ values: observations })
  .createScatterPlot({
    x: "displacement",
    y: "acceleration",
    color: "origin"
  });

const outlined = checkpoint.editPointMark({
  stroke: "#0f172a",
  strokeWidth: 2
});
const muted = checkpoint.editPointMark({ opacity: 0.35 });

console.log(checkpoint === outlined); // false
console.log(checkpoint.trace.children.at(-1).op); // "createScatterPlot"
console.log(outlined.trace.children.at(-1).op);   // "editPointMark"

All three remain renderable and inspectable. They are immutable values, not an automatic undo stack; the application chooses which to retain or render.

Use createLinePlot, createBarPlot, createHistogram, and createHeatmap for the other basic Cartesian charts. The ggaction/basic entry keeps this common creation path at or below the current 120,000-byte gzip regression ceiling while each facade still records its mark, encoding, and guide actions as trace children. Import from ggaction when you need editing, selection, composition, alternative coordinates, or statistical layers. See the Basic Charts API.

Use createParallelCoordinates({ dimensions }) to connect each source row across ordered, dimension-local scales and axes. See the Parallel Coordinates API or the runnable Cars example.

For an advanced layered example, follow the regression recipe or open the runnable regression example. To compare category distributions with density-filled strips, read the gradient-plot guide or open the runnable example. For symmetric or split density shapes centered on categories, use the violin-plot API or the runnable Cars example. For compact signed time-series bands, use encodeHorizon on an area mark and open the runnable Gapminder example.

What it supports

  • Cartesian, Polar, and Parallel-coordinate charts
  • Statistical layers and intervals
  • Faceting and program composition
  • Mark selection and coordinated highlighting
  • Browser Canvas, SVG, Node PNG, and vector PDF output
  • TypeScript declarations and traceable extension actions

See the current supported features, tutorials and examples, and action reference for exact coverage. Runnable programs are collected in examples/.

Package entries

The package is ESM-only and requires Node.js 20 or later.

| Entry | Purpose | | --- | --- | | ggaction | Create chart programs and render them to Browser Canvas | | ggaction/basic | Create and render scatter, line, bar, histogram, and heatmap charts with a smaller browser bundle | | ggaction/extension | Author and register wrapped actions with public low-level primitives | | ggaction/png | Render a completed program to a PNG file in Node.js | | ggaction/pdf | Render a completed program to a single-page vector PDF file in Node.js | | ggaction/svg | Serialize a completed program to browser-safe SVG | | ggaction-mcp | Run the local read-only MCP authoring server over stdio in Node.js |

All module entries include TypeScript declarations. The default, basic, extension, and SVG entries are browser-safe; the PNG and PDF adapters are Node-only.

The installed package also includes the Node-only ggaction-mcp executable. It provides one local, read-only chart-authoring search tool and stays outside every browser entry. See the local MCP guide.

Documentation

Contributing

Bug reports, documentation improvements, examples, and focused code changes are welcome. Read CONTRIBUTING.md for setup, scope, tests, and the extra discussion required before public API or architecture changes.

Status and development

Status: 0.0.10 is the current experimental public release. APIs may change before 1.0.0; changes are recorded in the changelog.

npm install
npm run assets:readme
npm test
npm run test:render
npm run test:docs

Related Links

  • Action-trace demo: Link