react-native-graph is a free, open source design & prototyping project written in TypeScript and released under MIT. It has 2,633 GitHub stars, 137 forks and 31 open issues, and was last pushed 22 days ago. On this registry it ranks #58 of 93 tracked projects in Design & Prototyping, with 5 head-to-head comparisons available.

What is react-native-graph?

react-native-graph is an MIT-licensed React Native charting library that draws animated line graphs through Skia, aimed at developers building crypto, token, and wallet screens that need smooth scrolling and gesture performance.

What it is

react-native-graph is a TypeScript library for React Native that exposes a LineGraph component, rendered by the high-performance 2D graphics engine Skia from @shopify/react-native-skia and driven by react-native-reanimated and react-native-gesture-handler for animation and touch handling. It ships as a single line-graph implementation rather than a general-purpose chart suite, with an animated prop that switches between an animated renderer and a lightweight static renderer. The project lives in the React Native ecosystem and its README documents props, a typed GraphPoint shape, and an Expo example.

The concrete problem it solves is drawing many small time-series graphs on a mobile screen without degrading the surrounding interface. It replaces hand-built chart rendering on top of react-native-svg with native path interpolation inside Skia, so graphs animate at up to 120 FPS and, in the project's own words, do not block navigation, press, or scroll animations. The README notes that it already powers thousands of token graphs every day in the Bamboo app, which is the scale case it was written for.

Key capabilities

  • Native path interpolation in Skia with animations running at up to 120 FPS, using cubic bezier rendering for smoother edges on the graph line.
  • A pan and scrubbing gesture enabled through enablePanGesture, with a configurable panGestureDelay (default 300 ms, or 0 to start immediately) and onGestureStart, onPointSelected, and onGestureEnd callbacks.
  • A selectable scrub marker via the SelectionDot component prop, which can be replaced with a custom component or set to null to hide it.
  • Vertical area fills through gradientFillColors, available when animated={true}, plus a lineThickness default of 3 points and an enableFadeInMask option that fades in the start of the line.
  • Axis control through the range prop, which overrides all or part of the visible x-axis and y-axis ranges when the inferred range from points is not what you want.
  • Root-view passthrough of React Native ViewProps, so the graph container participates in normal layout and styling.
  • Rendering stays off the main interaction path: the README states it does not block navigation, press, or scroll animations.

Who uses it and how

  • The Bamboo app uses it to power thousands of token graphs every day, which is the reference deployment described in the README.
  • Crypto applications and wallets are the stated target, plotting price history where each GraphPoint carries a Date and a numeric value.
  • Teams supply their own data: the library does not fetch anything or expose a usePriceHistory hook, so callers build GraphPoint[] from their own API, state, or local data and keep points ordered from oldest to newest.
  • Developers evaluating it can run the Expo example from the example directory in Expo Go on Expo SDK 57, using the SDK's compatible versions of Skia, Reanimated, Worklets, and Gesture Handler, without building a custom development client.

Getting started

Install with yarn add react-native-reanimated react-native-gesture-handler @shopify/react-native-skia react-native-graph (Reanimated additionally requires react-native-worklets), or start the bundled Expo example from its example directory and open it in Expo Go.

How it compares

The README positions it directly against graphs built with react-native-svg, claiming faster and smoother rendering because interpolation happens natively in Skia rather than through SVG path updates. It is a narrower tool than a general charting suite: it draws line graphs with an area fill and a scrub gesture, and leaves bars, pies, and categorical axes to other libraries.

When to use it β€” and when not

Choose it for time-series line charts on a date-based x-axis; do not choose it if you need categorical string values on the x-axis, since those are explicitly unsupported, or if you want the library to fetch or transform data, which it does not do. Be aware that the selectionDotShadowColor prop is documented as having no visual effect, and the repository carries 31 open issues, so some rough edges remain. Like any React Native native-module dependency, adopting it means taking on Reanimated, Worklets, Gesture Handler, and Skia as transitive requirements in your build.

project readme (upstream, from github) β€” read inline

πŸ“ˆ
react-native-graph

Beautiful, high-performance Graphs/Charts for React Native.

About

react-native-graph is a Line Graph implementation based on the high performance 2D graphics rendering engine "Skia". It's used in the Bamboo app to power thousands of token graphs every day.

  • 🏎️ Faster and smoother than react-native-svg graphs
  • ⚑️ Native path interpolation in Skia
  • 🐎 Up to 120 FPS animations
  • πŸ“ˆ Cubic bezier rendering for smoother edges
  • πŸ‘ Smooth pan/scrubbing gesture
  • πŸ’° Made for crypto apps and Wallets
  • ❌ Does not block navigation, press or scroll animations

Installation

yarn add react-native-reanimated # Reanimated requires react-native-worklets
yarn add react-native-gesture-handler
yarn add @shopify/react-native-skia
yarn add react-native-graph

Expo

The Expo example runs in Expo Go with Expo SDK 57. Install react-native-graph alongside the Expo SDK's compatible versions of Skia, Reanimated, Worklets, and Gesture Handler. Start the example from its example directory and open it in Expo Go to try the graph without building a custom development client.

Usage

import { LineGraph, type GraphPoint } from 'react-native-graph';

const priceHistory: GraphPoint[] = [
  { date: new Date('2026-08-27T00:00:00Z'), value: 3.44 },
  { date: new Date('2026-08-28T00:00:00Z'), value: 3.51 },
  { date: new Date('2026-08-29T00:00:00Z'), value: 3.49 },
];

function App() {
  return (
    <LineGraph
      style={{ height: 200 }}
      points={priceHistory}
      animated={false}
      color="#4484B2"
    />
  );
}

react-native-graph does not fetch data or provide a usePriceHistory hook. Create the GraphPoint[] from your own API, state, or local data. Each point uses a Date for its horizontal position and a number for its vertical value; keep the points ordered from oldest to newest. Categorical string values are not supported on the x-axis.

Configuration

LineGraph accepts the following props. It also accepts React Native ViewProps, which are forwarded to the root view.

Prop Type Default Availability Description
animated boolean false Always Uses the animated renderer when true and the lightweight static renderer when false.
points GraphPoint[] None. Required. Always The points to draw. Each point contains a numeric value and a Date. The graph scales to fit them unless range overrides an axis.
color string None. Required. Always The graph line color.
range GraphRange undefined. Both axes are inferred from points. Always Overrides all or part of the visible x-axis and y-axis ranges.
gradientFillColors Color[] undefined. No area fill is drawn. animated={true} Colors for the vertical gradient below the graph line.
lineThickness number 3 Always The graph line width in points.
enableFadeInMask boolean false Always Fades in the start of the graph line.
enablePanGesture boolean false animated={true} Lets the user press and scrub through graph points.
panGestureDelay number 300 animated={true} Time in milliseconds that a press must be held before scrubbing starts. Set it to 0 to start immediately.
onGestureStart () => void undefined. No callback runs. animated={true} Called when scrubbing starts.
onPointSelected (point: GraphPoint) => void undefined. No callback runs. animated={true} Called when scrubbing reaches a different point.
onGestureEnd () => void undefined. No callback runs. animated={true} Called when scrubbing ends.
SelectionDot ComponentType | null Built-in SelectionDot animated={true} Renders the current scrub position. Pass null to hide it.
selectionDotShadowColor string undefined animated={true} Currently unused. This prop has no visual effect.
horizontalPadding number 10 when the indicator is enabled, otherwise 0 animated={true} Adds space to both horizontal edges of the drawing area.
verticalPadding number The value of lineThickness animated={true} Adds space to both vertical edges of the drawing area.
enableIndicator boolean false animated={true} Shows an indicator at the last graph point.
indicatorPulsating boolean false animated={true} Pulses the indicator while the graph is idle. Requires enableIndicator.
TopAxisLabel () => ReactElement | null undefined. Nothing is rendered. animated={true} Renders a label above the graph.
BottomAxisLabel () => ReactElement | null undefined. Nothing is rendered. animated={true} Renders a label below the graph.

Data types

interface GraphPoint {
  value: number;
  date: Date;
}

interface GraphRange {
  x?: { min: Date; max: Date };
  y?: { min: number; max: number };
}

You can provide either axis in range and let the graph infer the other one from points.

Prop examples

animated

Whether to animate between data changes. Defaults to false when omitted.

Animations run using the Skia animation system, with path interpolation handled on the UI thread.

If animated is false, the graph uses a lightweight static renderer. This is useful when displaying many graphs in a list.

Example:

<LineGraph points={priceHistory} animated={true} color="#4484B2" />

enablePanGesture

Whether to enable the pan gesture. Defaults to false.

Requires animated to be true.

There are three events fired when the user interacts with the graph:

  1. onGestureStart: Fires once the user presses and holds the graph. The pan gesture activates.
  2. onPointSelected: Fires for each point the user pans through. Use it to update a label or highlight the selected value.
  3. onGestureEnd: Fires once the user releases the graph. The pan gesture deactivates.

The pan gesture can be configured using these props:

  • panGestureDelay controls how long the user must hold before the gesture activates. It defaults to 300 milliseconds. Set it to 0 to start immediately.

Example:

<LineGraph
  points={priceHistory}
  animated={true}
  color="#4484B2"
  enablePanGesture={true}
  onGestureStart={() => hapticFeedback('impactLight')}
  onPointSelected={(p) => updatePriceTitle(p)}
  onGestureEnd={() => resetPriceTitle()}
/>

TopAxisLabel / BottomAxisLabel

Renders labels above or below the graph. Both props default to undefined, so no labels are rendered.

Requires animated to be true.

These labels usually show the maximum and minimum values. AxisLabel is not a component exported by this package: both props are callbacks that receive no arguments and render any React Native element you provide. The graph reserves a row above or below the canvas; positioning and styling inside that row belong to your label component.

Example:

import { Text } from 'react-native';

function PriceGraph() {
  const values = priceHistory.map((point) => point.value);
  const maxValue = Math.max(...values);
  const minValue = Math.min(...values);

  return (
    <LineGraph
      points={priceHistory}
      animated={true}
      color="#4484B2"
      TopAxisLabel={() => <Text>{`Max: ${maxValue.toFixed(2)}`}</Text>}
      BottomAxisLabel={() => <Text>{`Min: ${minValue.toFixed(2)}`}</Text>}
    />
  );
}

range

Defines the visible range of the graph canvas. It defaults to undefined, which infers both axes from points.

Use a custom range to show a fixed time frame or value scale, even when the data does not cover the whole range. Points outside the x-axis range are not drawn.



This example shows January 2000 and sets the y-axis range to 0 through 200:

<LineGraph
  points={priceHistory}
  animated={true}
  color="#4484B2"
  enablePanGesture={true}
  range={{
    x: {
      min: new Date('2000-01-01T00:00:00.000Z'),
      max: new Date('2000-01-31T23:59:59.999Z'),
    },
    y: {
      min: 0,
      max: 200,
    },
  }}
/>

SelectionDot

Renders the selection dot. It defaults to the built-in SelectionDot. Pass null to hide it.

Requires animated and enablePanGesture to be true.

A custom selection-dot component receives these props from LineGraph. They are all required and have no defaults when you render SelectionDot directly.

Prop Type Default Description
isActive SharedValue None. Required. Whether the pan gesture is active.
color string None. Required. The graph line color.
lineThickness number | undefined None. Required. The resolved graph line width when supplied by LineGraph.
circleX SharedValue None. Required. The selected point's x-coordinate.
circleY SharedValue None. Required. The selected point's y-coordinate.

Example:

<LineGraph
  points={priceHistory}
  animated={true}
  color="#4484B2"
  enablePanGesture={true}
  SelectionDot={CustomSelectionDot}
/>

See this [example `` component](./example/src/components/CustomSelectionDot.tsx).

Sponsor

react-native-graph is sponsored by Pink Panda.

Download the Pink Panda mobile app to see react-native-graph in action!

Community Discord

Join the Margelo Community Discord to chat about react-native-graph or other Margelo libraries.

Adopting at scale

react-native-graph was built at Margelo, an elite app development agency. For enterprise support or other business inquiries, contact us at hello@margelo.com!

Thanks

Special thanks to William Candillon and Christian Falch for their amazing help and support for React Native Skia ❀️

Frequently asked questions

Is react-native-graph free to use?

react-native-graph is open source under the MIT licence. There is no licence fee and no seat count β€” you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does react-native-graph do?

πŸ“ˆ Beautiful, high-performance Graphs and Charts for React Native built with Skia

What is react-native-graph written in?

react-native-graph is primarily written in TypeScript. Its source is publicly available at https://github.com/margelo/react-native-graph, and it has 2,633 GitHub stars.