A sample application demonstrating the WREN Stack - a lightweight desktop application architecture that fuses web UI technologies with native F# code.
WebView + Reactive + Embedded + Native
The WREN Stack eliminates the bloat of Electron by using the operating system's native WebView (WebKitGTK on Linux, WebView2 on Windows, WKWebView on macOS) as a rendering surface while running application logic as native code compiled by Firefly.
| Aspect | Electron | WREN Stack |
|---|---|---|
| Binary Size | 150-300 MB | 2-10 MB |
| Memory Usage | 100-200 MB | 10-30 MB |
| Cold Start | 2-5 seconds | 50-200 ms |
| Browser Engine | Bundled Chromium | System WebView |
┌─────────────────────────────────────────────┐
│ WREN Stack Application │
├─────────────────────────────────────────────┤
│ Frontend (Face) │ Backend (Brain) │
│ ───────────────── │ ────────────────── │
│ Partas.Solid │ F# Native Code │
│ Fable → JavaScript │ Firefly → LLVM │
│ DaisyUI + Tailwind │ Direct syscalls │
├─────────────────────────────────────────────┤
│ BAREWire over localhost WebSocket │
└─────────────────────────────────────────────┘
WrenHello/
├── src/
│ ├── Shared/
│ │ └── Protocol.fs # Shared types (compiled by both Fable & Firefly)
│ ├── Frontend/
│ │ └── App.fs # Partas.Solid UI components
│ └── Backend/
│ └── Main.fs # Native F# application entry point
├── index.html # Vite entry point
├── vite.config.js # Vite bundler configuration
├── tailwind.config.js # Tailwind CSS configuration
└── package.json # Node dependencies for frontend build
Defines message types that are compiled by both Fable (for the frontend) and Firefly (for the native backend). BAREWire ensures binary compatibility between the two representations.
type WindowAction =
| Close
| Maximize
| RestoreUses Partas.Solid (F# bindings for SolidJS) with DaisyUI components. The UI sends typed commands to the native backend via BAREWire over WebSocket.
Native F# code compiled by Firefly that creates a GTK window with a WebKitGTK WebView and handles commands from the frontend.
- .NET SDK (for Fable compilation)
- Node.js (for Vite and frontend dependencies)
- Firefly (for native F# compilation)
- GTK4 and WebKitGTK (on Linux)
npm install
npm run buildThis runs Fable to compile F# to JavaScript, then Vite to bundle everything.
The complete WREN Stack build process ("The Weld") is handled by Firefly:
- Fable compiles
src/Frontend/*.fs→ JavaScript - Vite bundles JS + CSS →
index.html - Firefly embeds
index.htmlinto the native binary's.rodatasection - Firefly compiles
src/Backend/*.fs→ MLIR → LLVM → native binary
- Startup: The native binary spawns a WebSocket server on localhost and creates a system WebView window
- UI Loading: The embedded HTML (with all assets inlined) is passed directly to
WebView.setHtml()- no file fetches needed - Communication: Frontend and backend exchange BAREWire-encoded binary messages over the WebSocket
- Reactivity: Partas.Solid's fine-grained reactivity updates only the DOM nodes that changed
- The WREN Stack Blog Post - Full architectural deep-dive
- Partas.Solid - F# bindings for SolidJS
- Firefly - F# to native compiler via MLIR/LLVM
- BAREWire - Binary serialization framework
- DaisyUI - Tailwind CSS component library
MIT