Using with AI agents
react-native-skia-chart is built to be agent-ready. It has predictable props, strict types, and no hidden configuration, so AI coding agents (Cursor, Claude, Grok, Copilot) can generate correct charts on the first try.
Agents can find guidance in three places:
AGENTS.mdat the repo root, which most agents read automatically;/llms.txt, an index for LLM crawlers;example/recipes/agent-recipes.tsx, a set of copy-paste recipes that compile under strict TypeScript (npx tsc --noEmitinexample/).
Every exported prop has JSDoc, so hover info and the .d.ts files carry the same guidance.
:::tip Prompt template
"Using react-native-skia-chart (react-native-skia 3.8), add an interactive area chart of data: number[] with a teal→violet gradient, full width minus 32px, 220px tall. Follow AGENTS.md."
:::
Rules for agents
- Import everything from
'react-native-skia-chart'. Skia isreact-native-skia3.8.0 (not@shopify/react-native-skia). widthandheightare required numbers in pixels. No'100%'. UseuseWindowDimensions()oronLayout.- Data is plain arrays:
number[],{x,y}[], or the typed shapes below. Colours are hex strings ('#7C5CFF'). - Text labels render only when you pass a Skia
font(useFont(require('./Inter.ttf'), 11)). No font means no labels and no error. - Optional styling is opt-in and composable:
gradient(ChartGradient) andeffects(ChartEffects) work on every chart. - Needs a dev build (
npx expo run:ios|android), not Expo Go. Peers: reanimated ≥ 4, react-native-worklets ≥ 0.7, gesture-handler. - For scrubbing, set
interactiveand readonScrub(point | null, index). It runs on the JS thread, so it's safe tosetState.
Pick a component
| Goal | Component | Required data prop |
|---|---|---|
| Trend over time | LineChart / AreaChart | data: number[] | DataPoint[] or series: LineSeries[] |
| Inline trend (list row) | Sparkline | data: number[] |
| Compare categories | BarChart (horizontal, stacked) / StackedBarChart | data: number[] or series: BarSeries[] |
| Distribution of raw values | Histogram | values: number[], bins? |
| Composition over time | StackedAreaChart (percent) | series: {data, color}[] |
| Part of whole | PieChart / DonutChart | data: PieSlice[] ({value, color, label?}) |
| Correlation | ScatterChart / BubbleChart | data: {x, y}[] / {x, y, z}[] |
| Multi-axis profile | RadarChart | axes: string[], series: RadarSeries[] |
| OHLC prices | CandlestickChart / OHLCChart | data: Candle[] ({x, open, high, low, close}) |
| Matrix intensity | HeatmapChart | data: number[][] (row-major) |
| Single KPI | GaugeChart | value: number, min?, max? |
| Goal progress | ProgressRings / ProgressRing | data: RingData[] (progress 0..1) |
Common props (all charts)
width, height (required) · padding?: number | Partial<Padding> · animation?: {duration?, delay?} (duration: 0 disables it) · font? · backgroundColor? · style? · gradient?: ChartGradient · effects?: ChartEffects.
Axis charts also take showGrid, formatY(v) => string and color.
Canonical snippet
import { useWindowDimensions } from 'react-native';
import { AreaChart } from 'react-native-skia-chart';
export function Revenue({ data }: { data: number[] }) {
const { width } = useWindowDimensions();
return (
<AreaChart
data={data}
width={width - 32}
height={220}
curve="monotone"
interactive
gradient={{ type: 'linear', colors: ['#00E0C6', '#7C5CFF'] }}
effects={{ glow: 6, clipReveal: 800 }}
/>
);
}
Don't
- Don't wrap charts in
<Canvas>. Each chart renders its own. - Don't pass strings for numeric values, or
undefinedholes indata. - Don't use
glow: true.glowis a number (blur sigma).shadowacceptstrueor an object. - Don't import from
react-native-skia-chart/src/...or from build paths.
More patterns
// Scrub readout
const [p, setP] = useState<DataPoint | null>(null);
<LineChart data={points} width={w} height={200} interactive onScrub={(pt) => setP(pt)} />
// Grouped vs stacked bars
<BarChart width={w} height={200} series={[{ data: [3, 4], color: '#7C5CFF' }, { data: [2, 5], color: '#00E0C6' }]} />
<BarChart width={w} height={200} stacked series={...} />
// KPI gauge with gradient stops
<GaugeChart width={220} height={180} value={72} gradient={['#FF5A5F', '#FFC048', '#2FD47A']} />
// Typed effect presets you can reuse
const neon: ChartEffects = { glow: 6, shadow: true, clipReveal: 800 };
See Charts for each component's full props, Gradients, GPU effects and the API reference.
Interactivity
- Scrubbing:
interactive(default true) andonScrubon Line, Area and Candlestick. Inside scroll views, usescrubActivation="longPress". - Selection:
selectable,selectedIndexandonSelect(index | null)on Bar, Pie/Donut, Scatter, Bubble, Heatmap and ProgressRings. Unselected marks dim. - Zoom:
zoom(trueor{ min, max, doubleTap }) on axis charts. Pinch to zoom, two-finger pan, double-tap to toggle 2x or reset. Touches are mapped back to chart coordinates, so selection and scrubbing still work while zoomed. - Custom charts:
ChartFrame,ZoomGroup,useSelection(props, hitTestWorklet)anduseHighlight(selected, index).