sofka: a Rust Kubernetes TUI built on kube-rs and ratatui
A Kubernetes TUI, reimagined in Rust - built on kube-rs and ratatui, async-first from the ground up.
At a glance
- What is it?
- sofka is an async Kubernetes terminal UI written in Rust, with native Flux CD and Argo CD actions and an evidence-based incident view. It installs from Homebrew, Nix, Cargo or prebuilt release binaries, and the README is explicit that those macOS binaries are not yet signed or notarized.
- Who is it for?
- sofka suits engineers who already live in a terminal, run Flux CD or Argo CD, and want suspend, resume, sync and reconcile without a second CLI on the PATH. Skip it if you need a signed, notarized macOS binary or you work mostly in a browser dashboard.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 19, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
What sofka solves, and who it is aimed at
kubectl answers one question per invocation. A terminal UI is meant to hold cluster state on screen and let you move between resources without retyping a command. sofka is a Kubernetes TUI written in Rust on kube-rs and ratatui, and the README frames the core promise as async everywhere, so the UI never blocks on the cluster. That is the whole design premise: a watch stream can stall, a port-forward can hang, and the interface keeps redrawing.
The intended user is a platform or SRE engineer who already works from a terminal and runs GitOps tooling. Two capabilities make that audience specific. Flux CD support is built in: t suspends, resumes and reconciles through native API patches, and the README states no flux binary is required. Argo CD support is built in on the same terms: t suspends, resumes and syncs Applications, ApplicationSets support suspend and resume, and no argocd binary is required. If you do not run either controller, that part of the tool is inert for you.
The second audience signal is the incident view. X opens what the README calls a deterministic, evidence-based incident view, with no AI and no external service. For anyone who has watched a colleague paste pod YAML into a hosted model to ask why it is broken, the boundary is deliberate. The trade-off is that the view is only as good as the evidence the cluster exposes; it does not reason about your application's semantics.
The object pipeline behind the resource views
The README describes a shared object pipeline, and says both sofka and k9s use one and that both support built-in and custom resources. The practical consequence is that custom resources are not a special screen bolted on the side. There is one generic render pipeline: built-in columns for common kinds, NAME and AGE for everything else, and pressing enter on a CRD drills into its custom resources. A CRD you install tomorrow renders with the fallback columns rather than an error.
The dependency list in Cargo.toml tells you what sits underneath. kube 4.2.0 is pulled with a reduced feature set that still includes runtime, client, ws, http-proxy, socks5, gzip and oidc. That is a deliberate build: websocket exec and attach, proxy and SOCKS5 support, and OIDC authentication are all compiled in, which matters for clusters behind a jump host or an identity provider. k8s-openapi 0.28 is pinned with the latest feature, and ratatui 0.30.1 with crossterm 0.29.0 provides the terminal layer. The Rust edition is 2024.
Some behaviour is not in the README. The README does not document how the watch cache is invalidated, how many resources are held in memory, or what happens when a watch stream drops mid-session. If you operate large clusters, that is the area to probe yourself before trusting the tool on a production context.
Installing sofka and running a first session
The README lists three package-manager routes and prebuilt binaries. Homebrew covers macOS and Linux, Nix runs it without installing anything, and Cargo builds from source. Pick one.
brew install nklmilojevic/sofka/sofka # Homebrew (macOS/Linux)
nix run github:nklmilojevic/sofka # Nix, nothing to install
cargo install sofka # CargoIf you downloaded a tarball in a browser on macOS, the README says Gatekeeper will refuse it because the release binaries are not signed or notarized yet. The documented fix is to clear the quarantine attribute once. The README also notes you can right-click the binary in Finder, pick Open and confirm once.
xattr -d com.apple.quarantine sofkaBefore connecting to anything real, run the headless check. It needs no TTY, and the README presents it as doubling as a CI smoke test: it connects, runs discovery, prints a summary and exits. If authentication or RBAC is wrong, you find out here rather than inside the UI.
sofka --checkThen open a resource. The launch form takes a resource, a namespace flag, an all-namespaces flag, and context and kubeconfig options. The README gives the defaults: the resource defaults to pods, and the context defaults to the current one.
sofka [RESOURCE] [-n NAMESPACE] [-A] [--context NAME] [--kubeconfig PATH] [--readonly | --write]If you would rather choose the cluster first, the README documents sofka ctx or sofka contexts, which opens the context picker before connecting. Selecting a context connects and opens that context's configured default resource, or pods. An unknown name returns an error. Note the constraint the README states: -n and -A apply to the first successful selection only, and these launch commands require interactive mode, so they cannot be combined with --check or --snapshot.
Read-only mode is a session rule, not a habit
Guardrails are where a TUI earns or loses trust, because the destructive key is usually one keystroke from the inspect key. sofka's README puts it as never delete in prod is enforced, not remembered. The mechanism is a mode attached to the session.
--readonly disables every mutating action for the session. --write forces write mode and overrides any readonly setting in config. Both flags win over the config readonly option, including per-cluster and per-context overrides, on every :ctx switch. With no flag, the rule is contextual: switching into a context whose config sets readonly = true enables read-only mode, shown as [read-only] in the header, and switching away restores write mode. Bulk actions follow the same rule. space marks rows for delete, kill or Flux actions across many resources at once, which is exactly the operation you do not want available in the wrong context.
There is a real limitation in this design. The flag is per session, and the config rule is per context. If your prod context is not marked readonly = true in config, nothing stops a write except your own typing. The README does not describe an organisation-wide policy file or a server-side enforcement path. Treat the config entry as the enforcement point and audit it the same way you audit kubeconfig.
Flux and Argo CD actions without their CLIs
The most concrete difference from a general-purpose Kubernetes TUI is that the GitOps controllers are first-class. For Flux, t suspends, resumes and reconciles through native API patches, and the README states no flux binary is required. There is also a native Helm inspector that decodes release Secrets itself, rather than shelling out to helm. For Argo CD, t suspends, resumes and syncs Applications, ApplicationSets support suspend and resume, and again the actions use native API patches with no argocd binary.
The approach matters because it changes what you have to install and what credentials you need. Talking to the API directly means one authentication path, the one sofka already uses to read the cluster. It also means the tool is bound to the CRD schema it knows about. The README does not describe what happens when a Flux or Argo CD version changes a field the patches depend on. If you pin controller versions conservatively, that is fine. If you track upstream releases closely, test the actions after an upgrade rather than assuming they still apply cleanly.
This is also the clearest case where sofka is the wrong tool. If your GitOps workflow is built around flux CLI or argocd CLI behaviour, including their output formats and their own configuration, replacing them with TUI keybindings removes the scriptable surface. sofka is for interactive work, not for pipelines.
Where the design costs you something
The macOS signing gap is the first limitation and it is stated plainly in the README. The release binaries are not signed or notarized yet, so a browser-downloaded tarball is quarantined. The xattr workaround is documented and simple, but it is a per-binary step, and it is the kind of thing that makes a tool awkward to distribute inside a managed fleet. If your organisation requires notarized binaries, sofka does not meet that bar today. The README also points to docs/release-packages.md for installation and platform limits, which is where the platform-specific caveats live.
The second limitation is scope. This is a terminal interface. It has no browser UI and no server component. Everything happens on the machine where you run it, against the kubeconfig you point it at. That is a feature for a single operator and a problem for a team that wants a shared view.
The third is the experimental native describe. The README says native describe is experimental and uses the standalone deskribe Rust library, enabled with --experimental-describe or [experimental] native_describe = true in config to use it for d. Kubectl remains the default. A feature that ships behind a flag and carries an experimental label is one to evaluate on non-critical clusters first, particularly because the describe output is what people paste into incident tickets.
How sofka differs from k9s
The README names k9s as the inspiration and links a comparison document at docs/vs-k9s.md, which it describes as covering shared functions and design differences. The shared ground is stated directly: both use a shared object pipeline, and both support built-in and custom resources. If you are a k9s user, the muscle memory for browsing resources transfers.
The difference in approach is the language and runtime underneath. k9s is a Go program. sofka is Rust on kube-rs and ratatui, with the async premise stated in the first line of the README. The dependency list shows the consequences: rustls with aws-lc-rs rather than a Go TLS stack, hyper for HTTP, tokio for the runtime. Whether that produces a better experience on your cluster is something you have to observe; the README makes no performance claim, and none should be inferred from the language choice alone.
The second difference is the GitOps surface. sofka builds Flux and Argo CD actions into the interface as native API patches. That is a narrower bet than a general Kubernetes browser, and it is the reason the topic list includes argocd, flux and fluxcd alongside k8s and kubectl. If you use neither controller, that work is dead weight for you and a general-purpose TUI may fit better.
The third difference is the incident view. X opens a deterministic, evidence-based view with no AI and no external service. That is a deliberate constraint rather than a missing feature, and it sets a clear expectation: you get evidence assembled from the cluster, not a generated explanation.
Editorial conclusion
sofka suits engineers who already live in a terminal, run Flux CD or Argo CD, and want suspend, resume, sync and reconcile without a second CLI on the PATH. Skip it if you need a signed, notarized macOS binary or you work mostly in a browser dashboard. Before adopting it, verify the actual release artefacts on the releases page for your platform, read docs/vs-k9s.md for the design differences, and run sofka --check against a non-production context to confirm discovery succeeds.
Frequently asked questions
What does the name sofka mean?
The README says sofka is the Serbian short form of Sophia, which means wisdom, and that the project is named after Sophie, a Russian Blue cat that watches the screen behind the monitor.
How do I install sofka on macOS?
The README gives three routes: brew install nklmilojevic/sofka/sofka, nix run github:nklmilojevic/sofka, or cargo install sofka. If you downloaded a release tarball in a browser, Gatekeeper will refuse it because the binaries are not signed or notarized yet, and the README documents clearing the quarantine flag once with xattr -d com.apple.quarantine sofka.
Does sofka need the flux or argocd CLI installed?
No. The README states that Flux suspend, resume and reconcile actions and Argo CD suspend, resume and sync actions all use native API patches, with no flux binary and no argocd binary required.
Can I run sofka without a terminal, for example in CI?
Yes for the headless modes. The README lists sofka --check, which connects, runs discovery, prints a summary and exits, and sofka pods --snapshot, which renders one frame of a resource view to stdout. The launch commands such as sofka ctx require interactive mode and cannot be combined with --check or --snapshot.
How does sofka prevent accidental deletion in production?
Through session mode. The README states that --readonly disables every mutating action for the session and that --write overrides any config readonly setting, and that with no flag a context whose config sets readonly = true enables read-only mode, shown as [read-only] in the header.
Community notes