@elitechart/react
v0.0.2
Published
React adapter for ChartForge — component, hooks, and Next.js App Router integration.
Maintainers
Readme
@elitechart/react
A minimal, headless React adapter for the ChartForge charting engine. Three small exports (<Chart />, useChart, useChartTheme) is all you need to drop a professional-grade trading chart into a React 18 / 19 app — including Next.js App Router — without the opinionated UI shell that @elitechart/elitechart ships.
If you want a fully-styled, batteries-included trading chart, install @elitechart/elitechart. If you want a primitive you can compose into your own design system, this is your package.
Install
pnpm add @elitechart/react @elitechart/core @elitechart/themesreact and react-dom are peer dependencies (>=18.3). The bundle ships with a leading 'use client'; banner so it imports cleanly from a Next.js Server Component without any extra wrapping — every internal hook is client-side.
Quick example
'use client';
import { useRef } from 'react';
import {
Chart,
useChart,
useChartTheme,
asPrice,
asTickSize,
asTimestampMs,
asVolume,
type ChartRef,
type Series,
} from '@elitechart/react';
import { darkTheme, lightTheme } from '@elitechart/themes';
const series: Series = {
symbol: {
id: 'BTCUSDT',
ticker: 'BTCUSDT',
type: 'crypto',
tickSize: asTickSize(0.01),
priceScale: 2,
},
resolution: { kind: 'minutes', value: 1 },
bars: [
{
time: asTimestampMs(Date.now() - 60_000),
open: asPrice(67_000),
high: asPrice(67_120),
low: asPrice(66_980),
close: asPrice(67_080),
volume: asVolume(12),
},
// …more bars
],
};
export function BtcChart() {
const ref = useRef<ChartRef>(null);
const handle = useChart(ref);
const [theme, setTheme] = useChartTheme(handle, darkTheme);
return (
<div style={{ height: 480 }}>
<button onClick={() => setTheme(theme === darkTheme ? lightTheme : darkTheme)}>Toggle theme</button>
<Chart ref={ref} series={series} kind="candle" theme={theme} />
</div>
);
}What's in the box
<Chart />
A forwardRef component that mounts the engine on first paint and disposes on unmount. Strict-Mode-safe — the dev double-invoke (mount → cleanup → mount) cannot leak a destroyed handle onto the live ref.
| Prop | Type | Notes |
| --------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| series | Series | Required. The OHLCV series to render. |
| kind | SeriesKind | 'candle', 'line', 'bar', 'area', 'heikin-ashi', 'renko', … |
| theme | ChartForgeTheme | Initial theme. Defaults to a built-in dark fallback. Update reactively via useChartTheme rather than re-rendering this prop. |
| onReady | (handle) => void | Fires once after first paint with the live engine handle. |
| className / style | DOM-side knobs forwarded to the mount <div>. |
The mount effect runs once per <Chart /> instance — reactive updates (symbol/timeframe/theme swaps) travel through imperative setters on the handle (setSeries, setKind, setTheme). This keeps the engine from re-mounting on every parent render.
useChart(ref)
Reactively read the engine handle from a <Chart /> ref. Returns null before the engine boots and after it unmounts; otherwise returns the live ChartHandle. Useful when a sibling component (toolbar, legend, drawing-tool dock) needs to call into the engine.
const ref = useRef<ChartRef>(null);
const handle = useChart(ref);
useEffect(() => {
if (handle === null) return;
return handle.on('crosshair:move', (p) => {
// …
});
}, [handle]);
return <Chart ref={ref} series={series} />;useChartTheme(handle, initial)
Returns a [theme, setTheme] tuple identical in shape to useState. Whenever setTheme runs (or the handle transitions from null to a live engine), the new theme is pushed through to chart.setTheme(theme). No-ops while the handle is null.
const [theme, setTheme] = useChartTheme(handle, darkTheme);Compatibility
- React 18.3+ and React 19. Uses
forwardRef,useEffect,useStateonly — no concurrent-only APIs. - Next.js App Router. The bundle has a
'use client';banner so consumers don't need to wrap. - SSR-safe. No
windowordocumentaccess at module scope; the engine boot runs insideuseEffect. - Tree-shakeable. ESM + CJS dual emit, named exports only.
Links
License
MIT — see LICENSE.
