qb
EMACS for Kubernetes.
A keyboard-driven terminal UI for managing Kubernetes clusters. Single binary, native K8s API, no kubectl dependency.
┌ prod-cluster > All Namespaces > Deployments ───────────────── ⟳ just now ┐
├───────────────────────┬──────────────────────────────────────────────────┤
│ Overview │ NAME NAMESPACE READY UP-TO-DATE │
│ Favorites (3) │▶ api-gateway production 3/3 3 │
│ Port Forwards │ auth-service production 2/2 2 │
│ Profiles │ web-frontend production 5/5 5 │
│ WORKLOADS │ coredns kube-system 2/2 2 │
│ Deployments (12) │ metrics-server monitoring 1/1 1 │
│ StatefulSets (2) │ │
│ Pods (24) │ │
│ NETWORK │ │
│ Services (8) │ │
│ CONFIG │ │
│ Secrets │ │
│ CERT-MANAGER.IO │ │
│ Certificate │ │
│ ClusterIssuer │ │
├───────────────────────┴──────────────────────────────────────────────────┤
│ e Edit l Logs D Delete F PortFwd * Star / Filter ? Help q Quit │
└──────────────────────────────────────────────────────────────────────────┘
Why qb
Most Kubernetes dashboards are web apps that need a running backend, a browser, and a pile of YAML to deploy. kubectl is powerful but context-switching between commands and mentally tracking state across namespaces is slow.
qb gives you a single binary that connects directly to the K8s API server through your kubeconfig. You see everything at once -- resources, logs, port forwards, events -- and act on any of it without leaving the terminal. It discovers Custom Resources automatically, so third-party operators (cert-manager, Argo, Istio, etc.) show up in the sidebar with zero configuration.
Features
Browse
- 26 built-in resource types across Workloads, Network, Config, Storage, RBAC, and Cluster categories
- Custom Resources discovered automatically from CRDs, grouped by API group in the sidebar
- All namespaces by default with a namespace column; narrow with
n - Cluster overview on startup: node grid cards, pod health gauges, cluster stats
- Regex filter (
/) against name, namespace, and all column values - Resource count badges in the sidebar
- 2-second auto-refresh that preserves scroll position and selection
Inspect
- Smart detail views with structured, per-resource-type rendering (replicas, conditions, ports, rules, volumes, etc.)
- YAML view toggle with
v - Related events shown at the bottom of every detail view (kubectl-describe style)
- Related resources -- navigate to owner references, pods, services with
r - Labels and annotations --
l/ato select,Spaceto expand long values,yto copy - Secret decoding --
Spaceto decode base64 values in-place
Act
| Key | Action | Scope |
|---|---|---|
e |
Edit in $EDITOR with diff preview before apply |
Any resource |
C |
Create from YAML template in $EDITOR |
Any type |
D |
Delete with confirmation | Any resource |
S |
Scale replicas | Deployment, StatefulSet, ReplicaSet |
R |
Rolling restart | Deployment, StatefulSet, DaemonSet |
d |
Diff two resources side-by-side | Any two of same type |
K |
Cordon/uncordon | Node |
T |
Drain (cordon + evict pods) | Node |
T |
Trigger Job from CronJob | CronJob |
Logs
- All pods, all containers aggregated by default for any workload
- Color-coded by pod -- each source pod gets a distinct prefix color
- Strictly timestamp-ordered -- lines from different pods merge correctly
- Auto-discovery of new pods -- rolling updates are captured without reopening the log view
- Follow mode (
f) for live streaming - Regex filter (
/) with inline match highlighting - Pod/container selectors (
p/c) to narrow the stream - Time range (
t) -- e.g.30m,2h,1d - Line selection with
j/k, multi-select withShift+j/Shift+k, copy withY
Port Forwarding
- Create (
F) from Services, Deployments, StatefulSets, DaemonSets, ReplicaSets, Pods, Jobs, CronJobs - Survives pod restarts -- resolves the current pod per-connection via label selectors
- Persistent -- saved to your active profile and restored on next launch
- Manage -- dedicated sidebar view to pause (
p), resume, cancel (d), edit local port (e)
Favorites and Profiles
- Star (
*) any resource from list or detail view - Favorites view in the sidebar -- fully functional (edit, logs, delete, etc.)
- Profiles -- named groups of favorites and port forwards;
Ctrl+sto save,Pto switch - Missing indicators --
⚠for favorites from unreachable clusters
Command Palette
Ctrl+pto open- Type to fuzzy-search resources across all types in the cluster
- Prefix with
>to search available commands - Context-aware help with
?(pressTabto see all keybindings)
Exec (Experimental)
Xto exec into a pod (requiresqb -eflag)- Choose container, command, and terminal application in a dialog
- Opens a new terminal window with
kubectl exec -it - Supports Ghostty, iTerm2, Alacritty, kitty, WezTerm, Terminal.app, and others via
$TERMINALor$TERM_PROGRAM
Installation
From source
Requires Rust (edition 2021).
# Binary at target/release/qb
Usage
At runtime, press c to switch cluster context, n to switch namespace, or O to open a different kubeconfig file.
Key Bindings
Global
| Key | Action |
|---|---|
Ctrl+c |
Force quit |
q |
Quit / go back |
Esc |
Dismiss popup or selection |
? |
Help (context-aware; Tab for all) |
Ctrl+p |
Command palette |
Ctrl+s |
Save profile |
P |
Load/switch profile |
p |
Pause/resume auto-refresh |
Main View
| Key | Action |
|---|---|
j/k |
Move down/up |
Ctrl+d/Ctrl+u |
Page down/up |
g/G |
Top/bottom |
Enter |
Open detail / focus table |
Tab |
Toggle sidebar/table focus |
</> |
Resize sidebar |
c |
Switch cluster |
n |
Switch namespace |
O |
Open kubeconfig |
/ |
Filter by regex |
x |
Clear filter |
e |
Edit resource |
l |
Logs |
D |
Delete |
R |
Restart |
S |
Scale |
F |
Port forward |
C |
Create resource |
d |
Mark/diff |
y |
Copy name |
* |
Toggle favorite |
X |
Exec (experimental) |
Detail View
| Key | Action |
|---|---|
v |
Toggle Smart/YAML |
w |
Toggle watch (auto-refresh) |
l/a |
Select labels/annotations |
Space |
Expand value / decode secret |
y |
Copy value or YAML |
r |
Related resources |
e |
Edit |
L |
Logs |
D |
Delete |
Log View
| Key | Action |
|---|---|
f |
Toggle follow |
/ |
Filter by regex |
p/c |
Select pod/container |
t |
Time range |
w |
Toggle wrapping |
Y |
Copy to clipboard |
J/K |
Extend selection |
Edit Diff View
| Key | Action |
|---|---|
v |
Toggle inline/side-by-side |
Enter |
Apply changes |
e |
Re-edit |
Esc |
Cancel |
Port Forwards View
| Key | Action |
|---|---|
p |
Pause/resume |
d |
Cancel forward |
e |
Edit local port |
How It Works
qb uses the kube crate with rustls for direct communication with the Kubernetes API server. Authentication and cluster details come from your kubeconfig (~/.kube/config or $KUBECONFIG). There is no dependency on kubectl for any operation except exec (which spawns kubectl exec in a new terminal window).
The TUI is built on ratatui + crossterm. All API calls are deferred and executed between render frames so the UI never blocks. Log streaming and port forwarding run as background async tasks with channel-based updates polled each tick.
Custom Resource support works by discovering all CRDs at startup and using the kube dynamic API (DynamicObject + ApiResource) to list, inspect, edit, and delete CR instances without compile-time type information. CRD additionalPrinterColumns are used to render table columns.
Configuration (favorites, port forwards, profiles) is persisted to ~/.config/qb/config.yaml and auto-saved on changes.
License
MIT