Hi all — I'd like to introduce Rivet, a framework (MIT, on the package catalog as rivet) for building desktop apps where the application logic is Racket and the UI is each platform's own first-party stack: SwiftUI on macOS, WinUI 3 on Windows, GTK4 on Linux. Its embedding model is inspired by Bogdan Popa's Noise — see "Why not a direct Noise port?" in the docs.
The short version: Rivet embeds the Racket CS runtime inside a real native app process. Your backend declares typed RPCs, events, and shared state; Rivet generates typed Swift / C++ / Kotlin native clients at build time; and the native UI layer stays genuinely native — Rivet is not a WebView framework and not a cross-platform widget toolkit. Each platform keeps its own UI stack and platform behavior.
Hello Rivet
The Racket backend declares the API shared by all three hosts:
#lang racket/base
(require rivet/backend)
(provide start)
(define-event progress)
(define-state counter : Int64 0)
(define-rpc (greet [name : String] : String)
(format "Hello, ~a!" name))
(define-rpc (increment [value : Int64] : Int64)
(add1 value))
(define (start in-fd out-fd)
(serve-fds in-fd out-fd))
raco rivet build reads the RPC / Event / State / Record / Enum schema and generates typed clients — Swift gets increment(value:), C++ gets the native equivalent, Kotlin gets suspend methods. The Racket runtime runs on a dedicated thread inside the app process; native code only ever sees framed messages and generated values, never raw Racket pointers.
What's in the box
- One backend contract (RPC / Event / State / Cancel) across all three desktop platforms
- Generated typed native clients (Swift, C++, Kotlin)
- A real toolchain:
raco rivet new / doctor / inspect --json / dev / build / package / verify - Agent-native by design: every generated project ships an
AGENTS.mdand a machine-readable project map, so coding agents can drive the full lifecycle - Production packaging: DMG (Developer ID), MSI (Authenticode), deb / rpm / AppImage — plus signed online-update manifests, so apps update themselves safely
- Real-time chart widgets over one typed data plane, on every host
- Keel contracts shared with our sibling framework Glaze (the web-UI flavor — separate post on that)
- Searchable docs: getting started · docs map · Taskboard example app
Is it a demo?
Fair question for any framework announcement, so: Rivet grew under a stack of shipped desktop apps, not the other way around. Everything below is built on it, releases real installers, and several of these self-update in the wild through Rivet's signed update channel — which is the best bug-finder a framework can ask for:
| App | What it is |
|---|---|
| Taskly | keyboard-first task manager, three platforms |
| Fulcrum | one-keystroke launcher, three platforms |
| Threadly | a native desktop client for this very forum |
| Payback | device cost / payback tracker |
| PodLens | podcast player with transcription & translation |
| PdfGist | local-first PDF reader with AI translation |
| Movebit | work-time tracker & break enforcer tray app |
| Brainfuel | always-on-top quota monitor widget |
| SyncPilot | Resilio Sync companion for Linux |
| Autarx | AUTOSAR integration workbench |
| Keyward | vault for release-signing keys of self-updating apps |
| gPTP Studio | Linux-native gPTP / IEEE 802.1AS debugging workstation (commercial) |
(Threadly being a native client for this forum is my favorite proof point — it's dogfooding all the way down.)
Honest scope
- Three platforms means three native UI codebases. The backend, contract, and generated clients are shared; the UIs are not. That's the trade Rivet makes on purpose — if you'd rather write one HTML UI, that's exactly what Glaze is for.
- Mobile (iOS / iPadOS / watchOS / Android) has real foundations — typed codecs, generated clients, CI cross-compiles — but finished mobile app delivery is not there yet.
- You write the native UI in Swift / C++ / Kotlin yourself. Rivet generates the bridging layer, not your views.
Try it
raco pkg install --auto rivet
raco rivet new hello
cd hello && raco rivet dev
raco rivet doctor checks your native toolchain and tells you what's missing in plain language.
Current release: v0.11.0. Feedback, issues, and "why doesn't it do X" are all very welcome — issues or right here in this thread. What would you want from a Racket-native desktop stack?