{"id":50688470,"url":"https://github.com/brandtnewlabs/react-native-livechart","last_synced_at":"2026-06-09T01:04:45.763Z","repository":{"id":362748189,"uuid":"1200270905","full_name":"brandtnewlabs/react-native-livechart","owner":"brandtnewlabs","description":"High-performance live line \u0026 candlestick charts for React Native, built on Skia and Reanimated.","archived":false,"fork":false,"pushed_at":"2026-06-05T18:19:53.000Z","size":552,"stargazers_count":7,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-05T19:19:15.156Z","etag":null,"topics":["candlestick","chart","charts","expo","gesture-handler","react-native","reanimated","skia","trading","typescript"],"latest_commit_sha":null,"homepage":"https://react-native-livechart.brandtnewlabs.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brandtnewlabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"brandtnewlabs"}},"created_at":"2026-04-03T08:10:06.000Z","updated_at":"2026-06-05T14:22:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/brandtnewlabs/react-native-livechart","commit_stats":null,"previous_names":["brandtnewlabs/react-native-livechart"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/brandtnewlabs/react-native-livechart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandtnewlabs%2Freact-native-livechart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandtnewlabs%2Freact-native-livechart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandtnewlabs%2Freact-native-livechart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandtnewlabs%2Freact-native-livechart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brandtnewlabs","download_url":"https://codeload.github.com/brandtnewlabs/react-native-livechart/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brandtnewlabs%2Freact-native-livechart/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34086665,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-08T02:00:07.615Z","response_time":111,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["candlestick","chart","charts","expo","gesture-handler","react-native","reanimated","skia","trading","typescript"],"created_at":"2026-06-09T01:04:45.058Z","updated_at":"2026-06-09T01:04:45.756Z","avatar_url":"https://github.com/brandtnewlabs.png","language":"TypeScript","funding_links":["https://github.com/sponsors/brandtnewlabs"],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/brandtnewlabs/react-native-livechart/main/assets/images/logo.png\" alt=\"react-native-livechart\" width=\"84\" height=\"84\" /\u003e\n\u003c/p\u003e\n\n# react-native-livechart\n\n[![npm version](https://img.shields.io/npm/v/react-native-livechart.svg)](https://www.npmjs.com/package/react-native-livechart)\n[![CI](https://github.com/brandtnewlabs/react-native-livechart/actions/workflows/test.yml/badge.svg)](https://github.com/brandtnewlabs/react-native-livechart/actions/workflows/test.yml)\n[![License: MIT](https://img.shields.io/npm/l/react-native-livechart.svg)](https://github.com/brandtnewlabs/react-native-livechart/blob/main/LICENSE)\n[![Docs](https://img.shields.io/badge/docs-online-3323E6.svg)](https://react-native-livechart.brandtnewlabs.com)\n\nHigh-performance **live** line and candlestick charts for React Native, built on **[@shopify/react-native-skia](https://shopify.github.io/react-native-skia/)**, **[react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/)**, and **[react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/)**. Data and live values flow through Reanimated `SharedValue`s, so the UI thread animates without per-frame JS bridge traffic.\n\n📖 **[Documentation →](https://react-native-livechart.brandtnewlabs.com)**\n\n🤖 **Docs MCP** — point an AI assistant (Claude, Cursor, …) at the docs via the hosted MCP server: `https://react-native-livechart.brandtnewlabs.com/mcp`\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/brandtnewlabs/react-native-livechart/main/assets/images/hero.webp\" alt=\"react-native-livechart live demo\" width=\"480\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003ca href=\"https://react-native-livechart.brandtnewlabs.com\"\u003e\u003cb\u003e▶ Watch the full video demos in the docs →\u003c/b\u003e\u003c/a\u003e\u003c/p\u003e\n\n\u003e The design, feature set, and API shape are **conceptually inspired by [liveline](https://github.com/benjitaylor/liveline)** — Benji Taylor's real-time canvas chart for React — reimagined for React Native. This is **not** a fork; see [Acknowledgments](#acknowledgments).\n\n## Features\n\n- 📈 **Line \u0026 candlestick** modes (with line/candle morph) in a single component\n- 🧬 **Multi-series** charts with a toggleable legend and per-series live dots\n- 🔍 **Scrubbing** with a crosshair and worklet-friendly `onScrub` payloads\n- ⚡ **Momentum** detection and **degen** effects (particle bursts + shake on big swings)\n- 🏷️ **Trade markers** driven by a `SharedValue` trade stream\n- 🎨 **Theming** with light/dark modes, an accent-driven `palette`, and `metrics` sizing/motion tokens\n- ⏳ **Loading** (breathing-line shell) and **paused** states out of the box\n- 🧵 **SharedValue-driven** rendering — history and live values stay on the UI thread\n\n## Demos\n\nSee every feature in motion — line \u0026 area, candlestick, multi-series, scrubbing, momentum \u0026 degen, markers, theming, and more — in the **[documentation](https://react-native-livechart.brandtnewlabs.com)**.\n\n## Install\n\n```bash\nnpm install react-native-livechart\n```\n\n### Peer dependencies\n\nInstall the library's **peer dependencies** in your app (versions should match your React Native / Expo SDK):\n\n| Peer                           | Role                                |\n| ------------------------------ | ----------------------------------- |\n| `react`                        | UI                                  |\n| `react-native`                 | Host                                |\n| `@shopify/react-native-skia`   | Canvas rendering                    |\n| `react-native-reanimated`      | Shared values, animations, worklets |\n| `react-native-worklets`        | Required by Reanimated 4+           |\n| `react-native-gesture-handler` | Pan / scrub gestures                |\n\nFollow the Skia, Reanimated, and Gesture Handler install docs for your toolchain (Babel plugin, `GestureHandlerRootView`, etc.).\n\n### Babel (required)\n\nThe package ships **TypeScript source**; your app's bundler compiles it with the same stack as a typical **Expo / Reanimated 4** project. In practice that means:\n\n- **`babel-preset-expo`** (or an equivalent that includes Reanimated's Babel plugin), and\n- **`react-native-worklets/plugin`** — keep it **last** in the `plugins` array, matching this repo's root [`babel.config.js`](https://github.com/brandtnewlabs/react-native-livechart/blob/main/babel.config.js).\n\nIf you omit Worklets or reorder plugins, worklets in the chart may fail at build or runtime.\n\n### Metro / `package.json` exports\n\nFrom **Expo SDK 53+**, Metro resolves `import` using `package.json` **`exports`**, including the **`react-native`** condition (see [Expo Metro: ES Module resolution](https://docs.expo.dev/versions/latest/config/metro/#es-module-resolution)). This library's runtime entry is **`src/index.ts`** under that condition. If you disabled package exports (`unstable_enablePackageExports: false`), align your resolver or re-enable exports so resolution matches the published map.\n\n## Quick start\n\n```tsx\nimport { useEffect } from \"react\";\nimport { View } from \"react-native\";\nimport { useSharedValue } from \"react-native-reanimated\";\nimport { LiveChart, type LiveChartPoint } from \"react-native-livechart\";\n\nfunction LivePrice() {\n  const data = useSharedValue\u003cLiveChartPoint[]\u003e([]);\n  const value = useSharedValue(100);\n\n  useEffect(() =\u003e {\n    const id = setInterval(() =\u003e {\n      const next = value.get() + (Math.random() - 0.5) * 2;\n      // Reanimated 4: append in place on the UI thread + set the scalar — never `data.value = ...`\n      data.modify((arr) =\u003e {\n        \"worklet\";\n        arr.push({ time: Date.now() / 1000, value: next });\n        if (arr.length \u003e 600) arr.shift();\n        return arr;\n      });\n      value.set(next);\n    }, 100);\n    return () =\u003e clearInterval(id);\n  }, [data, value]);\n\n  return (\n    \u003cView style={{ height: 240 }}\u003e\n      \u003cLiveChart data={data} value={value} accentColor=\"#3323E6\" /\u003e\n    \u003c/View\u003e\n  );\n}\n```\n\nCandlestick mode is a prop away:\n\n```tsx\n\u003cLiveChart data={data} value={value} mode=\"candle\" /\u003e\n```\n\nMulti-series with a legend:\n\n```tsx\nimport { LiveChartSeries, type SeriesConfig } from \"react-native-livechart\";\n\nconst series = useSharedValue\u003cSeriesConfig[]\u003e([\n  { id: \"btc\", label: \"BTC\", color: \"#f7931a\", data: [], value: 0 },\n  { id: \"eth\", label: \"ETH\", color: \"#627eea\", data: [], value: 0 },\n]);\n\n\u003cLiveChartSeries series={series} legend dot /\u003e;\n```\n\n## API overview\n\nThe tables below are a **highlight** — the **canonical, full reference is the TypeScript types and JSDoc** shipped in the source (your editor surfaces them on hover and autocomplete).\n\n### `LiveChart` (single series)\n\n| Prop                                     | Description                                                         |\n| ---------------------------------------- | ------------------------------------------------------------------- |\n| `data`                                   | `SharedValue\u003cLiveChartPoint[]\u003e` — history                           |\n| `value`                                  | `SharedValue\u003cnumber\u003e` — live value for interpolation                |\n| `theme`                                  | `\"light\"` or `\"dark\"`                                               |\n| `accentColor`                            | Primary accent; palette is derived from it                          |\n| `timeWindow`                             | Visible window in seconds (default `30`)                            |\n| `paused`                                 | Freeze scrolling                                                    |\n| `loading`                                | Breathing-line shell until data is ready                            |\n| `mode`                                   | `\"line\"` (default) or `\"candle\"`                                    |\n| `candles` / `liveCandle` / `candleWidth` | Candlestick mode                                                    |\n| `tradeStream`                            | `SharedValue\u003cTradeEvent[]\u003e` for trade markers                       |\n| `degen`                                  | Particle burst + shake on momentum swings                           |\n| `scrub`                                  | Crosshair scrubbing                                                 |\n| `momentum`                               | `true` / `false` / `\"up\"`, `\"down\"`, or `\"flat\"` / `MomentumConfig` |\n| `dot`                                    | `true` / `false` (hide) / `DotConfig` — `radius`, `ring` (halo), `color` |\n| `metrics`                                | Sizing \u0026 motion tokens — geometry/feel analogue of `palette`        |\n| `onScrub`                                | Callback: `ScrubPoint` or `null`                                    |\n\n### `LiveChartSeries` (multi-series)\n\n| Prop             | Description                                 |\n| ---------------- | ------------------------------------------- |\n| `series`         | `SharedValue\u003cSeriesConfig[]\u003e`               |\n| `legend`         | Toggle chips / compact legend               |\n| `dot`            | `true` / `false` (hide) / `MultiSeriesDotConfig` — haloed `ring`, `color`, `radius`, `pulse`, `valueLine`, `valueLabel` |\n| `scrub`          | Crosshair scrubbing (**on by default** as of v2)            |\n| `onSeriesToggle` | Chip tap                                    |\n| `onScrub`        | Worklet-friendly multi-series scrub payload |\n\nThese tables are a **highlight, not the full surface** (`LiveChart` alone has ~48 props). Other shared props include `font`, `insets`, `smoothing`, `xAxis`, `yAxis`, `referenceLines`, `gridStyle`, `palette`, `metrics`, `markers`, `leftEdgeFade`, `line`, `formatValue`, `formatTime`, and `emptyText`; single-series adds `gradient`, `badge`, `pulse`, `valueLine`, and `showValue`. Every overlay toggle follows the same **`boolean | Config`** convention (`badge`, `gradient`, `pulse`, `valueLine`, `scrub`, `yAxis`, `xAxis`, `leftEdgeFade`, `legend`, and `dot`) — pass `true`/omit for defaults, `false` to disable, or an object to customize. Both charts share the same `dot` styling (a `DotConfig` base — `radius`, `ring`, `color`); multi-series extends it with `pulse`, `valueLine`, and `valueLabel`. Beyond `palette` (color), `metrics` exposes sizing \u0026 motion tokens (badge/candle geometry, grid/motion speeds) with the same per-key override model. See the TypeScript types and JSDoc for the complete, canonical reference.\n\n## Migrating to v2\n\nv2 makes the feature-flag surface uniform and adds the `metrics` token object. Two behavior changes to know about:\n\n- **`LiveChartSeries` scrubs by default.** Crosshair scrubbing is now on by default (it previously defaulted off), matching `LiveChart`. Pass `scrub={false}` to restore the old behavior.\n- **`dot.show` is deprecated.** Prefer `dot={false}` to hide the live dot — every overlay toggle now follows the same `boolean | Config` convention. `dot={{ show: false }}` still works.\n\nEverything else is additive: the new [`metrics`](https://react-native-livechart.brandtnewlabs.com/guides/theming#sizing-and-motion-tokens) prop is optional, and omitting it keeps the built-in geometry and motion.\n\n## Examples (Expo app in this repo)\n\nRun the example from the repository root:\n\n```bash\nnpm install\nnpm start\n```\n\nThe example app bundles the library from **`src/`**; Metro's [`watchFolders`](https://github.com/brandtnewlabs/react-native-livechart/blob/main/metro.config.js) include the package so Fast Refresh sees edits without a separate library bundler. Optionally run **`npm run build:lib:types:watch`** if you want **`dist/*.d.ts`** regenerated continuously for editor/tsconfig consumers.\n\nScreens demonstrate candlestick mode, multi-series, scrub, momentum tuning, degen mode, loading / paused states, and more.\n\n## How it works\n\n- **Skia** draws grid, line, candles, badges, and overlays on the GPU.\n- **Reanimated** owns timeline layout, smoothing, and scrub state; hooks feed a small engine API on the UI thread.\n- **Gesture Handler** drives scrubbing and chart interactions.\n\nA frame-callback engine (`useFrameCallback`) runs a pure tick function on the UI thread each frame, updating display range, time window, and smoothed values, then writing results to `SharedValue`s. Path builders and overlays read those `SharedValue`s inside `useDerivedValue`, so React re-renders stay minimal.\n\n## Contributing\n\nContributions are welcome — see [CONTRIBUTING.md](https://github.com/brandtnewlabs/react-native-livechart/blob/main/CONTRIBUTING.md) for the dev setup, the `npm run verify` gate, and the worklets-plugin rule. By participating you agree to the [Code of Conduct](https://github.com/brandtnewlabs/react-native-livechart/blob/main/CODE_OF_CONDUCT.md).\n\n## Acknowledgments\n\n**[liveline](https://github.com/benjitaylor/liveline)** by **Benji Taylor** (MIT) is the **primary inspiration** for this project: live updating charts, line and candlestick modes (including line/candle morph ideas), multi-series behavior, momentum and degen effects, scrubbing, loading and paused states, theme plus accent-driven palettes, and the overall prop vocabulary — even though names differ here (for example `accentColor` vs `color`, `timeWindow` vs `window`, and `SharedValue` streams instead of React state).\n\nThis package is a **React Native reimplementation** using **Skia**, **Reanimated**, and **Gesture Handler**. It is **not** the web canvas component ported line-for-line. The codebase **diverged** over time toward more hooks, layout options, and customizability for mobile.\n\n**Third-party / adapted code:** math utilities used for chart geometry and smoothing (including Fritsch–Carlson monotone spline tangents, momentum detection, range/lerp helpers, and related pieces) are **adapted from liveline** under the MIT license. See the [LICENSE](https://github.com/brandtnewlabs/react-native-livechart/blob/main/LICENSE) file for the formal notice.\n\n### Compared to liveline\n\n- **Rendering:** liveline uses a DOM `\u003ccanvas\u003e` and `requestAnimationFrame`; this library uses **Skia** on the UI thread.\n- **Data flow:** liveline takes plain `data` / `value` props; here history and live values are **`SharedValue`s** so worklets avoid per-frame JS bridge work.\n- **Input:** scrubbing uses **pan gestures** instead of canvas hover.\n- **Scope:** liveline includes features this repo does not (for example **orderbook** visualization and built-in time-window controls); this repo adds **React Native–specific** pieces (for example trade markers via `tradeStream`) and a more decomposed hook API.\n\n## License\n\nMIT — see [LICENSE](https://github.com/brandtnewlabs/react-native-livechart/blob/main/LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandtnewlabs%2Freact-native-livechart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrandtnewlabs%2Freact-native-livechart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrandtnewlabs%2Freact-native-livechart/lists"}