The chart you see in the terminal is not a licensed SDK; it’s our own WebGL2 engine, Fast Financial Charts, and it’s a standalone library you can use in any app. No license tiers, no watermark: MIT, free forever.
It is headless by design: the engine owns the canvases and the render hot path; your app owns every pixel of chrome (toolbars, HUDs, menus), so it drops into any design system. The /charts page runs a live demo rendered by the library itself.
Install
$ bun add @pairlens/fast-financial-chartsPublished to NPM, semver-versioned, MIT.
Note
The package ships TypeScript source: entry points resolve to .ts/.tsx
files. Use a bundler that understands TypeScript (Vite, esbuild, Bun, Rspack,
webpack + TS loader). With Vite, exclude @pairlens/fast-financial-charts
from optimizeDeps so the indicator Web Worker (new Worker(new URL(...)))
resolves correctly.
Quick start (React)
React bindings live under the @pairlens/fast-financial-charts/react entry point. The core
engine has no React dependency at all; React 19+ is only needed for the
/react entries.
import { useRef } from 'react'
import { FastFinancialChart } from '@pairlens/fast-financial-charts/react'
import type { FastFinancialChartRef } from '@pairlens/fast-financial-charts/types'
export function PairChart({ bars }) {
const chartRef = useRef<FastFinancialChartRef>(null)
return (
<FastFinancialChart
ref={chartRef}
style={{ height: '100%' }} // the chart fills its container, size it
series={[{ id: 'BTC-USD', label: 'BTC/USD', bars, pricePrecision: 2 }]}
timeframe="1m"
indicators={[
{
type: 'EMA',
seriesId: 'BTC-USD',
params: { period: 21 },
pane: 'overlay',
},
{
type: 'RSI',
seriesId: 'BTC-USD',
params: { period: 14 },
pane: 'separate',
},
]}
/>
)
}
Live ticks: the imperative hot path
For high-frequency feeds, push updates through the ref; ticks mutate the last bar in place (or roll into a new one) without a React re-render:
chartRef.current?.applyTick({
seriesId: 'BTC-USD',
ts: Date.now(),
price: 64020.5,
volume: 0.12,
})
chartRef.current?.applyTicks(batchOfTicks) // burst ingestion for batched feeds
What’s in the box
- Sixteen chart types, all GPU-accelerated: candles, Heikin-Ashi, hollow candles, OHLC bars, high-low, line, step line, area, HLC area, baseline, histogram, column, Renko, line break, Kagi, point and figure.
- 90 built-in indicators computed off the main thread in a Web Worker: moving averages, oscillators, bands, trend, volume, volatility, statistical.
- Drawings with magnet snapping, measurement labels, and undo/redo; custom
shapes via
DrawingShapeDefinition. - Multi-pane layouts with resizable separators and per-pane price scales.
- Four price-scale modes (linear, log, percentage, indexed-to-100), configurable time scale, crosshair modes, watermarks, price lines, markers, and localization.
- An MCP-compatible tool surface: 52 deterministic tools
(
addIndicator,setViewport,getVisibleData,screenshot, …) so an AI agent or your automation can drive the chart the way a user does. This is the same surface the Pairlens assistant uses. See the MCP tool surface.
Entry points
Targeted imports keep bundles small (sideEffects: false):
| Entry point | What it exports |
|---|---|
@pairlens/fast-financial-charts |
Core engine (no React), theme tokens |
@pairlens/fast-financial-charts/react |
<FastFinancialChart />, <DepthChart />, hooks |
@pairlens/fast-financial-charts/types |
All public types |
@pairlens/fast-financial-charts/mcp |
MCP schema + executor |
@pairlens/fast-financial-charts/theme |
Theme presets and resolution |
@pairlens/fast-financial-charts/indicators |
Indicator registry |
@pairlens/fast-financial-charts/drawings |
Drawing tools |
Theming
Pass a partial theme and override only what you need, or start from a preset:
import { getThemePreset } from '@pairlens/fast-financial-charts/theme'
;<FastFinancialChart theme={getThemePreset('dark')} />
Runtime theme updates only trigger the relevant overlay redraw paths.
Note
Inside the terminal, @pairlens/fast-financial-charts and
@pairlens/fast-financial-charts/react are also plugin runtime modules;
plugins mark them as build externals and the host provides its own instances,
so the WebGL engine is never duplicated into a plugin bundle. See the Plugin
SDK.
