BitFun: keeping a large Rust agent runtime below the Tauri boundary #15835
bobleer
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
BitFun: keeping a large Rust agent runtime below the Tauri boundary
Disclosure: I maintain BitFun, a Tauri v2 + React desktop agent for Windows, macOS, and Linux.
The interesting Tauri lesson for us was not how to add another command. It was how to stop a growing command surface from quietly turning the desktop host into the product architecture.
Our working rule is: keep product behavior platform-agnostic, then expose it through platform adapters. The Tauri app owns desktop integration, commands, window lifecycle, and OS automation; reusable agent, execution, and service behavior stays below it. That boundary is documented in the repository's root architecture rules and desktop host guide.
Three practices have helped as the app grew:
1. Make local-versus-remote behavior an explicit command contract
BitFun can open local or remote SSH workspaces. A new Tauri command that accidentally reads the local filesystem while a remote workspace is active can fail silently or, worse, act on the wrong machine.
Every registered command therefore has one policy:
RemoteRouted,RemoteUnsupported,LocalOnly,WorkspaceAgnostic, orLegacyUnaudited. Contract tests require a one-to-one match with the registered command list and forbid growth of the legacy backlog. The backlog is not zero yet, but it can only shrink. Policy and rationale2. Keep the frontend call shape independent of the transport
UI features invoke structured requests through an adapter instead of calling Tauri APIs directly. The web transport unwraps the same
{ request: ... }envelope, maps command names to JSON-RPC methods, and encodes the body into the app-server wire shape. That lets the desktop and web/remote surfaces reuse feature code without pretending their lifecycles are identical. WebSocket adapter3. Fan out events at one boundary
Peer-device controllers need selected UI events, but scattering remote-sync calls through product logic made ownership hard to reason about. We wrap the shared event emitter at the desktop boundary. It mirrors only eligible events to attached controllers and clones a payload only when fan-out will actually occur. Peer-aware emitter
This is still a work in progress. The explicit policy registry exposed real legacy debt, and keeping schemas aligned across Tauri and JSON-RPC requires regression tests. But those costs are visible now, rather than appearing later as "works locally, blank panel remotely" bugs.
I would be interested in how other larger Tauri apps handle two questions:
Repository: https://github.com/GCWing/BitFun
All reactions