KampányMűvek / 18 September 2026

We restarted the desktop Workshop: native SwiftUI replaced Rust/Tauri

We wanted a desktop application around the web-based Workshop, but even after several fixes the Tauri/Rust shell kept bringing web-oriented compromises back into the product. By the end of the day, the Engine remained the headless control plane and the client became a thin native macOS SwiftUI application.

2 min read
KampányMűvek
SwiftUImacOSdesktoparchitecture
Custom technical illustration of the move from a web desktop shell to a native SwiftUI client
A native desktop client above the headless Engine: the client can change while platform logic stays put.

Situation

The KampányMűvek generator, deployment flow and QA had become strong, but day-to-day operation was still too terminal-centric. The goal was therefore not to build a CMS, but an engineering control surface: a desktop Workshop from which sites, builds, operations and content tasks could be reached safely. The existing Tauri/Rust direction produced a working prototype quickly, but first a blocking Rust `Command::output()` call froze the UI, and later small-window navigation, menu behaviour, responsive CSS and the overall interaction model showed that we were still dressing a web application up as a desktop product.

Approach

We did not discard the approach immediately. We added a Job Manager with streaming stdout/stderr, progress and cancellation, separated Engine and Site operations, and introduced a macOS-style sidebar, scrollable navigation and light/dark/automatic themes. When we were still fixing shell limitations instead of the engineering workflow itself, we made the decision to drop the Tauri/Rust client and move to native SwiftUI. One architectural rule stayed non-negotiable: no business or control-plane logic may live in the desktop client. The Engine exposes state and operations through a headless JSONL interface; the Swift client only starts commands, consumes events and renders them as native UI. On top of that boundary we built workspace, Node, language and theme settings, port handling, bootstrap/dependency flows, legacy/generator/artifact development modes, Content CRUD, an Engine dashboard, Operations views and live logs.

Outcome

By the end of the day we no longer had a wrapped website; we had a functioning native macOS application foundation. Debug and release builds passed, macOS code-signing verification passed, and fleet smoke was green across all five sites while the Engine remained the single source of truth. The most important result was not the amount of Swift code, but the fact that the desktop layer had become replaceable without rewriting the platform logic.