Skip to main content

Architecture

vroom's architecture is designed around a single principle: one rendering core, many platforms. A shared C++ engine built on Skia handles all drawing, while thin platform-specific wrappers handle the canvas surface and input events.

High-level design​

┌─────────────────────────────────────────────┐
│ Your App │
├──────────────┬──────────────┬────────────────┤
│ React Native│ React DOM │ (future) │
│ VroomChart │ VroomChart │ Swift / Kotlin│
├──────────────┼──────────────┼────────────────┤
│ JSI Bridge │ WASM glue │ FFI │
├──────────────┴──────────────┴────────────────┤
│ C++ Core (Skia) │
│ ┌──────────────────────────────────────┐ │
│ │ extern "C" facade (vroom_chart.h) │ │
│ ├──────────────────────────────────────┤ │
│ │ Renderer │ Layout │ Indicators │ │
│ ├──────────────────────────────────────┤ │
│ │ Gestures │ Drawings│ Liquidity │ │
│ └──────────────────────────────────────┘ │
└──────────────────────────────────────────────┘

The C++ core​

The core (packages/core/) is a C++17 library that does all the heavy lifting:

  • Rendering: Draws candles, volume bars, indicators, gridlines, axes, crosshair, and drawing tools directly to an SkCanvas
  • Layout: Computes pixel positions from data-space coordinates, handling pan/zoom transforms
  • Indicators: Computes RSI, MACD, ATR, VWAP, Bollinger Bands, Ichimoku, Fair Value Gaps, SMA, and EMA from OHLCV data
  • Gestures: Processes pan, pinch, zoom, and axis-drag inputs, updating the viewport
  • Crosshair: Snaps to candle-aligned time slots and computes OHLCV at the cursor position

The core exposes a public extern "C" facade in vroom_chart.h, making it callable from any language with C FFI support (JSI, WASM, JNI, Swift).

Platform wrappers​

React Native (react-native-vroom-chart)​

React Native JS
└── JSI (C++ bridge)
└── vroom C++ core (statically linked)
└── Skia canvas from @shopify/react-native-skia
  • The JSI bridge calls the C++ core directly — no serialization overhead
  • Gesture handlers (react-native-gesture-handler + Reanimated worklets) forward events to the core
  • The core renders to a Skia canvas provided by @shopify/react-native-skia ≥ 2.11 (which also needs react-native-worklets ≥ 0.7)

Web (@vroomchart/react + @vroomchart/core-wasm)​

React DOM JS
└── @vroomchart/react
└── @vroomchart/core-wasm (JS loader)
└── vroom_core.wasm (Emscripten-compiled C++ core)
└── Skia-WASM canvas
  • The C++ core is compiled to WebAssembly via Emscripten
  • @vroomchart/core-wasm loads the WASM module and provides loadVroom()
  • @vroomchart/react wraps it in a React component with Pointer/Wheel event forwarding
  • WASM assets (.wasm, .mjs, .ttf) are bundled inside the package — consumers don't host them

Data flow​

App provides Candle[] + props
↓
Platform wrapper forwards to C++ core
↓
Core computes layout + renders to Skia canvas
↓
Canvas pixels displayed on screen
↓
User gesture → platform wrapper → core updates viewport → re-render

Events flow back up:

Core fires event (crosshair, viewport change)
↓
Platform wrapper calls your callback (onCrosshair, onViewportChange)
↓
Your app reacts (render OHLCV readout, haptics, fetch more data)

Future platforms​

The extern "C" facade means the same core can be consumed by:

  • Android (native): JNI bridge → AAR with idiomatic Kotlin API
  • iOS (native): Swift FFI → SwiftPM with idiomatic Swift API
  • Desktop: Native windowing (Skia's own backend)

Each platform wrapper would own the canvas surface and gesture forwarding, identical to the existing React Native and web patterns.