Announcing Rivet: first-party native desktop apps with a Racket core (SwiftUI / WinUI 3 / GTK4)

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.md and 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?

1 Like

Good on you for ripping off Noise with AI, I guess.

4 Likes

@turinglambdaai ... you sound a lot like AI. Just saying? I'm not really convinced that you're human. Wow. It's a weird world we live in.

1 Like

(In addition to the more fundamental critiques already made:)

I would suggest that this is not a useful description. I am not aware of any GUI solution in Racket that is a “cross-platform widget toolkit.”

In particular, racket/gui does not work that way. For example, a Racket button% is implemented by a native GtkButton, NSButton, or a Win32 BUTTON.

(Technically, it is possible to specially configure Racket to use GTK on Mac OS and even Windows, but this is not the default or a common configuration. Historically, PLT Scheme used wxWidgets—which is closer to being a “cross-platform widget toolkit,” but still not in the sense of e.g. Qt—but that has not been the case at least since the port of racket/gui from C++ to Racket in Racket 5.1 (February 2011), and I think wxWidgets may have been replaced even earlier.)

1 Like

but this is exactly the definition of turing test:

:sweat_smile:

2 Likes

Obligatory: the Turing test paper is weird! Cf.

(Really, give them both a listen.)

2 Likes

Ben,
cet échange d'articles scientifiques me fait penser aux joutes verbales de Brice de Nice :laughing:
comme je crois que tu parles assez français et qu'il est 4h du matin ici et que je suis de Nice et pas un type assez sérieux pour répondre sérieusement et j'ai vraiment que cette vidéo en tête à ce moment :

:joy: :joy: :joy:

(But i really have a look to the articles, but the audio file is too hard for me in english, but i read entirely the first text article.)

Damien de Nice