Satvik Akkarajuall systems operational
← All projects

Kafui

A native desktop app for Apache Kafka: manage clusters and topics, and browse, produce and live-tail messages, all running on your own machine

What it is

Kafui is a desktop app for working with Apache Kafka across multiple clusters. You save your clusters, browse and manage topics, and browse, produce and live-tail messages. It runs on macOS, Windows and Linux, and everything stays on the machine it’s installed on: there’s no server to run and no account to create.

The constraint that shaped it: an app that touches production brokers shouldn’t need anything between the user and their cluster, and message data shouldn’t travel anywhere it doesn’t have to.

How it’s built

  • Desktop app. An Angular UI in a Tauri 2 shell. The Rust side starts the agent when the window opens and stops it when the app quits.
  • Local agent. A Spring Boot service that ships inside the installer, together with a trimmed Java runtime built with jlink, so users don’t need Java installed. It listens only on the loopback address and holds the real broker connections through the official Kafka clients.
  • Saved clusters. A JSON file in the agent’s config directory. Credentials are encrypted at rest and never returned to the UI.

The UI talks to the agent over REST, and over Server-Sent Events for the live tail. The agent talks to the brokers directly, so it works over the user’s own network or VPN.

Key decisions

Local-first, no server. Everything the app needs ships in the installer. That removes deployment and accounts entirely, and it means message payloads only ever move between the user’s machine and their brokers.

EventSource for the live tail, not fetch streaming. The Linux webview buffers streaming fetch bodies, so records sat in the buffer and never reached the UI. The native EventSource delivers each frame as it arrives and reconnects on its own.

The UI waits for the agent. A JVM takes a couple of seconds to bind its port, so the app polls a health endpoint and shows a loader instead of letting the first screen fail against a socket that isn’t listening. It gives up after 30 seconds and offers a retry.

A cluster file that can’t corrupt itself. Saves go through a temp file and an atomic move, so an interrupted write can’t leave the list half-written. If the file is unreadable the agent refuses to start rather than quietly losing someone’s clusters.

Self-contained installers for five targets. Release CI builds macOS (Apple silicon and Intel), Windows, and Linux (x64 and ARM64), each with its own trimmed runtime. I dropped AppImage from Linux: bundling it needs FUSE, which GitHub’s runners don’t allow, so .deb and .rpm cover it.

Tradeoffs

  • Newest versions on purpose: Java 25, Spring Boot 4.1 and Angular 22. That cost real friction: Vitest replacing Karma, and NgRx Signals pinned a major version behind with a peer-dependency workaround until the matching release ships.
  • Big installers. Each one is around 120 MB because it carries a Java runtime and the agent.
  • Unsigned on macOS. The builds are ad-hoc signed but not notarized, so Gatekeeper warns on first open.
  • No shared state. Clusters live on each machine, so a team doesn’t share a cluster list yet.
  • A heavier toolchain: building the app takes a JDK, Rust and webview libraries.

Where it stands

Version 0.2, with installers published for macOS, Windows and Linux. Cluster management, topic browse and full topic management, and message browse, produce and live-tail are done. Consumer groups, a dashboard and Schema Registry support are next. I’ve been building it since July 2026.

An earlier design with a hosted plane for sign-in, roles and audit logging is halted for now, and will be released in the future. Its code lives on a separate branch.