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

@tanstack/charts

v0.7.2

Published

A chart grammar for TypeScript and JavaScript. Marks consume your data directly, channels describe visual encodings, and the engine compiles them into a renderer-neutral keyed scene. TanStack's compact scales cover common numeric and categorical mappings.

Readme

TanStack Charts

A chart grammar for TypeScript and JavaScript. Marks consume your data directly, channels describe visual encodings, and the engine compiles them into a renderer-neutral keyed scene. TanStack's compact scales cover common numeric and categorical mappings. Granular D3 modules remain available for temporal, nonlinear, piecewise, spatial, and other specialized algorithms.

TanStack Charts is an independent implementation for typed application infrastructure. Project lineage is recorded in the repository ACKNOWLEDGEMENTS.md.

Install the grammar and compact scales for the common path:

pnpm add @tanstack/charts @tanstack/charts-scales

The scale package has no root export. Import only the required /linear, /band, /point, or /ordinal entry.

import { colorLegend, defineChart, lineY } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts-scales/linear'
import { scaleOrdinal } from '@tanstack/charts-scales/ordinal'
import { scalePoint } from '@tanstack/charts-scales/point'
import { tooltip } from '@tanstack/charts/tooltip'

interface DownloadRow {
  id: string
  month: string
  downloads: number
  package: string
}

const data: readonly DownloadRow[] = [
  {
    id: 'query-jan',
    month: 'Jan',
    downloads: 1_200_000,
    package: 'Query',
  },
  {
    id: 'query-feb',
    month: 'Feb',
    downloads: 1_480_000,
    package: 'Query',
  },
  {
    id: 'router-jan',
    month: 'Jan',
    downloads: 420_000,
    package: 'Router',
  },
  {
    id: 'router-feb',
    month: 'Feb',
    downloads: 510_000,
    package: 'Router',
  },
]

const downloads = defineChart({
  marks: [
    lineY(data, {
      x: 'month',
      y: 'downloads',
      z: 'package',
    }),
  ],
  x: { scale: () => scalePoint<string>().padding(0.4) },
  y: {
    scale: scaleLinear,
    nice: true,
    grid: true,
    axis: { label: 'Monthly downloads' },
  },
  color: {
    scale: () =>
      scaleOrdinal<string, string>().range(['#0ea5e9', '#f97316', '#10b981']),
    legend: colorLegend({ label: 'Package' }),
  },
  animate: true,
  tooltip,
})

Factories ask Charts to infer domains from materialized mark channels. Pass a configured compact instance when a semantic domain must remain fixed. Charts copies either form and owns its responsive positional range.

Add D3 for advanced scale semantics

Upgrade one scale at a time. A continuous calendar axis needs D3, while its numeric axis can stay compact:

pnpm add d3-scale
pnpm add -D @types/d3-scale
import { defineChart, lineY } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts-scales/linear'
import { scaleUtc } from 'd3-scale'

const history = [
  { date: new Date('2026-01-01T00:00:00Z'), downloads: 1_200_000 },
  { date: new Date('2026-02-01T00:00:00Z'), downloads: 1_480_000 },
]

const historicalDownloads = defineChart({
  marks: [lineY(history, { x: 'date', y: 'downloads' })],
  x: { scale: scaleUtc, nice: true },
  y: { scale: scaleLinear, nice: true },
})

Use D3 for time and UTC, log, power, symlog, radial, sequential, diverging, quantile, quantize, threshold, piecewise, or nonnumeric interpolation. Declare only the granular D3 modules and matching type packages imported by application source.

Use the vanilla host directly:

import { mountChart } from '@tanstack/charts/dom'

const options = {
  definition: downloads,
  height: 320,
  ariaLabel: 'Monthly package downloads',
}

const host = mountChart(element, options)
host.update({ ...options, height: 360 })
host.destroy()

Use the same host options with the opt-in Canvas surface:

import { mountCanvasChart } from '@tanstack/charts/canvas'

const host = mountCanvasChart(element, options)

@tanstack/charts/renderer exposes the renderer-neutral host, and @tanstack/charts/svg/renderer exposes the default SVG surface. Canvas, renderer-neutral, and SVG implementations remain separate bundle boundaries.

Or use a thin framework adapter:

import { Chart } from '@tanstack/react-charts'

;<Chart
  definition={downloads}
  height={320}
  ariaLabel="Monthly package downloads"
/>

Type inference

Mark data drives the public types. Field channels include only compatible datum keys, built-in marks with unambiguous positional semantics constrain their scales and axis formatters, and interaction callbacks retain the original datum type. ChartPoint.xValue and yValue retain the inferred channel types, including Date; conditional definitions expose honest unions for normal TypeScript narrowing. Rectangles infer scale types from their interval endpoints independently from their interaction anchors, and cells retain their categorical point values. Facets and custom marks remain unchecked only where their positional semantics are intentionally opaque. Definitions capture application values directly, and their identity is the host update boundary.

Normal authoring needs no cast, mark-array annotation, or adapter generic. If TypeScript rejects a chart, correct the data type, channel, scale, or definition. Custom marks introduce their datum and optional positional types at the public createMark<Datum, X, Y>() boundary. When a custom mark's interaction values intentionally differ from its materialized scale values, use createMarkWithScaleValues from @tanstack/charts/mark/scale-values; the exceptional subpath stays out of ordinary bundles.

Included grammar

  • Marks: lineY, areaX, areaY, barX, barY, dot, rect, cell, ruleX, ruleY, text, arrow, frame, hexagon, link, tickX, tickY, vector, and responsive facet composition
  • Scales: compact factories with inferred domains or configured instances with application-owned domains, plus direct D3 scales for advanced semantics
  • Guides: responsive axes, grids, labels, categorical legends, and gradient legends
  • Data preparation: TanStack transforms, direct granular D3 output, server-prepared intervals, and application-derived rows flow into ordinary marks
  • Runtime: object and responsive definitions, definition-identity updates, responsive measurement, keyed reconciliation, interruptible animation, pointer and keyboard focus, point activation, native tooltips, SSR, and hydration
  • Renderers: static SVG, a vanilla DOM host, optional Canvas, and custom renderer hosts
  • Optional export: standalone SVG and browser raster export from @tanstack/charts/export
  • Optional dense interaction: an application-supplied ChartSpatialIndexFactory backed by D3 quadtree, Delaunay, or another index
  • Optional grouped pointer focus from @tanstack/charts/focus
  • Optional native-focus suppression for application-owned gestures from @tanstack/charts/focus/disabled
  • Optional gradients and clipping from @tanstack/charts/svg/resources

Every built-in mark, renderer, and chart-owned optional capability has a subpath export. Compact scale families and D3 algorithms stay visibly imported from exact package entries. Importing @tanstack/charts/line cannot pull in bars, DOM interaction, React, or export. Set guides: false and margin: 0 for sparklines.

Automatic guide margins

Omit margin for the normal responsive path. Each scene solves the minimum space needed for formatted ticks, rotated bounds, first and last tick overhang, and axis titles. The solve may resolve guide scales more than once, but marks render once against the final plot rectangle.

import { barX, defineChart } from '@tanstack/charts'
import { scaleBand } from '@tanstack/charts-scales/band'
import { scaleLinear } from '@tanstack/charts-scales/linear'

const rankingRows = [
  { package: 'Query', downloads: 1_480_000 },
  { package: 'Router', downloads: 420_000 },
  { package: 'Table', downloads: 360_000 },
]

const chart = defineChart({
  marks: [barX(rankingRows, { x: 'downloads', y: 'package' })],
  x: {
    scale: scaleLinear,
    nice: true,
    axis: { label: 'Weekly downloads' },
  },
  y: {
    scale: () => scaleBand<string>().padding(0.1),
  },
})
  • Omitted sides are automatic.
  • margin: { left: 80 } locks only the left side.
  • margin: 0 locks every side to zero.
  • scene.margin and scene.chart expose the resolved geometry for aligned application UI.
  • Tick collision policy is separate. Set ticks or tickRotate when labels should be thinned or rotated; margins guarantee containment, not legibility between overlapping labels.

Static scenes use deterministic text estimates. The DOM host and browser framework adapters measure the painted glyph bounds with the inherited container font and relayout after web fonts load. Advanced renderers can supply measureText on the host, adapter, runtime, or createChartScene layout options. Its returned x and y are the painted box offsets relative to the requested anchor and baseline.

Definitions accept scale factories for inferred domains and configured instances for application-owned domains. createChartScene rejects missing positional scales. TanStack copies each scale, applies the responsive pixel range, and centers band output without mutating the source:

import { createChartScene, defineChart, lineY } from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts-scales/linear'

const values = [32, 48, 41, 57]
const definition = defineChart({
  marks: [lineY(values)],
  x: { scale: scaleLinear().domain([0, values.length - 1]) },
  y: { scale: scaleLinear().domain([0, 100]) },
})

const scene = createChartScene(definition, { width: 640, height: 320 })

Documentation for humans and agents

Start with llms.txt, Overview, or the Quick Start. The installed package includes the same canonical documentation published on the TanStack website:

Lineage and license

See the repository ACKNOWLEDGEMENTS.md for the full credit. TanStack Charts is licensed under MIT.