diff --git a/README.md b/README.md
index a7e1abe..9a05d80 100644
--- a/README.md
+++ b/README.md
@@ -2,37 +2,43 @@
-
- React bindings for ChartGPU — The fastest open-source charting library — 50M points at 60 FPS.
+
+ React bindings for ChartGPU: MIT-licensed WebGPU charts for dense real-time, multi-series and multi-panel dashboards.
-[

](https://forthebadge.com)
-[](https://github.com/chartgpu/chartgpu-react/blob/main/docs/GETTING_STARTED.md)
-[](https://github.com/chartgpu/chartgpu-react/blob/main/docs/API.md)
-[](https://github.com/chartgpu/chartgpu-react/tree/main/examples)
+[

](#browser-support-webgpu-required)
[](https://www.npmjs.com/package/chartgpu-react)
[](https://www.npmjs.com/package/chartgpu-react)
-[](https://www.npmjs.com/package/chartgpu-react)
+[](https://github.com/ChartGPU/chartgpu-react/blob/main/LICENSE)
+[](https://chartgpu.io)
+[](https://chartgpu.io/docs/getting-started/)
+[](./docs/API.md)
[

](https://news.ycombinator.com/item?id=46706528)
[

](https://github.com/mikbry/awesome-webgpu)
-
-`chartgpu-react` is a **thin React + TypeScript wrapper** around the [`@chartgpu/chartgpu`](https://www.npmjs.com/package/@chartgpu/chartgpu) core library.
+`chartgpu-react` is a thin React + TypeScript wrapper around [`@chartgpu/chartgpu`](https://www.npmjs.com/package/@chartgpu/chartgpu): lifecycle, resize, events, refs, and multi-chart GPU sharing in React. Core charting stays in ChartGPU (MIT commercial embed, zero npm runtime dependencies in core, WebGPU required, no WebGL fallback).
+
+Use it when Chart.js, ECharts, or uPlot hit streaming or multi-panel walls. Commercial GPU seats often ship WebGL fallback and broader catalog; ChartGPU is the open WebGPU-only embed.
+
+Demo and docs: [chartgpu.io](https://chartgpu.io) · [docs](https://chartgpu.io/docs/) · [streaming dashboards](https://chartgpu.io/docs/streaming-dashboards/) · [core repo](https://github.com/ChartGPU/ChartGPU)
+
+---
+
+## Install
-## Highlights
+```bash
+npm install chartgpu-react @chartgpu/chartgpu react react-dom
+```
-- **`ChartGPU` component (recommended)**: async create/dispose lifecycle + debounced `ResizeObserver` sizing
-- **Event props**: `onClick`, `onCrosshairMove`, `onZoomChange`, `onDataAppend`, `onDeviceLost`, etc.
-- **Imperative `ref` API**: `ChartGPUHandle` (`getChart`, `getContainer`, `appendData` with optional `{ maxPoints }` FIFO, `setOption`, `setZoomRange`, `setInteractionX`, `getInteractionX`, `hitTest`, `needsRender`, `renderFrame`, `getRenderMode`, `setRenderMode`)
-- **Hooks**: `useChartGPU(...)`, `useGPUContext()`, `useConnectCharts(..., syncOptions?)`
-- **Multi-chart + streaming**: share a `GPUDevice` via `gpuContext` / `useGPUContext`, sync with `useConnectCharts`, stream with `appendData(..., { maxPoints })`
-- **Helper re-exports (from `@chartgpu/chartgpu`)**: `createChart`, `connectCharts`, `createPipelineCache`, `getPipelineCacheStats`, `destroyPipelineCache`, `createAnnotationAuthoring`
+Peer dependency: **`@chartgpu/chartgpu` ^0.3.6** (aligned with this package’s 0.3.x line). React 18 or 19.
+
+---
## Quick start
@@ -45,16 +51,11 @@ function MyChart() {
series: [
{
type: 'line',
- data: [
- { x: 0, y: 0 },
- { x: 1, y: 1 },
- { x: 2, y: 4 },
- { x: 3, y: 9 },
- ],
- lineStyle: {
- width: 2,
- color: '#667eea',
+ data: {
+ x: new Float64Array([0, 1, 2, 3]),
+ y: new Float64Array([0, 1, 4, 9]),
},
+ lineStyle: { width: 2, color: '#667eea' },
},
],
xAxis: { type: 'value' },
@@ -65,81 +66,36 @@ function MyChart() {
}
```
-## Installation
+Object / `[x,y]` tuples are fine for tiny demos; prefer typed-array columns at scale.
-```bash
-npm install chartgpu-react @chartgpu/chartgpu react react-dom
-```
+---
-Peer dependency: **`@chartgpu/chartgpu` ^0.3.6** (aligned with this package’s 0.3.x line).
+## Why chartgpu-react
-### Requirements
+| | |
+|---|---|
+| **React lifecycle** | Async create/dispose, debounced `ResizeObserver` sizing |
+| **Dense real-time jobs** | Multi-series streaming, multi-panel dashboards, finance, heatmaps (via core) |
+| **Shared-device multi-panel** | `useGPUContext` / `gpuContext` prop (recommended for ≥3 charts); `useConnectCharts` / `connectCharts` |
+| **Ring FIFO streaming** | `ref.appendData(..., { maxPoints })`; heatmap/surface stream APIs on core |
+| **Events and refs** | `onClick`, `onCrosshairMove`, `onZoomChange`, `onDataAppend`, `onDeviceLost`, …; `ChartGPUHandle` imperative API |
+| **MIT commercial embed** | MIT wrapper; core density stays free under MIT with no feature gates on FIFO, zoom, multi-chart, or finance series |
+| **WebGPU-only** | Same browser gate as core; no WebGL fallback |
-- **React 18 or 19** (`react` / `react-dom` ≥ 18)
-- **TypeScript 5+** for consumers (this package is built and typechecked with **TypeScript 7**)
-- Browser with WebGPU support:
- - Chrome/Edge 113+
- - Safari 18+
- - Firefox: Windows 114+, Mac 145+, Linux nightly
-
-Check browser compatibility at [caniuse.com/webgpu](https://caniuse.com/webgpu).
+---
## What this package provides
-- **`ChartGPU`** React component (recommended)
- - lifecycle management (async create + dispose)
- - `ResizeObserver` resize (debounced)
- - event props: `onClick`, `onCrosshairMove`, `onZoomChange`, `onDataAppend`, `onDeviceLost`, etc.
- - multi-chart dashboards: `gpuContext` prop (share a `GPUDevice` across charts)
- - imperative `ref` API: `ChartGPUHandle` (`getChart`, `getContainer`, `appendData`, `setOption`, `setZoomRange`, `setInteractionX`, `getInteractionX`, `hitTest`, `needsRender`, `renderFrame`, `getRenderMode`, `setRenderMode`)
-- **Hooks**
- - `useChartGPU(containerRef, options, gpuContext?)` — create/manage a chart instance (optionally share GPU resources)
- - `useGPUContext()` — create a shared `GPUAdapter` + `GPUDevice` + `PipelineCache` for multi-chart dashboards
- - `useConnectCharts([chartA, chartB, ...], syncOptions?)` — sync crosshair/interaction-x (and optionally zoom) across charts
-- **Deprecated**
- - `ChartGPUChart` (legacy adapter; use `ChartGPU` instead)
-- **Helper re-exports** (from peer dependency `@chartgpu/chartgpu`)
- - `createChart`, `connectCharts`, `createAnnotationAuthoring`, `createPipelineCache`, `getPipelineCacheStats`, `destroyPipelineCache`
-
-For details, start with the [API reference](./docs/API.md).
+- **`ChartGPU`** component (recommended): create/dispose, resize, event props, `gpuContext`, `ref` / `ChartGPUHandle`
+- **Hooks:** `useChartGPU`, `useGPUContext`, `useConnectCharts`
+- **Deprecated:** `ChartGPUChart` (use `ChartGPU`)
+- **Re-exports from core:** `createChart`, `connectCharts`, `createAnnotationAuthoring`, `createPipelineCache`, `getPipelineCacheStats`, `destroyPipelineCache`
-## Feature snippets (ChartGPU core)
-
-These snippets use helpers and events from the `@chartgpu/chartgpu` core library (peer dependency of `chartgpu-react`).
-
-### Crosshair / interaction X (`'crosshairMove'`)
-
-```tsx
-import { ChartGPU } from 'chartgpu-react';
-import type { ChartGPUCrosshairMovePayload } from 'chartgpu-react';
-
- {
- // p.x is the current interaction x (domain units), or null when cleared
- console.log('crosshair x:', p.x, 'source:', p.source);
- }}
-/>;
-```
-
-### Connect charts (sync crosshair/tooltip)
-
-```tsx
-import { connectCharts } from 'chartgpu-react';
-
-// When you have two ChartGPUInstance objects:
-const disconnect = connectCharts([chartA, chartB]);
-
-// With zoom sync:
-// const disconnect = connectCharts([chartA, chartB], { syncZoom: true });
-
-// Later:
-disconnect();
-```
+Details: [API reference](./docs/API.md) · [Getting started](./docs/GETTING_STARTED.md)
-If you prefer a hook-driven approach, you can use `onReady` (or `useChartGPU`) to capture instances, then call `useConnectCharts(...)` once both are available.
+---
-### Streaming append with FIFO window (`maxPoints`)
+## Streaming append with FIFO (`maxPoints`)
```tsx
import { useEffect, useRef } from 'react';
@@ -148,12 +104,16 @@ import type { ChartGPUHandle } from 'chartgpu-react';
function StreamingChart() {
const ref = useRef(null);
- const xRef = useRef(0);
+ const t = useRef(0);
useEffect(() => {
const id = window.setInterval(() => {
- const x = xRef.current++;
- ref.current?.appendData(0, [{ x, y: Math.sin(x * 0.05) }], { maxPoints: 50_000 });
+ const x0 = t.current;
+ const x = new Float64Array([x0, x0 + 1, x0 + 2]);
+ const y = new Float64Array([Math.sin(x0 * 0.05), Math.sin((x0 + 1) * 0.05), Math.sin((x0 + 2) * 0.05)]);
+ t.current += 3;
+ // Density path: column payload + fixed-capacity ring
+ ref.current?.appendData(0, { x, y }, { maxPoints: 50_000 });
}, 16);
return () => window.clearInterval(id);
}, []);
@@ -163,7 +123,13 @@ function StreamingChart() {
ref={ref}
options={{
autoScroll: true,
- series: [{ type: 'line', data: [], lineStyle: { width: 2, color: '#4facfe' } }],
+ series: [
+ {
+ type: 'line',
+ data: { x: new Float64Array(0), y: new Float64Array(0) },
+ lineStyle: { width: 2, color: '#4facfe' },
+ },
+ ],
xAxis: { type: 'value' },
yAxis: { type: 'value' },
}}
@@ -173,33 +139,9 @@ function StreamingChart() {
}
```
-### External render mode (app-owned render loop)
-
-```tsx
-import { useEffect, useRef } from 'react';
-import { ChartGPU } from 'chartgpu-react';
-import type { ChartGPUHandle } from 'chartgpu-react';
-
-function ExternalLoop() {
- const ref = useRef(null);
-
- useEffect(() => {
- let raf = 0;
- const loop = () => {
- if (ref.current?.needsRender()) {
- ref.current.renderFrame();
- }
- raf = requestAnimationFrame(loop);
- };
- raf = requestAnimationFrame(loop);
- return () => cancelAnimationFrame(raf);
- }, []);
-
- return ;
-}
-```
+---
-### Multi-chart dashboards (shared GPU device + pipeline cache)
+## Multi-chart dashboards (shared GPU device)
```tsx
import { ChartGPU, useGPUContext } from 'chartgpu-react';
@@ -216,22 +158,77 @@ function Dashboard() {
return (
<>
-
-
+
+
+
>
);
}
```
-### Annotation authoring UI (`createAnnotationAuthoring`)
+Recommended for ≥3 charts. Full recipes: [streaming dashboards](https://chartgpu.io/docs/streaming-dashboards/) · [chart-sync recipe](./docs/recipes/chart-sync.md) · [core multi-chart cookbook](https://github.com/ChartGPU/ChartGPU/blob/main/docs/guides/multichart-dashboard-cookbook.md)
+
+---
+
+## More feature snippets
+
+### Crosshair / interaction X
```tsx
-import { useEffect, useRef, useState } from 'react';
import { ChartGPU } from 'chartgpu-react';
+import type { ChartGPUCrosshairMovePayload } from 'chartgpu-react';
+
+ {
+ console.log('crosshair x:', p.x, 'source:', p.source);
+ }}
+/>;
+```
+
+### Connect charts (sync crosshair / zoom)
+
+```tsx
+import { connectCharts } from 'chartgpu-react';
+
+const disconnect = connectCharts([chartA, chartB], { syncZoom: true });
+// later: disconnect();
+```
+
+Prefer `useConnectCharts(...)` when instances come from `onReady` / `useChartGPU`.
+
+### External render mode (app-owned rAF)
+
+```tsx
+import { useEffect, useRef } from 'react';
+import { ChartGPU } from 'chartgpu-react';
+import type { ChartGPUHandle } from 'chartgpu-react';
+
+function ExternalLoop({ options }) {
+ const ref = useRef(null);
+
+ useEffect(() => {
+ let raf = 0;
+ const loop = () => {
+ if (ref.current?.needsRender()) ref.current.renderFrame();
+ raf = requestAnimationFrame(loop);
+ };
+ raf = requestAnimationFrame(loop);
+ return () => cancelAnimationFrame(raf);
+ }, []);
+
+ return ;
+}
+```
+
+### Annotation authoring
+
+```tsx
+import { useEffect, useRef, useState } from 'react';
+import { ChartGPU, createAnnotationAuthoring } from 'chartgpu-react';
import type { ChartGPUHandle, ChartGPUInstance } from 'chartgpu-react';
-import { createAnnotationAuthoring } from 'chartgpu-react';
-function AnnotationAuthoringExample() {
+function AnnotationAuthoringExample({ options }) {
const chartRef = useRef(null);
const [chart, setChart] = useState(null);
@@ -243,8 +240,6 @@ function AnnotationAuthoringExample() {
const authoring = createAnnotationAuthoring(container, instance, {
enableContextMenu: true,
});
-
- // IMPORTANT: dispose authoring before disposing the chart
return () => authoring.dispose();
}, [chart]);
@@ -252,13 +247,12 @@ function AnnotationAuthoringExample() {
}
```
-### Candlestick streaming (`appendData` + `OHLCDataPoint`)
+### Candlestick streaming
```tsx
import { useEffect, useRef } from 'react';
import { ChartGPU } from 'chartgpu-react';
-import type { ChartGPUHandle, ChartGPUOptions } from 'chartgpu-react';
-import type { OHLCDataPoint } from 'chartgpu-react';
+import type { ChartGPUHandle, ChartGPUOptions, OHLCDataPoint } from 'chartgpu-react';
function CandlestickStreaming() {
const ref = useRef(null);
@@ -267,13 +261,7 @@ function CandlestickStreaming() {
xAxis: { type: 'time' },
dataZoom: [{ type: 'inside' }, { type: 'slider' }],
autoScroll: true,
- series: [
- {
- type: 'candlestick',
- sampling: 'ohlc',
- data: [], // start empty; stream in candles below
- },
- ],
+ series: [{ type: 'candlestick', sampling: 'ohlc', data: [] }],
};
useEffect(() => {
@@ -294,74 +282,95 @@ function CandlestickStreaming() {
}
```
+---
+
## Documentation
-- **Getting started**: [`docs/GETTING_STARTED.md`](./docs/GETTING_STARTED.md)
-- **API reference**: [`docs/API.md`](./docs/API.md)
-- **Recipes**:
- - [`onCrosshairMove`](./docs/recipes/crosshair-move.md)
- - [`useConnectCharts` / `connectCharts`](./docs/recipes/chart-sync.md)
- - [`createAnnotationAuthoring`](./docs/recipes/annotation-authoring.md)
- - [`appendData` streaming](./docs/recipes/streaming.md)
- - [`dataZoom` + `onZoomChange`](./docs/recipes/datazoom-basics.md)
+### chartgpu.io (core product)
+
+| | |
+|---|---|
+| [Docs hub](https://chartgpu.io/docs/) | Guides and series docs |
+| [Getting started](https://chartgpu.io/docs/getting-started/) | Install and first chart |
+| [Streaming dashboards](https://chartgpu.io/docs/streaming-dashboards/) | Shared device, multi-chart |
+| [Performance](https://chartgpu.io/docs/performance/) | Density, sampling, GPU sharing |
+
+### This repository (React)
+
+| | |
+|---|---|
+| [Getting started](./docs/GETTING_STARTED.md) | React install and first component |
+| [API](./docs/API.md) | Component, hooks, handle |
+| [Recipes](./docs/recipes/) | Crosshair, sync, streaming, annotations, dataZoom |
+
+---
## Examples
-- Runnable example app: [`examples/main.tsx`](./examples/main.tsx)
-- Run locally:
- - `npm install`
- - `npm run dev` (opens `http://localhost:3000/examples/index.html`)
+```bash
+npm install
+npm run dev
+# http://localhost:3000/examples/index.html
+```
+
+See [`examples/main.tsx`](./examples/main.tsx).
+
+---
+
+## Browser support (WebGPU required)
+
+No WebGL fallback. Gate unsupported browsers in your app (capability detect; never a blank canvas).
+
+| Browser | Notes |
+|---------|--------|
+| Chrome / Edge | 113+ |
+| Safari | 18+ |
+| Firefox | Windows 114+, macOS 145+, Linux still incomplete on [gpuweb status](https://github.com/gpuweb/gpuweb/wiki/Implementation-Status) |
+
+```ts
+if (!navigator.gpu) {
+ // fail closed: show UI, do not leave an empty chart
+}
+```
+
+WebGPU-only is intentional. Need Canvas/SVG or dual WebGL+WebGPU? Use a stack that ships a fallback.
+
+---
## Development
```bash
-# Install dependencies
npm install
-
-# Run type checking
npm run typecheck
-
-# Build library
npm run build
-
-# Run examples in dev mode
npm run dev
```
-The dev server will start at `http://localhost:3000` and open the examples page automatically.
-
### Local development with linked ChartGPU
-To develop `chartgpu-react` against a local version of the `@chartgpu/chartgpu` package (useful for testing changes across both repositories):
-
```bash
-# 1. Link the @chartgpu/chartgpu package from the sibling repo
-cd ../chart-gpu
+# From sibling ChartGPU clone (directory name may vary)
+cd ../ChartGPU
npm link
-# 2. Link @chartgpu/chartgpu into this project
cd ../chartgpu-react
npm link @chartgpu/chartgpu
-
-# 3. Build and run - will use the linked local package
npm run build
npm run dev
```
-**Note:** After linking, `npm run build` and `npm run dev` will resolve imports to your local `@chartgpu/chartgpu` package instead of the published version. This allows you to test changes in both repos simultaneously.
-
-To unlink and return to the published package:
+Unlink:
```bash
npm unlink @chartgpu/chartgpu
npm install
```
-## Type exports
+---
-The package re-exports common types from ChartGPU for convenience:
+## Type exports
-```typescript
+```ts
import type {
ChartGPUInstance,
ChartGPUOptions,
@@ -371,46 +380,30 @@ import type {
ChartGPUHitTestResult,
ChartGPUHitTestMatch,
ChartSyncOptions,
- AreaSeriesConfig,
LineSeriesConfig,
+ AreaSeriesConfig,
BarSeriesConfig,
- PieSeriesConfig,
ScatterSeriesConfig,
+ PieSeriesConfig,
SeriesConfig,
- LineStyleConfig,
- AreaStyleConfig,
DataPoint,
- LegendConfig,
- LegendPosition,
- AnimationConfig,
+ OHLCDataPoint,
TooltipConfig,
- TooltipParams,
PerformanceMetrics,
} from 'chartgpu-react';
```
-## Browser support (WebGPU required)
-
-WebGPU is required. Check support at runtime:
-
-```typescript
-const checkSupport = async () => {
- if (!('gpu' in navigator)) {
- console.warn('WebGPU not supported');
- return false;
- }
- return true;
-};
-```
+---
## Contributing
-Issues and pull requests are welcome. If you're planning a larger change, open an issue first so we can discuss direction.
+Issues and pull requests welcome. For larger changes, open an issue first.
## License
-MIT
+[MIT](LICENSE). Free for commercial embedding. ChartGPU core keeps density, FIFO, multi-chart, and finance series in the open core.
-## Related Projects
+## Related
-- [ChartGPU](https://github.com/ChartGPU/ChartGPU) - Core WebGPU charting library
+- [ChartGPU](https://github.com/ChartGPU/ChartGPU) — core WebGPU charting library
+- [chartgpu.io](https://chartgpu.io) — demos and docs