all posts
engineering

why we chose rust for a kubernetes desktop app

building a native desktop app for kubernetes management — why we picked rust over electron, and what we learned along the way.

Nov 18, 20258 min readby kdashboard team

When we started building kdashboard, the first decision was the tech stack. For a Kubernetes management app, performance and resource efficiency aren't nice-to-haves — they're requirements.

Why not electron?

Electron is the default choice for cross-platform desktop apps. VS Code, Slack, Discord — all Electron. It's proven, has a massive ecosystem, and lets you reuse web skills.

But Electron comes with trade-offs:

  • Memory: A minimal Electron app consumes 80-150MB of RAM. A Kubernetes tool that's always running alongside resource-hungry clusters can't afford that
  • Binary size: Electron bundles Chromium, resulting in 150-300MB downloads
  • Startup time: Cold start takes 2-5 seconds depending on the machine
  • CPU: The Chromium renderer is always running, even when idle

For a tool that engineers keep open all day, these costs compound.

Why Rust?

Rust gives us:

Near-zero overhead

Our binary is ~15MB. Memory usage starts at 20MB and stays under 60MB even with multiple clusters connected. Cold start is under 500ms.

GPU-accelerated rendering

We use a GPU-accelerated rendering approach for the UI. This means smooth 60fps scrolling through thousands of log lines, animated status transitions, and responsive interactions even under heavy data loads.

Safe concurrency

Kubernetes management involves heavy concurrent I/O — watching multiple resources, streaming logs from several pods, maintaining WebSocket connections. Rust's ownership model prevents data races at compile time, which means fewer runtime bugs.

Cross-platform from day one

Rust compiles natively to macOS, Windows, and Linux. No compatibility layers, no platform-specific quirks in the runtime.

The learning curve

Let's be honest — Rust has a steep learning curve. The borrow checker is famously demanding, and the ecosystem for desktop UI is less mature than web frameworks.

What helped:

  • Start with the data layer: We built the Kubernetes API client, log streaming, and port forwarding logic first. This is where Rust shines — async I/O, error handling, type safety
  • Iterate on the UI: The UI layer took more experimentation. We tried several approaches before settling on one that felt productive
  • Lean on the ecosystem: The Rust ecosystem for Kubernetes (kube-rs), async runtime (tokio), and serialization (serde) is excellent

Performance in practice

Some real-world benchmarks from our development builds:

Metrickdashboard (Rust)Typical Electron app
Binary size~15MB~200MB
Cold start<500ms2-5s
Idle memory20MB100-150MB
Log streaming (1000 lines/s)<5% CPU15-25% CPU
Cluster watch (50 resources)<2% CPU8-12% CPU

These numbers matter when your machine is already running Docker, a browser with 40 tabs, your IDE, and a local Kubernetes cluster.

Trade-offs we accepted

Nothing is free:

  • Slower iteration speed: Rust compile times are longer than JavaScript hot-reload
  • Smaller talent pool: Fewer engineers know Rust compared to TypeScript
  • Less UI ecosystem: No equivalent of npm's 2M+ packages for UI components
  • Steeper onboarding: New contributors need Rust knowledge

We believe the end result — a fast, lightweight, native application — is worth these trade-offs for a tool that engineers use daily.

The result

kdashboard starts instantly, barely touches your CPU when idle, and handles heavy log streaming without breaking a sweat. That's the Rust advantage in practice.