Draftly is built on a decoupled graphics architecture. Unlike traditional web-based design tools that rely on JavaScript for geometry calculations, Draftly offloads all high-computation tasks to a standalone system core written in Rust.
graph TD
subgraph "Frontend (React 19 + Vite)"
UI[UI Shell & Panels]
State[React State - Tool Selection]
Canvas[Canvas Component]
end
subgraph "Bridge (WASM Glue)"
Events[Mouse/Keyboard Events]
Glue[wasm-bindgen / Glue Code]
end
subgraph "Graphics Engine (Rust Store)"
Engine[DraftlyEngine Struct]
Shapes[Scene Graph / Shapes List]
Render[Draw Logic]
end
UI --> Events
Events --> Glue
Glue --> Engine
Engine --> Shapes
Shapes --> Render
Render --> Canvas
- The Intelligence: All geometry math, shape storage, and rendering logic are implemented in Rust.
- Precision: Near-native execution speed and the absence of Garbage Collection (GC) pauses during complex rendering tasks ensure high performance and reliability.
- The Translator:
wasm-packserves as the build tool that compiles Rust source code into a WebAssembly binary and generates the corresponding JavaScript glue code. - Bridge Logic: It produces a suite consisting of
.jsand.d.tsfiles, enabling the Rust module to be integrated as a standard ES module.
- The Speed: The project is managed as a monorepo via Bun Workspaces. Bun handles package management and provides a high-performance development server for the API.
When modifications are made to the Rust engine, the following pipeline is executed to synchronize the client application:
cd engine
wasm-pack build --target webThis command updates the engine/pkg directory with the latest binary and JavaScript interfaces.
The client application connects to the engine via a symbolic link within the Bun monorepo:
# In client/package.json
"devDependencies": {
"engine": "link:../engine/pkg"
}Note: Due to Vite's dependency pre-bundling, a restart of the development server is required after significant changes to the WebAssembly structure:
bun run dev:clientThe connection between React and Rust utilizes a shared memory architecture rather than simple data passing.
sequenceDiagram
participant User
participant React
participant WASM_Glue
participant Rust_Engine
participant Canvas_API
User->>React: Click on Canvas
React->>WASM_Glue: engine.on_click(x, y, tool)
WASM_Glue->>Rust_Engine: Update Internal Shape Vector
Note over Rust_Engine: Logic: push Shape { x, y, type }
loop Every Animation Frame
React->>WASM_Glue: engine.render(ctx, w, h)
WASM_Glue->>Rust_Engine: Access Canvas 2D Context
Rust_Engine->>Canvas_API: ctx.fill_rect() / ctx.arc()
end
- Memory Isolation: The engine maintains a dedicated memory heap. The JavaScript layer transmits only primitive event data (coordinates, strings), mitigating the overhead of expensive data serialization and copying.
- Type Safety: The
engine.d.tsfile generated bywasm-packensures the React application has precise knowledge of the methods available in the Rust engine, facilitating full IDE support. - Hardware Acceleration: By driving the
CanvasRenderingContext2ddirectly from Rust, the system bypasses the overhead associated with JavaScript array iterations and complex object lookups.
Strict quality control is maintained across the entire development stack:
- Root Level:
bun run check(Parallelized Linting and Type Checking) - Rust Engine:
cargo clippy(Production-grade linting following strict safety standards) - TypeScript/JavaScript:
biome check(Modern, high-performance linter and formatter)