npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rn-tradingview

v2.1.0

Published

Production-grade multi-exchange candlestick chart for React Native. Supports Binance, OKX, and Bybit. GPU-accelerated (Skia), Reanimated v3 gestures, technical indicators (MACD, RSI, Bollinger Bands), drawing tools, live WebSocket candles, order book dept

Readme

rn-tradingview

npm version npm downloads license platform

Production-grade multi-exchange trading chart for React Native.

rn-tradingview is a free, open-source React Native trading chart engine that connects to Binance, OKX, Bybit, or any custom exchange out of the box. GPU-accelerated Skia rendering, native Reanimated v3 gestures, real-time WebSocket candles + order book, full-featured technical indicators, drawing tools, and depth charts — all in a single library.

Built for crypto trading apps, DeFi dashboards, portfolio trackers, and any React Native app that needs a professional financial chart.


Why rn-tradingview?

| | rn-tradingview | WebView-based libs | |---|---|---| | Rendering | GPU (Skia canvas) | Web / WebView | | Performance | 60 FPS on 10 000+ candles | Laggy on large datasets | | Gestures | Native Reanimated v3 | JS-bridge events | | Exchanges | Binance + OKX + Bybit + Custom | Manual wiring | | Offline | Yes (bring your own data) | Needs web bundle | | TypeScript | Full coverage | Partial |


Features

  • Multi-exchange, zero config — plug in exchange="binance", "okx", or "bybit" and get live candles + order book automatically
  • Custom exchange adapters — wire any REST + WebSocket feed in ~20 lines with createExchangeAdapter
  • GPU-accelerated rendering — all pixels drawn in a Skia <Canvas>, never on the JS thread
  • Reanimated v3 gestures — inertial pan, pinch-zoom around focal point, long-press crosshair that snaps to nearest candle
  • Technical indicators
    • Main / overlay: MA, EMA, BOLL (Bollinger Bands), SAR (Parabolic SAR), AVL (volume MA), SUPER (Supertrend)
    • Sub-pane: MACD, RSI, KDJ, OBV, WR (Williams %R), StochRSI
  • Drawing tools — Trend line, Ray, Horizontal line, Fibonacci retracement, Channel, Measure; sidebar modeled after Binance's drawing toolbar
  • Depth / order book chart — cumulative bid & ask visualization with live WebSocket updates, switchable between exchanges
  • Infinite scroll history — scroll left to auto-paginate older candles
  • Fullscreen & orientation — portrait ↔ landscape with optional react-native-orientation-locker
  • Bring-your-own data — use any REST API or WebSocket feed with CandlestickChart
  • Full TypeScript — every prop, candle shape, indicator config, and theme token is typed

Installation

npm install rn-tradingview
# or
yarn add rn-tradingview

Peer dependencies

npm install \
  @shopify/react-native-skia \
  react-native-gesture-handler \
  react-native-reanimated \
  react-native-safe-area-context \
  react-native-svg
cd ios && pod install

Add the Reanimated Babel plugin:

// babel.config.js
module.exports = {
  presets: ['module:metro-react-native-babel-preset'],
  plugins: ['react-native-reanimated/plugin'],
};

Quick Start

TradingChart — live chart, one line per exchange

TradingChart manages WebSocket subscriptions, candle state, ticker, order book, and drawing persistence internally.

Binance

import { TradingChart } from 'rn-tradingview';

<TradingChart exchange="binance" pair="BTCUSDT" interval="1m" height={500} />

OKX

import { TradingChart } from 'rn-tradingview';

<TradingChart exchange="okx" pair="BTC-USDT" interval="1m" height={500} />

Bybit

import { TradingChart } from 'rn-tradingview';

<TradingChart exchange="bybit" pair="BTCUSDT" interval="1m" height={500} />

Full example:

import React from 'react';
import { SafeAreaView } from 'react-native';
import { TradingChart } from 'rn-tradingview';

export default function App() {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: '#0B0F14' }}>
      <TradingChart
        exchange="binance"   // 'binance' | 'okx' | 'bybit'
        pair="BTCUSDT"
        interval="1m"
        height={500}
        themeMode="dark"
      />
    </SafeAreaView>
  );
}

CandlestickChart — bring your own data

Use this when you already have candle data from your own API or WebSocket.

import React from 'react';
import { SafeAreaView } from 'react-native';
import { CandlestickChart } from 'rn-tradingview';
import type { Candle } from 'rn-tradingview';

const candles: Candle[] = [
  { t: 1700000000000, o: 36000, h: 36500, l: 35800, c: 36200, v: 120.5 },
  { t: 1700003600000, o: 36200, h: 37000, l: 36100, c: 36800, v: 98.3 },
  // oldest → newest
];

export default function App() {
  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: '#0B0F14' }}>
      <CandlestickChart
        candles={candles}
        symbol="BTCUSDT"
        interval="1h"
        height={450}
        themeMode="dark"
        onTimeframeChange={(tf) => console.log('new timeframe:', tf)}
      />
    </SafeAreaView>
  );
}

Exchange Adapters

rn-tradingview ships purpose-built adapters for Binance, OKX, and Bybit. Each adapter exposes fetchCandles (REST) and subscribeCandles / subscribeTicker (WebSocket) with a normalized Candle shape.

Binance adapter

import { binanceAdapter } from 'rn-tradingview';

// REST — fetch historical candles
const candles = await binanceAdapter.fetchCandles('BTCUSDT', '1h', 500);

// WebSocket — live candle stream
const unsub = binanceAdapter.subscribeCandles('BTCUSDT', '1m', (candle) => {
  console.log('Binance candle:', candle);
});

// Live ticker (price updates)
const unsubTicker = binanceAdapter.subscribeTicker('BTCUSDT', (ticker) => {
  console.log('Binance price:', ticker.price);
});

// Cleanup
unsub();
unsubTicker();

Binance WebSocket: wss://stream.binance.com:9443/ws/<symbol>@kline_<interval> Binance REST: https://api.binance.com/api/v3/klines Symbol format: BTCUSDT (no hyphen, uppercase)


OKX adapter

import { okxAdapter } from 'rn-tradingview';

// REST — fetch historical candles
const candles = await okxAdapter.fetchCandles('BTC-USDT', '1H', 300);

// WebSocket — live candle stream
const unsub = okxAdapter.subscribeCandles('BTC-USDT', '1m', (candle) => {
  console.log('OKX candle:', candle);
});

// Live ticker (price updates)
const unsubTicker = okxAdapter.subscribeTicker('BTC-USDT', (ticker) => {
  console.log('OKX price:', ticker.price, '24h vol:', ticker.volume24h);
});

// Cleanup
unsub();
unsubTicker();

OKX WebSocket: wss://wspri.okx.com:8443/ws/v5/ipublic (channels: candle{tf}, tickers) OKX REST: https://www.okx.com/api/v5/market/candles Symbol format: BTC-USDT (hyphen-separated, uppercase)


Bybit adapter

import { bybitAdapter } from 'rn-tradingview';

// REST — fetch historical candles
const candles = await bybitAdapter.fetchCandles('BTCUSDT', '1h', 200);

// WebSocket — live candle stream
const unsub = bybitAdapter.subscribeCandles('BTCUSDT', '1m', (candle) => {
  console.log('Bybit candle:', candle);
});

// Live ticker (price updates)
const unsubTicker = bybitAdapter.subscribeTicker('BTCUSDT', (ticker) => {
  console.log('Bybit price:', ticker.price);
});

// Cleanup
unsub();
unsubTicker();

Bybit WebSocket: wss://stream.bybit.com/v5/public/spot (topics: kline.<interval>.<symbol>, tickers.<symbol>) Bybit REST: https://api.bybit.com/v5/market/kline Symbol format: BTCUSDT (no hyphen, uppercase)


Custom exchange adapter

Wire any exchange — or your own proprietary data feed — with createExchangeAdapter:

import { createExchangeAdapter, CandlestickChart, mergeLiveCandle } from 'rn-tradingview';
import type { Candle } from 'rn-tradingview';

const myAdapter = createExchangeAdapter({
  name: 'MyExchange',

  // REST: fetch historical OHLCV
  async fetchCandles(symbol, interval, limit = 200, endTime) {
    const res = await fetch(
      `https://api.myexchange.com/candles?symbol=${symbol}&tf=${interval}&limit=${limit}`
    );
    const rows = await res.json();
    return rows.map((r: any): Candle => ({
      t: r.timestamp,
      o: r.open,
      h: r.high,
      l: r.low,
      c: r.close,
      v: r.volume,
    }));
  },

  // WebSocket: live candle stream
  subscribeCandles(symbol, interval, onUpdate) {
    const ws = new WebSocket('wss://ws.myexchange.com/stream');
    ws.onopen = () =>
      ws.send(JSON.stringify({ type: 'subscribe', channel: `candle:${symbol}:${interval}` }));
    ws.onmessage = (e) => {
      const d = JSON.parse(e.data);
      onUpdate({ t: d.t, o: d.o, h: d.h, l: d.l, c: d.c, v: d.v });
    };
    return () => ws.close();
  },

  normalizeSymbol: (s) => s.toUpperCase(),
  normalizeInterval: (i) => i,
});

// Use with CandlestickChart:
export default function MyChart() {
  const [candles, setCandles] = React.useState<Candle[]>([]);

  React.useEffect(() => {
    myAdapter.fetchCandles('BTCUSDT', '1m').then(setCandles);
    const unsub = myAdapter.subscribeCandles('BTCUSDT', '1m', (c) => {
      setCandles((prev) => mergeLiveCandle(prev, c));
    });
    return unsub;
  }, []);

  return <CandlestickChart candles={candles} symbol="BTCUSDT" interval="1m" height={450} />;
}

Normalized Candle Format

All exchange adapters produce the same Candle shape:

type Candle = {
  t: number; // Unix timestamp in milliseconds
  o: number; // Open
  h: number; // High
  l: number; // Low
  c: number; // Close
  v: number; // Volume (base asset)
};

All candle arrays are oldest → newest (ascending t).


Depth / Order Book Chart

Single exchange:

import { DepthChart } from 'rn-tradingview';

<DepthChart
  exchange="binance"   // 'binance' | 'okx' | 'bybit'
  symbol="BTCUSDT"
  height={300}
/>

Multi-exchange with built-in toggle (Binance / OKX / Bybit):

import { ExchangeDepthChart } from 'rn-tradingview';

<ExchangeDepthChart
  defaultExchange="binance"
  symbol="BTCUSDT"
  symbolByExchange={{ okx: 'BTC-USDT', bybit: 'BTCUSDT', binance: 'BTCUSDT' }}
  height={300}
/>

ExchangeDepthChart renders a Binance / OKX / Bybit toggle bar above the chart and switches the live WebSocket automatically.


OKX — useOkxCandles hook with infinite scroll

import React, { useEffect } from 'react';
import { SafeAreaView, ActivityIndicator } from 'react-native';
import { CandlestickChart, useOkxCandles } from 'rn-tradingview';

export default function OkxScreen() {
  const { candles, loading, loadingMore, fetchInitialCandles, fetchMoreCandles } =
    useOkxCandles({ instId: 'BTC-USDT', bar: '1m' });

  useEffect(() => { void fetchInitialCandles(); }, []);

  if (loading) return <ActivityIndicator />;

  return (
    <SafeAreaView style={{ flex: 1, backgroundColor: '#0B0F14' }}>
      <CandlestickChart
        candles={candles}
        symbol="BTC-USDT"
        interval="1m"
        height={450}
        onLoadMore={(oldestTimestamp) => void fetchMoreCandles(oldestTimestamp)}
        loadingMore={loadingMore}
      />
    </SafeAreaView>
  );
}

Exchange Support

| Feature | Binance | OKX | Bybit | Custom | |---------|:-------:|:---:|:-----:|:------:| | REST candles | ✅ | ✅ | ✅ | ✅ | | Live candle WebSocket | ✅ | ✅ | ✅ | ✅ | | Live ticker WebSocket | ✅ | ✅ | ✅ | optional | | Order book WebSocket | ✅ | ✅ | ✅ | — | | useOkxCandles hook | — | ✅ | — | — | | Infinite scroll history | ✅ | ✅ | ✅ | — | | Exchange adapter | binanceAdapter | okxAdapter | bybitAdapter | createExchangeAdapter | | Symbol format | BTCUSDT | BTC-USDT | BTCUSDT | yours |


API Reference

<TradingChart>

All-in-one component: manages WebSocket connections, candle buffer, ticker, order book, drawing persistence.

| Prop | Type | Default | Description | |------|------|---------|-------------| | exchange | 'binance' \| 'okx' \| 'bybit' | 'binance' | Exchange to connect to | | pair | string | required | Trading pair, e.g. "BTCUSDT" / "BTC-USDT" | | interval | string | '1m' | Timeframe: "1m", "5m", "15m", "1h", "4h", "1d" | | height | number | 400 | Chart height in px | | themeMode | 'dark' \| 'light' | 'dark' | Color theme |


<CandlestickChart>

Stateless chart — you own the candle data.

| Prop | Type | Default | Description | |------|------|---------|-------------| | candles | Candle[] | required | OHLCV array, oldest → newest | | symbol | string | — | Label shown in header | | interval | string | — | Active timeframe label | | height | number | 400 | Chart height in px | | width | number | full | Chart width in px | | themeMode | 'dark' \| 'light' | 'dark' | Color theme | | onTimeframeChange | (tf: string) => void | — | Called when user picks a timeframe | | onLoadMore | (oldestTs: number) => void | — | Called when user scrolls past oldest candle | | loadingMore | boolean | — | Shows pagination spinner | | indicatorTrigger | number | — | Increment to open indicator sheet | | contentInset | { top?, bottom?, left?, right? } | — | Safe-area padding override |


<DepthChart>

Single-exchange live order book.

| Prop | Type | Default | Description | |------|------|---------|-------------| | exchange | 'binance' \| 'okx' \| 'bybit' | 'binance' | Exchange | | symbol | string | required | Trading pair | | height | number | — | Chart height | | maxLevelsPerSide | number | 100 | Max bid/ask levels | | throttleMs | number | — | WebSocket update throttle |


<ExchangeDepthChart>

Depth chart with a built-in Binance / OKX / Bybit toggle.

| Prop | Type | Default | Description | |------|------|---------|-------------| | defaultExchange | 'binance' \| 'okx' \| 'bybit' | 'binance' | Initial exchange | | symbol | string | — | Fallback symbol for all exchanges | | symbolByExchange | { binance?, okx?, bybit? } | — | Per-exchange symbol overrides | | height | number | — | Chart height |


Exchange adapter interface

interface ExchangeAdapter {
  readonly name: string;

  fetchCandles(symbol: string, interval: string, limit?: number, endTime?: number): Promise<Candle[]>;
  subscribeCandles(symbol: string, interval: string, onUpdate: CandleCallback): Unsubscribe;
  subscribeTicker?(symbol: string, onUpdate: TickerCallback): Unsubscribe;
  normalizeSymbol(symbol: string): string;
  normalizeInterval(interval: string): string;
}

createExchangeAdapter

import { createExchangeAdapter } from 'rn-tradingview';

const adapter = createExchangeAdapter({
  name: 'MyExchange',
  fetchCandles: async (symbol, interval, limit, endTime) => { /* ... */ return candles; },
  subscribeCandles: (symbol, interval, onUpdate) => { /* ... */ return () => ws.close(); },
});

useOkxCandles hook

const {
  candles,          // Candle[]
  loading,          // initial fetch in progress
  loadingMore,      // pagination in progress
  error,            // Error | null
  hasMore,          // more history available
  fetchInitialCandles,  // () => Promise<void>
  fetchMoreCandles,     // (oldestTs?: number) => Promise<void>
  applyLiveCandle,      // (candle: Candle) => void
  reset,            // () => void
} = useOkxCandles({
  instId: 'BTC-USDT',      // OKX instrument ID
  bar: '1m',               // timeframe
  initialLimit: 300,       // candles to fetch on first load (max 300)
  pageLimit: 100,          // candles per history page
});

Data utilities

import {
  fetchKlines,        // fetch REST candles (OKX-backed)
  subscribeKlines,    // subscribe to live candle WebSocket (OKX)
  fetchDepth,         // fetch order book snapshot (Binance)
  subscribeDepth,     // subscribe to live depth stream (Binance)
  mergeLiveCandle,    // merge a forming candle into a candle array
} from 'rn-tradingview';

// Fetch 300 candles
const candles = await fetchKlines('BTC-USDT', '1h', 300);

// Subscribe to live candles
const ws = subscribeKlines('BTC-USDT', '1m', (candle) => {
  // merge candle into your state
});
ws.close(); // cleanup

Indicator engine (advanced)

import { computeChartIndicators } from 'rn-tradingview';

const result = computeChartIndicators(candles, {
  ma:   [{ period: 7 }, { period: 25 }, { period: 99 }],
  ema:  [{ period: 12 }, { period: 26 }],
  boll: { period: 20, multiplier: 2 },
  rsi:  { period: 14 },
  macd: { fast: 12, slow: 26, signal: 9 },
  kdj:  { period: 9 },
  obv:  true,
});

Theming

import { TradingChart, CandlestickChart } from 'rn-tradingview';

// Dark theme (default — matches Binance Mobile)
<TradingChart exchange="binance" pair="BTCUSDT" themeMode="dark" ... />

// Light theme
<CandlestickChart candles={candles} themeMode="light" ... />

Import raw tokens if you need to match colors in your own UI:

import { DarkTheme, LightTheme, Themes } from 'rn-tradingview';

React Native Compatibility

| rn-tradingview | React Native | React | |----------------|-------------|-------| | 2.x | 0.72 – 0.85 | 18–19 | | 1.x | 0.72 – 0.75 | 18 |


License

MIT © Salil Samdarshy & Shubham Narula