Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TanStack Charts

TanStack Charts

A tiny TypeScript visualization grammar for responsive, accessible, server-rendered application charts.

Important

TanStack Charts is currently an unpublished 0.0.0 product proof. The packages are not published or ready for production use yet.

Most chart libraries are easy until the chart stops being standard. TanStack Charts gives you one typed grammar that can grow from a familiar line or bar chart into a product-specific visualization without replacing your data model or dropping down to a separate API.

  • Keep your data as it is. Marks consume arrays, objects, tuples, and iterables directly. Different layers can use different datum types.
  • Bring native D3 primitives. Use D3 scales, curves, transforms, and layout output instead of relearning a parallel math API.
  • Build from common to custom. Layer built-in marks or implement a custom mark against the same public scene protocol.
  • Get the application runtime too. Responsive layout, automatic guide margins, themes, interaction, animation, accessibility, SVG SSR, opt-in Canvas painting, hydration, and export are part of the system.
  • Pay for what you import. Marks, renderers, and chart-owned interactions have independent TanStack subpaths; specialized algorithms come directly from granular, tree-shakeable d3-* packages.

Quick look

import { max } from 'd3-array'
import { scaleBand, scaleLinear } from 'd3-scale'
import { barY, defineChart } from '@tanstack/charts'
import { Chart } from '@tanstack/react-charts'

const revenue = [
  { month: 'Jan', value: 42 },
  { month: 'Feb', value: 58 },
  { month: 'Mar', value: 76 },
  { month: 'Apr', value: 64 },
]

const revenueChart = defineChart({
  marks: [
    barY(revenue, {
      x: 'month',
      y: 'value',
    }),
  ],
  x: {
    scale: scaleBand()
      .domain(revenue.map((row) => row.month))
      .padding(0.2),
  },
  y: {
    scale: scaleLinear()
      .domain([0, max(revenue, (row) => row.value) ?? 0])
      .nice(),
    label: 'Revenue',
    grid: true,
  },
})

export function RevenueChart() {
  return (
    <Chart
      definition={revenueChart}
      height={320}
      ariaLabel="Monthly revenue"
      tooltip
    />
  )
}

Marks consume the original rows, channels describe their visual encodings, and configured D3 scales own the domain and mapping. TanStack copies those scales, assigns their responsive pixel ranges, compiles a renderer-neutral keyed scene, and hands that scene to the selected host.

Definitions are framework-independent. The same revenueChart can render through React, Octane, the vanilla DOM host, static SVG, or the optional Canvas renderer.

When SVG element count becomes the bottleneck, switch the adapter import and keep the definition and interaction props:

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

Canvas stays outside the default bundles. React and Octane also expose a renderer-neutral /core entry when an application owns the surface. Canvas removes per-mark DOM cost, not scene memory or dense nearest-point work, so large interactive charts should still use a measured spatial index or a bounded representation.

Packages

Package Role
@tanstack/charts Marks, channels, guides, scene compilation, SVG, optional Canvas, vanilla DOM lifecycle, and export
@tanstack/react-charts Thin React lifecycle adapter with SSR and hydration
@tanstack/octane-charts Thin Octane lifecycle adapter with equivalent scene output

The earlier host experiment remains under @plot-poc/* for migration evidence and benchmark comparison. The private @tanstack/charts-d3 package preserves a superseded backend experiment.

Core model

TanStack Charts deliberately splits ownership:

D3 owns TanStack Charts owns
Scales, shapes, transforms, color, spatial math, and layouts Marks, channels, responsive ranges, guide layout, scene compilation, rendering, and lifecycle

This boundary keeps D3 visible and replaceable at the algorithm level while giving applications a consistent runtime. There is no global registry, library-owned dataframe, or chart-type configuration model.

Lineage

TanStack Charts is an independent implementation. Its conceptual lineage and the projects and people whose work informed it are credited in ACKNOWLEDGEMENTS.md.

Built almost entirely with AI

I designed TanStack Charts and directed its architecture, API, tradeoffs, and final decisions. Almost all of the implementation was produced with AI coding agents under my direct supervision, then reviewed and accepted into the project.

For live application state, defineChart<Input>() keeps expensive preparation separate from visual construction and responsive layout. The definition drives host prop and callback inference, so normal authoring does not require adapter generics, mark-array annotations, or casts. See Chart Definitions for the complete pattern.

Documentation

Start here Use it for
docs/overview.md Product model, responsibilities, and defaults
docs/quick-start.md First complete framework-agnostic chart
docs/concepts/grammar-of-graphics.md Marks, channels, scales, and composition
docs/concepts/scales-and-d3.md The D3 dependency and ownership boundary
docs/examples/index.md Curated chart-family and interaction examples
docs/guides/ai-authoring.md Deterministic authoring and validation for coding agents
docs/reference/index.md Complete public API map
llms.txt Generated documentation routing index

Architecture decisions and open production gates live in PLAN.md. Evidence from real authoring and migration work is tracked in API-FRICTION.md.

Get Involved

Partners

CodeRabbit Cloudflare
Charts and you?

We're looking for TanStack Charts Partners to join our mission! Partner with us to push the boundaries of TanStack Charts and build amazing things together.

LET'S CHAT

Explore the TanStack Ecosystem

… and more at TanStack.com »

Development

The workspace requires Node.js 22 or newer and pnpm 11.

pnpm install
pnpm test
pnpm typecheck
pnpm build
pnpm package:check

Run a local example:

pnpm dev:charts-react
pnpm dev:charts-octane
pnpm dev:sandbox
pnpm dev:conformance

The repository includes three complementary benchmark suites:

pnpm bundle:check
pnpm performance
pnpm benchmark:check
pnpm benchmark:stress:quick
pnpm conformance:quick

These measurements are development evidence, not release claims. See each suite's README for its protocol, output, and limitations.

Pull requests first gate formatting, types, tests, packed exports and declarations, locked bundles, comparison bundles, and catalog metadata. Browser comparison, all 79 conformance cases, and the quick five-library stress matrix then run as separate artifact-producing jobs.

License

MIT © Tanner Linsley. See ACKNOWLEDGEMENTS.md for project lineage.

Releases

Packages

Contributors

Languages