kestrel-loomv0.1.0

CASOON Open Source

Trading charts in the browser, drawn by Rust.

kestrel-loom puts an interactive candlestick chart on a canvas: zoom, pan, indicators, drawing tools. For web and desktop apps that show market data and would rather embed a chart than build one.

git clone https://github.com/casoon/kestrel-loom && cd kestrel-loom && ./build-wasm.sh
BUSL-1.1alphav0.1.0not on crates.io / npm
The kestrel-loom demo: synthetic five-minute candles with Bollinger Bands drawn over the price, an RSI pane below and a time axis with a scrollbar.The kestrel-loom demo: synthetic five-minute candles with Bollinger Bands drawn over the price, an RSI pane below and a time axis with a scrollbar.
indicators from kestrel-chartkit, reported by the WASM build
105
chart types, from candlestick to Renko and footprint
8
drawing tools, with snapping and undo/redo
7
scenes compared command by command in the tests
4

What it does

How it works

The chart lives in plain Rust: state, viewport, panes, tools and the render loop. That core knows no browser; it writes drawing commands, and a thin WebAssembly layer carries them out on the canvas. The indicator math comes from kestrel-chartkit, so neither project maintains the other's half.

From your page to the canvasYour page hands candles and input to the JavaScript wrapper. Through the WebAssembly façade they reach the Rust core, which keeps chart state, viewport and tools and takes its indicators from kestrel-chartkit. A render pass produces drawing commands, and the WASM crate executes them on a Canvas 2D context.From your page to the canvasYour page → kestrel-loom.jskestrel-loom.js → kestrel-loom: WASM façadekestrel-chartkit → kestrel-loom: on_barkestrel-loom → kestrel-loom-wasm: RenderCommandskestrel-loom-wasm → <canvas>WASM façadeon_barRenderCommandsYour page – candles, mouse, touchYour pagecandles, mouse, touchkestrel-loom.js – wrapper you embedkestrel-loom.jswrapper you embedkestrel-loom – Rust core, no browser APIkestrel-loomRust core, no browser APIkestrel-chartkit – indicator mathkestrel-chartkitindicator mathkestrel-loom-wasm – Canvas 2D executionkestrel-loom-wasmCanvas 2D execution<canvas> – the chart<canvas>the chart
From your page to the canvasYour page hands candles and input to the JavaScript wrapper. Through the WebAssembly façade they reach the Rust core, which keeps chart state, viewport and tools and takes its indicators from kestrel-chartkit. A render pass produces drawing commands, and the WASM crate executes them on a Canvas 2D context.From your page to the canvasYour page → kestrel-loom.jskestrel-loom.js → kestrel-loom: WASM façadekestrel-chartkit → kestrel-loom: on_barkestrel-loom → kestrel-loom-wasm: RenderCommandskestrel-loom-wasm → <canvas>WASM façadeon_barRenderCommandsYour page – candles, mouse, touchYour pagecandles, mouse, touchkestrel-loom.js – wrapper you embedkestrel-loom.jswrapper you embedkestrel-loom – Rust core, no browser APIkestrel-loomRust core, no browser APIkestrel-chartkit – indicator mathkestrel-chartkitindicator mathkestrel-loom-wasm – Canvas 2D executionkestrel-loom-wasmCanvas 2D execution<canvas> – the chart<canvas>the chart
From your page to the canvasYour page hands candles and input to the JavaScript wrapper. Through the WebAssembly façade they reach the Rust core, which keeps chart state, viewport and tools and takes its indicators from kestrel-chartkit. A render pass produces drawing commands, and the WASM crate executes them on a Canvas 2D context.From your page to the canvasYour page → kestrel-loom.jskestrel-loom.js → kestrel-loom: WASM façadekestrel-chartkit → kestrel-loom: on_barkestrel-loom → kestrel-loom-wasm: RenderCommandskestrel-loom-wasm → <canvas>WASM façadeon_barRenderCommandsYour page – candles, mouse, touchYour pagecandles, mouse,touchkestrel-loom.js – wrapper you embedkestrel-loom.jswrapper youembedkestrel-loom – Rust core, no browser APIkestrel-loomRust core, nobrowser APIkestrel-chartkit – indicator mathkestrel-chartkitindicator mathkestrel-loom-wasm – Canvas 2D executionkestrel-loom-wasmCanvas 2D execution<canvas> – the chart<canvas>the chart
From your page to the canvasYour page hands candles and input to the JavaScript wrapper. Through the WebAssembly façade they reach the Rust core, which keeps chart state, viewport and tools and takes its indicators from kestrel-chartkit. A render pass produces drawing commands, and the WASM crate executes them on a Canvas 2D context.From your page to the canvasYour page → kestrel-loom.jskestrel-loom.js → kestrel-loom: WASM façadekestrel-chartkit → kestrel-loom: on_barkestrel-loom → kestrel-loom-wasm: RenderCommandskestrel-loom-wasm → <canvas>WASM façadeon_barRenderCommandsYour page – candles, mouse, touchYour pagecandles, mouse,touchkestrel-loom.js – wrapper you embedkestrel-loom.jswrapper youembedkestrel-loom – Rust core, no browser APIkestrel-loomRust core, nobrowser APIkestrel-chartkit – indicator mathkestrel-chartkitindicator mathkestrel-loom-wasm – Canvas 2D executionkestrel-loom-wasmCanvas 2D execution<canvas> – the chart<canvas>the chart

Quickstart

Build the WASM package from the repository, load the wrapper and hand it a canvas. The documentation covers data, indicators, tools and the Rust core.

  1. Clone the repository and run ./build-wasm.sh; it writes the package to pkg/.
  2. Serve js/ and pkg/ next to each other and import createChart.
  3. Set candles in Unix seconds, fit the view, add indicators and tools.
chart.jsJavaScript
import { createChart } from './js/kestrel-loom.js';

const chart = await createChart(canvas, { timeframe: '5m' });
chart.data.set(candles);  // { time, o, h, l, c, v }
chart.view.fit();
chart.indicators.add('rsi');

A chart on your canvas in three steps.

Read the quickstart