
Description
Ship TanStack Charts with meaningful accessibility, deterministic SSR and hydration, correct adapter lifecycle, renderer and export choices, exact package subpaths, and explicit React Native validation.
SKILL.md
Ship Accessible Charts
Run trigger → inspect → decide → build → verify before release. A chart is shipped only when its semantic alternative, adapter lifecycle, SSR policy, renderer, exports, package boundaries, and teardown are proven in a consumer-shaped scenario.
Accessibility Checks
Check: the name identifies the comparison
Expected:
const hostOptions = {
definition,
height: 320,
initialWidth: 640,
ariaLabel: 'Weekly downloads for Core and React packages',
ariaDescription: 'Values are seven-day totals. Missing weeks appear as gaps.',
}
Fail condition: the label says only “chart”, repeats a visible heading without the metric, or omits the comparison and period.
Fix: name the metric, compared entities, and time scope; put conclusions and detailed values in normal application content.
Check: critical values have an equivalent representation
Expected: a visible heading and units, plus an adjacent summary or semantic table when precise values or application decisions depend on the chart.
Fail condition: the only way to retrieve an essential value is pointer hover, color, motion, or visual estimation.
Fix: bind the same semantic rows or selected key to application text/table controls.
Check: every interaction has a non-pointer path
Expected: native point keyboard navigation, semantic buttons/inputs for free cursors and range controls, visible focus, cancel/reset paths, and meaningful committed-state text.
Fail condition: a transparent pointer overlay is the sole control surface.
Fix: use first-party controls where their keyboard contract fits and application-owned semantic controls otherwise.
Lifecycle Checks
Check: SSR uses a supported adapter and deterministic inputs
Expected:
import {
createChartRuntime,
defineChart,
lineY,
renderChartSvg,
} from '@tanstack/charts'
import { scaleLinear } from '@tanstack/charts/scales/linear'
import { scaleUtc } from 'd3-scale'
interface TrafficRow {
date: Date
visits: number
}
const rows: readonly TrafficRow[] = [
{ date: new Date('2026-08-10T00:00:00Z'), visits: 820 },
{ date: new Date('2026-08-11T00:00:00Z'), visits: 910 },
]
const definition = defineChart({
marks: [lineY(rows, { x: 'date', y: 'visits' })],
x: { scale: scaleUtc },
y: { scale: scaleLinear },
})
const runtime = createChartRuntime<TrafficRow, Date, number>()
const scene = runtime.render(definition, { width: 720, height: 400 })
export const svg = renderChartSvg(scene, {
ariaLabel: 'Daily traffic',
idPrefix: 'daily-traffic',
})
runtime.destroy()
Fail condition: definition construction reads browser layout, random values, local time, or unresolved async data; or the selected adapter does not promise SSR.
Fix: resolve data before render, use deterministic formatting and dimensions, and follow the selected adapter reference.
Check: mount, update, and cleanup stay adapter-owned
Expected: one runtime per mounted adapter instance, complete immutable option updates, stable definitions until captured values change, and cleanup on unmount/disconnect.
Fail condition: application code calls DOM measurement or mounts a browser host during server render, or retains observers/listeners after removal.
Fix: use the adapter lifecycle or mountChart only in a browser-owned mount phase and call destroy() at teardown.
Renderer and Export Checks
Check: renderer choice matches the task
- SVG: visible server geometry, vector export, DOM styling, ordinary interactive charts.
- Canvas: high scene counts or raster-first output; server emits an accessible shell, not pixels.
- Static SVG: deterministic server/export artifact without browser interaction.
- React Native SVG: explicit native target with device-level validation.
Check: export is reproducible
Expected: explicit dimensions, theme/background, scoped IDs, portable fonts/assets, intentional focus inclusion, and a meaningful exported name/description.
Fail condition: export depends on current responsive pixels or unreachable application CSS/resources.
Fix: render an explicit scene or serialize/rasterize with explicit artifact policy.
Common Mistakes
CRITICAL Using a generic accessible label
Wrong: ariaLabel: 'Chart'.
Correct: identify the metric, entities, period, and unit needed to understand the figure.
A generic label exposes a focusable graphic without useful identity.
Source: docs/guides/accessibility.md
HIGH Making the chart the only representation
Wrong: require hover or visual estimation for exact operational values.
Correct: render a summary, table, or application controls from the same semantic data/state.
The chart surface is supplemental when exact values are critical.
Source: docs/guides/accessibility.md; archived responsive/accessibility notes
CRITICAL Mounting a browser host during server rendering
Wrong: call mountChart or adapter DOM mount from a server lifecycle.
Correct: prerender a deterministic scene through a supported SSR adapter or renderChartSvg, then mount the browser host only after a real element exists.
Measurement and mutation require browser elements. Older Angular workarounds were especially prone to this boundary error.
Source: GitHub issue 56; docs/guides/ssr-and-hydration.md
HIGH Putting behavior on adapter props
Wrong:
<Chart definition={chart} tooltip keyboard />
Correct:
const interactive = defineChart(chart, { tooltip, keyboard: true })
<Chart definition={interactive} ariaLabel="Revenue by month" />
Focus, tooltip, keyboard, controls, cursors, and SVG animation belong to the reusable definition; adapters own surface lifecycle and framework body composition. The current definition API replaces legacy adapter behavior props.
Source: chart-behavior migration in CHANGELOG.md; React chart reference
HIGH Importing the universal barrel on native
Wrong: use @tanstack/charts/universal for every native chart.
Correct: use exact core mark/scale/scene and @tanstack/charts/react-native subpaths unless cross-platform authoring justifies the universal bundle.
Exact imports protect Metro and native declaration environments from unrelated browser and optional capability code.
Source: API-FRICTION.md F-154, F-171, F-173, F-256; React Native package README
HIGH Tension: rich interaction versus portable rendering
DOM convenience can break static SVG, Canvas, native, SSR, or keyboard equivalence. Keep semantics in definitions and application state; use platform-specific body/host extensions only at the presentation seam.
See also: build-chart-interactions/SKILL.md and extend-tanstack-charts/SKILL.md
Pre-Deploy Summary
- Meaningful name and concise description.
- Visible units, time range, and source context.
- Exact-value summary/table where required.
- Pointer, keyboard, touch, and cancel/reset scenarios.
- Reduced-motion and non-color evidence.
- Supported SSR policy with deterministic initial geometry.
- Stable definition, mark, datum, and resource IDs.
- Mount, update, resize, font relayout, and destroy verified.
- Renderer and export behavior verified from a packed consumer.
- Native claims verified on target devices when applicable.
References
See also: debug-and-verify-charts/SKILL.md — SSR, accessibility, renderer, and package claims need consumer-level evidence.
More skills from the charts repository
View all 12 skillsbuild-chart-interactions
build chart interactions with TanStack Charts
Aug 15ChartsFrontendInteractionTanStackcompose-marks-and-views
compose marks and views in TanStack Charts
Aug 15ChartsFrontendTanStackUI Componentsconfigure-scales-guides-color
configure scales and guides for TanStack Charts
Aug 15ChartsData VisualizationFrontendTanStackcoordinate-charts-with-tanstack
coordinate TanStack Charts with data sources
Aug 15ChartsData AnalysisData EngineeringFrontend +1debug-and-verify-charts
debug and verify TanStack Charts
Aug 15ChartsDebuggingFrontendTanStackdesign-a-chart
design charts with TanStack Charts
Aug 15ChartsData VisualizationFrontendTanStack
More from TanStack
View publisheraggregation
perform data aggregation in TanStack Table
table
Aug 11Data AnalysisFrontendTanStackapi-not-found
diagnose TanStack Table API errors
table
Aug 11DebuggingFrontendTanStackcell-selection
select rectangular cell ranges in tables
table
Aug 11Data AnalysisTanStackUI Componentscell-spanning
configure cell spanning in TanStack Table
table
Aug 11Data VisualizationFrontendTanStackUI Componentsclient-vs-server
manage TanStack Table data pipelines
table
Aug 11Data PipelineFrontendPerformanceTanStackcolumn-faceting
build faceted filter UIs
table
Aug 11Data VisualizationFrontendTanStack