> ## Documentation Index
> Fetch the complete documentation index at: https://react-native-livechart.brandtnewlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Candlestick

> Render OHLC candlestick bars with a live in-progress candle.

Set `mode="candle"` and supply committed OHLC bars plus an optional in-progress candle. Both
must be `SharedValue`s so the chart can read them on the UI thread.

<Note>
  **Live example:**
  [`app/demo/candlestick.tsx`](https://github.com/brandtnewlabs/react-native-livechart/blob/main/app/demo/candlestick.tsx)
  in the example app.
</Note>

<Frame caption="Candlestick mode with a live, forming candle">
  <video autoPlay loop muted playsInline controls poster="/media/candlestick.jpg" src="https://mintcdn.com/brandtnewlabs/3aK_iydbC8Ff9g3s/media/candlestick.mp4?fit=max&auto=format&n=3aK_iydbC8Ff9g3s&q=85&s=099960415b2025eae4a672ae75b262e6" data-path="media/candlestick.mp4" />
</Frame>

```tsx theme={null}
import { useSharedValue } from "react-native-reanimated";
import { LiveChart, type CandlePoint } from "react-native-livechart";

const candles = useSharedValue<CandlePoint[]>([]);
const liveCandle = useSharedValue<CandlePoint | null>(null);

<LiveChart
  data={data}
  value={value}
  mode="candle"
  candles={candles}
  liveCandle={liveCandle}
  candleWidth={60} // seconds per bucket (1-minute bars)
/>;
```

## The candle shape

Each bar is an OHLC bucket:

```ts theme={null}
interface CandlePoint {
  time: number;  // bucket start, unix seconds
  open: number;
  high: number;
  low: number;
  close: number;
  volume?: number; // optional — drives the volume bars (see below)
}
```

* **`candles`** — committed bars, sorted by `time`.
* **`liveCandle`** — the in-progress bucket, updated each tick. Set it to `null` between buckets.
* **`candleWidth`** — bucket size in seconds; drives bar width and spacing.

<Note>
  `data` / `value` are still used for the line/candle morph and momentum detection, so keep
  feeding them alongside your candles.
</Note>

## Coloring

Bullish/bearish body and wick colors come from the palette derived from `accentColor` + `theme`.
Override them precisely via the [`palette`](/guides/theming) prop (`candleUp`, `candleDown`,
`wickUp`, `wickDown`).

## Body size, spacing & wick shape

Candlestick geometry lives in the `metrics.candle`
[sizing tokens](/api-reference/types#metrics). Body width is the smallest of
`bodyWidthRatio × slot width`, `slot width - minGapPx`, and `maxBodyPx`, with a 1px floor.
`minGapPx` defaults to `2`, preserving a visible gap between adjacent bodies. On dense charts,
set it to `0` to let `bodyWidthRatio` keep bodies proportional instead of collapsing them to the
1px floor:

```tsx theme={null}
<LiveChart
  mode="candle"
  candles={candles}
  liveCandle={liveCandle}
  candleWidth={60}
  metrics={{
    candle: {
      bodyWidthRatio: 0.9,
      minGapPx: 0,
      bodyRadius: 3,
      wickWidth: 2,
    },
  }}
/>
```

The 1px body floor takes precedence when a slot is too narrow to preserve the configured gap.
Volume bars automatically use the same body width and spacing. `bodyRadius` defaults to `0`
(sharp corners), and `wickWidth` defaults to `1`. See
[`CandleMetrics`](/api-reference/types#metrics) for every sizing token and default.

## Volume bars

Pass `volume` to draw volume bars in a reserved band **below** the candles. The candle/price plot
shrinks by the band height to make room (candles are never cut off) and the x-axis stays pinned to
the bottom. Each bar reads its candle's `volume`; bar heights are normalized to the **largest
visible volume**, so the tallest visible bar fills the band. Candles without a `volume` draw no bar.

```tsx theme={null}
const candles = useSharedValue<CandlePoint[]>([
  { time: 1700000000, open: 48, high: 52, low: 47, close: 50, volume: 1200 },
  // …
]);

<LiveChart
  mode="candle"
  candles={candles}
  liveCandle={liveCandle}
  candleWidth={60}
  volume // `true` = defaults, or pass a VolumeConfig
/>;
```

Configure colors, band height, rounding, and opacity with a
[`VolumeConfig`](/api-reference/types#config-objects):

```tsx theme={null}
<LiveChart
  mode="candle"
  candles={candles}
  liveCandle={liveCandle}
  candleWidth={60}
  volume={{
    maxHeight: 64,        // reserved band height (px) = the tallest bar; default 48
    radius: 2,            // bar-top corner radius; default 2
    opacity: 0.6,         // opacity of the whole band; default 0.6
    upColor: "#16a34a",   // default: palette.candleUp
    downColor: "#dc2626", // default: palette.candleDown
  }}
/>;
```

<Note>
  Volume is **candle mode only**. Bars align under the candle bodies (same width + center), colored
  by candle direction (up/down) unless you override `upColor` / `downColor`.
</Note>

## Historical reference series

Overlay a changing average cost, VWAP, peg, or other historical benchmark with the
[`referenceLines.series`](/guides/reference-lines-and-bands#time-varying-reference-line-series)
form. It draws a Skia polyline over the candles using the same time and Y scales, supports the
normal reference-line color, dash, width, and label fields, and extends its last value flat to
the live edge by default.

```tsx theme={null}
<LiveChart
  mode="candle"
  candles={candles}
  liveCandle={liveCandle}
  referenceLines={[
    {
      series: averageCostHistory,
      label: "Avg cost",
      showValue: true,
      color: "#f59e0b",
      strokeWidth: 2,
    },
  ]}
/>
```

## Scrubbing & the OHLC tooltip

Pass `scrub` to enable the crosshair: the built-in tooltip shows the scrubbed candle's O/H/L/C
stacked with its time. For full control — a minimal pill, your own layout, or to mirror the active
candle elsewhere in your UI — pass [`renderTooltip`](/guides/scrubbing#custom-tooltip-in-candle-mode),
which receives the scrubbed bucket as `ctx.candle`. The JS-thread [`onScrub`](/guides/scrubbing)
callback also includes `point.candle` for the OHLC under the crosshair. Set
[`scrub.snapToCandles`](/guides/scrubbing#snap-to-candle-centers-snaptocandles) to make the
crosshair jump from candle center to candle center instead of gliding.

See the full prop list in the [`LiveChart` reference](/api-reference/livechart).

For intervals without OHLC—no trades, exchange maintenance, or incomplete feed
coverage—use [`candleGaps`](/guides/empty-candles) instead of fabricating normal
bullish/bearish candles.

## Candle path construction

Sharp candle bodies reuse a plain rectangle input within each body-path rebuild.
This avoids creating a Skia rectangle wrapper for every candle. The chart still
uses four batched paths for up/down bodies and wicks, and returns fresh immutable
paths so live updates repaint normally. Rounded bodies and volume bars retain
their existing drawing behavior. No configuration change is required.

Volume bars use the same rectangle reuse for sharp bars. The largest visible
historical volume is recalculated when candle data notifies a change or the
visible bucket bounds change. Live volume is included on every geometry update.
Use normal SharedValue updates or `.modify()` for in-place edits; array length is
not used as a data revision.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.