the story

Why I built k4s

k9s is a great tool. So is lazykube. So is kubectl itself. So why another Kubernetes TUI?

I've used k9s for a while. It is excellent. It is also a trap — once you live inside the TUI, you stop reaching for kubectl. After a few months I could navigate a busy cluster blindfolded, and still couldn't remember the flags for kubectl logs. I'd built the wrong muscle.

The thing is, the TUI is the right interface most of the time. Filtering, paging, switching contexts, watching pods churn — that's all faster keyboard-driven than typing it out. But on-call? In a CI hook? On someone else's laptop with no TUI installed? You need kubectl, and you need to know it cold.

So I wanted a hybrid. Full TUI for speed, but every shortcut surfaces the underlying kubectl in the footer so I leave each session knowing one more command. Press l on a pod and the footer flashes kubectl logs -f -c …. Press :ns and the footer flashes kubectl get namespaces. After a week, you just know.

I called it kubectl by osmosis. It's the design idea the whole tool is built around. Read more on the FAQ, or skip ahead to the honest comparison vs k9s.

Bubble Tea is a joy to write in. The Elm-style update loop turns out to be a perfect fit for a Kubernetes TUI: the cluster is the state, the watcher is a subscription, and every keystroke is a deterministic message. I introduced an Action abstraction on top — every "do thing" path (logs, exec, describe, top, switch context) is a named verb with a structured payload. Today it powers footer hints; on the roadmap, every Action will emit an audit event so a session is fully replayable.

k4s is opinionated. It picks what to expose, when to flash a --watch, when to drop you back to home. It will probably never grow plugins. The opinion is the product. If you want a more general, more configurable, broader-feature TUI, k9s is genuinely better — go use it.

Made for k3s and k8s alike. The client-go footers stay the same whether you're talking to a Raspberry Pi cluster or EKS. I built it on a k3s docker-compose because the iteration loop was tighter; the same binary handles a 200-node prod cluster without changes.

k4s won't replace k9s. It's for the people who use a TUI but also want to leave with sharper kubectl reflexes.

kubectl by osmosis

The footer is the lesson.

k4s — pods · k4s-demo
NAMESPACE   NAME                   READY   STATUS    RESTARTS   AGE
k4s-demo    nginx-58bcfc684b-bcqpk 1/1     Running   0          14h
k4s-demo    nginx-58bcfc684b-r56bp 1/1     Running   0          14h
q quit · ^c quit · esc back · : command · ? help · enter describe · l logs
≈ kubectl get pods -n k4s-demo --watch
Press :ns and the footer flashes kubectl get namespaces. Press l and the footer flashes kubectl logs -f. After a week, you just know.

Try k4s now.

Single binary. No daemon. Works on any cluster reachable through kubeconfig.

go install github.com/LywwKkA-aD/k4s/cmd/k4s@latest