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

**URL:** <https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433>\
**Category:** Show & Tell\
**Created:** [October 14, 2026, 8:10pm UTC](https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433 "2026-10-14T20:10:51Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![turinglambdaai](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/turinglambdaai/32/2716_2.png) [@turinglambdaai](https://racket.discourse.group/u/turinglambdaai)\
**Post date:** [October 14, 2026, 8:10pm UTC](https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433/1 "2026-10-14T20:10:51Z")

</div>

Hi all — I'd like to introduce [Rivet](https://github.com/turinglambdaai/rivet), a framework (MIT, on the [package catalog](https://pkgs.racket-lang.org/) 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](https://github.com/Bogdanp/Noise) — see ["Why not a direct Noise port?"](https://github.com/turinglambdaai/rivet/blob/main/docs/architecture.md#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:

```racket
#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](https://github.com/turinglambdaai/keel) contracts shared with our sibling framework [Glaze](https://github.com/turinglambdaai/glaze) (the web-UI flavor — separate post on that)
- Searchable docs: [getting started](https://github.com/turinglambdaai/rivet/blob/main/docs/getting-started.md) · [docs map](https://github.com/turinglambdaai/rivet/blob/main/docs/README.md) · [Taskboard example app](https://github.com/turinglambdaai/rivet/tree/main/examples/taskboard)

## 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](https://github.com/turinglambdaai/taskly) | keyboard-first task manager, three platforms |
| [Fulcrum](https://github.com/turinglambdaai/fulcrum) | one-keystroke launcher, three platforms |
| [Threadly](https://github.com/turinglambdaai/threadly) | a native desktop client for this very forum |
| [Payback](https://github.com/turinglambdaai/payback) | device cost / payback tracker |
| [PodLens](https://github.com/turinglambdaai/podlens) | podcast player with transcription & translation |
| [PdfGist](https://github.com/turinglambdaai/pdfgist) | local-first PDF reader with AI translation |
| [Movebit](https://github.com/turinglambdaai/movebit) | work-time tracker & break enforcer tray app |
| [Brainfuel](https://github.com/turinglambdaai/brainfuel) | always-on-top quota monitor widget |
| [SyncPilot](https://github.com/turinglambdaai/syncpilot) | Resilio Sync companion for Linux |
| [Autarx](https://github.com/turinglambdaai/autarx) | AUTOSAR integration workbench |
| [Keyward](https://github.com/turinglambdaai/keyward) | vault for release-signing keys of self-updating apps |
| [gPTP Studio](https://github.com/turinglambdaai/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

```bash
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](https://github.com/turinglambdaai/rivet/issues) or right here in this thread. What would you want from a Racket-native desktop stack?

---

<div class="post-metadata">

**Author:** ![bogdan](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/bogdan/32/8_2.png) [@bogdan](https://racket.discourse.group/u/bogdan)\
**Post date:** [October 15, 2026, 3:47am UTC](https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433/2 "2026-10-15T03:47:35Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![turinglambdaai](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/turinglambdaai/32/2716_2.png) [@turinglambdaai](https://racket.discourse.group/u/turinglambdaai)\
**Post date:** [October 15, 2026, 8:19am UTC](https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433/3 "2026-10-15T08:19:39Z")

</div>

Hi Bogdan — fair callout, and I should have said this in the announcement itself: Rivet's embedding model is directly inspired by [Noise](https://github.com/Bogdanp/Noise). The credit is in the [README](https://github.com/turinglambdaai/rivet) ("The embedding model is inspired by Noise…"), and [docs/architecture.md](https://github.com/turinglambdaai/rivet/blob/main/docs/architecture.md) has a section — "Why not a direct Noise port?" — on what we kept and where Rivet diverges. But this thread is where most people meet the project first, so that's where the credit belonged.

The longer version of the credit: your open-source work is a big part of why I'm building in Racket at all. koyo showed me what a production-grade Racket project can look like, your blog posts made so much of the ecosystem legible, and Noise proved the embedding approach Rivet stands on — Racket CS inside a native app process, with the UI staying fully native behind a message boundary. Rivet's part is making that contract platform-neutral from day one: Swift and C++ as peer clients over one typed protocol, plus the lifecycle, packaging, and signed-update tooling around it, rather than a Swift-first core translated to other platforms later.

However the code gets written, the ideas we build on are ours to credit — so: thank you. Giving something back to the Racket community is exactly what all of this is for, and if you ever take Rivet for a spin, honest feedback would mean a lot.

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [October 17, 2026, 5:08am UTC](https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433/4 "2026-10-17T05:08:07Z")

</div>

@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.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [October 18, 2026, 7:39pm UTC](https://racket.discourse.group/t/announcing-rivet-first-party-native-desktop-apps-with-a-racket-core-swiftui-winui-3-gtk4/4433/5 "2026-10-18T19:39:59Z")

</div>

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

> [@turinglambdaai](#):
>
> … the native UI layer stays genuinely native — Rivet is not … a cross-platform widget toolkit.

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](https://web.archive.org/web/20101211053922/http://blog.racket-lang.org/2010/12/racket-version-5.html) in Racket 5.1 (February 2011), and I _think_ wxWidgets may have been replaced even earlier.)
