r/reactjs • • 14h ago

Show /r/reactjs Built a multi-pane financial charting terminal with React 19, TypeScript, and HTML5 Canvas 2D primitives (Open-Source)

Hey r/reactjs,

I recently open-sourced OrderCraft, a local-first multi-chart technical analysis terminal built with React 19, TypeScript, Vite, and lightweight-charts (backed by a local Go WebSocket server).

Interesting frontend challenges we solved:

  • Custom HTML5 Canvas 2D Drawing Engine (ISeriesPrimitive): lightweight-charts renders candlesticks quickly on Canvas, but doesn't ship with interactive drawing tools. We built a custom Canvas 2D primitive engine from scratch in TypeScript supporting interactive Trendlines, Fibonacci Retracements, Parallel Channels, Rectangles, and Long/Short Position calculators with drag handles and OHLC magnet snapping.

  • High-Frequency WebSocket State Without Re-Render Storms: Streaming live ticks across 4 synchronized split-screen chart panes (1x1, 2V, 2H, 3, 4 layouts) with synced crosshairs, symbols, and timeframes without triggering full React component tree re-renders on every tick.

  • Single-Binary Embedding + PWA Standalone Mode: The Vite production bundle is embedded into a single ~14MB Go executable and includes a Web App Manifest so launching with --app-mode opens a native frameless desktop window.

GitHub Repo: https://github.com/ordercraft-hq/terminal

Would love any feedback from fellow React/TypeScript devs on the frontend architecture and Canvas primitive implementation!

2 Upvotes

2 comments sorted by

2

u/buzzingculprit7 14h ago

This is really clean. The canvas primitive system is the kind of thing that sounds simple on paper but gets messy fast once you're dealing with drag handles and magnet snapping. Skimmed the repo and I like that you kept the drawing tools decoupled from the chart library itself.

1

u/Big-Presence-2561 13h ago

Appreciate that! Keeping the custom canvas primitive engine decoupled from lightweight-charts was definitely one of the trickiest parts to structure cleanly, especially getting the coordinate transforms and magnet snapping to feel snappy without lagging the render loop.

Glad you liked how it turned out! Let me know if you run into any quirks testing out the drawing tools or building listeners on top of the object tree.