Quickstart
Get a candlestick chart on screen, then add a scripting engine and an indicator.
Vela™ is a modern, layer-based charting library. This page gets a candlestick chart on screen, then adds a scripting engine and an indicator.
The fastest path uses offline data — an array of bars you already have. No network call, no API key, nothing to configure.
At a glance
- Step 1 alone renders candles. Engines are opt-in.
- Step 2 registers an engine so scripts can run.
- Step 3 adds an indicator from source.
Install the package first:
npm install @luxalgo/vela(see Installation).
Step 1 — Create a chart
Give Vela™ a container (an element or a CSS selector) and some options. Pass your own bars via data to stay fully offline.
import { Vela } from '@luxalgo/vela';
const chart = new Vela('#chart', {
data: myBars, // OHLCV[] you already have — no provider, no network
timeframe: '1h',
theme: 'dark',
});Each bar is { time, open, high, low, close, volume? }, where time is the bar's open time in epoch milliseconds.
With offline data, timeframe is still used — for bar spacing and axis labels — while symbol/bars are ignored (those drive the fetch path you are opting out of).
That is the whole first step. Candles paint immediately — no engine required. A chart with no scripting engine is a perfectly valid candlestick chart.
Want bars fetched for you instead of supplying them? Set a
symbol/timeframeand register a data provider withchart.data.registerProvider(...)— registering it fires the fetch.dataand provider fetch are mutually exclusive. See also Options (market options).
Step 2 — Register a scripting engine
Indicators run on a scripting engine, and Vela™ ships none. Install the one you need and register it under its language id. Pine Script lives in the @luxalgo/vela-pinets addon:
npm install @luxalgo/vela-pinets pinetsimport { PineEngine } from '@luxalgo/vela-pinets';
chart.registerEngine('pine', new PineEngine());registerEngine returns the chart, so you can chain it from construction:
const chart = new Vela('#chart', { data: myBars, timeframe: '1h' })
.registerEngine('pine', new PineEngine());This is deliberate: the bare chart stays lightweight, you only pull in an engine when you actually script — and Vela™'s own license stays clean of whatever a runtime brings with it. Calling addIndicator with no engine for that language throws an actionable error.
The addon is Vela-PineTS. It also exports
PineWorkerEngine, the same Pine semantics off the main thread. See Scripting engines or the PineTS guide Using within charts.
Step 3 — Add an indicator from source
Pass the script source. The engine is selected by language — addIndicator({ language }), or the chart's defaultLanguage when the call names none (seeded from the first engine passed at construction, 'pine' otherwise).
const ema = chart.addIndicator(`//@version=5
indicator("EMA", overlay=true)
plot(ta.ema(close, input.int(20, "Length")), "EMA", color.orange)`);addIndicator returns a handle synchronously, but the data fills in asynchronously. The handle is usable right away — you can read its id and title, change inputs, or remove it — but the plotted values appear once execution resolves. Listen for that:
ema.on('ready', () => console.log('EMA rendered'));
ema.on('error', ({ error }) => console.error(error));You can also await the whole chart's first paint:
await chart.ready();Deep-history charts (a
barscount beyond ~10k) become interactive after their first chunk and keep backfilling older bars in the background —await chart.historyComplete()when you need the full depth (see thehistory:progress/history:completeevents in the API reference).
Full example
import { Vela } from '@luxalgo/vela';
import { PineEngine } from '@luxalgo/vela-pinets';
const chart = new Vela('#chart', { data: myBars, timeframe: '1h', theme: 'dark' });
chart.registerEngine('pine', new PineEngine());
const rsi = chart.addIndicator(`//@version=5
indicator("RSI")
plot(ta.rsi(close, input.int(14, "Length")), "RSI", color.purple)`);
rsi.on('ready', () => console.log('RSI ready'));Where to go next
- Live mode (a forming candle + indicators recomputing on each tick): Options and FAQ.
- Runnable examples (a static and a live one, both offline): Examples.
- Full surface: API reference.
- Stuck? FAQ.