Self-hosted service
janosmiko/lfk avatar
janosmiko/lfk

LFK: a keyboard driven Kubernetes browser for the terminal

⚡ LFK is a lightning-fast, keyboard-focused, yazi-inspired terminal user interface for navigating and managing Kubernetes clusters. Built for speed and efficiency, it brings a three-column Miller columns layout with an owner-based resource hierarchy to your terminal.

919 stars37 forksGoApache-2.0

At a glance

What is it?
LFK is a Go terminal user interface for Kubernetes that borrows the Miller columns layout and keyboard flow of the yazi file manager, grouping resources by owner so a namespace view reads like a directory tree. It reads the same kubeconfig files as kubectl, shells out to kubectl, helm and trivy, and ships a built-in fake cluster so you can try it without one.
Who is it for?
Adopt LFK if you spend your day in a terminal and want to browse and act on cluster resources with keyboard navigation instead of remembering kubectl incantations, since the owner based grouping and the yazi style flow are the reason it exists. Do not adopt it as a replacement for kubectl in scripts, since it is an interactive tool that depends on kubectl being present and configured.
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 last received commits 1 day ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Miller columns instead of kubectl output

kubectl prints a table and asks you to remember flags. LFK takes the opposite approach and gives you a full screen interface where the cluster is a tree of panes you move through.

The layout is a three-column Miller columns arrangement, the same pattern used by file managers, and the project describes itself as keyboard-focused and yazi-inspired. The metaphor is literal enough to be useful: the middle column holds the thing you have selected, the left column holds its context, and the right column holds what is inside it.

What makes that work for Kubernetes rather than for files is the second half of the description, an owner-based resource hierarchy. Resources are grouped by the object that owns them, so a namespace expands into the workloads inside it, a workload expands into its pods, and a pod expands into its containers and volumes. The result is that moving right in a column moves down a causal chain rather than into an unrelated list.

The tool is written in Go and built on the Charm libraries, with charm.land/bubbletea/v2 and charm.land/bubbles/v2 for the terminal interface and charm.land/lipgloss/v2 for styling. That is the same family that powers most modern terminal applications, which is why the screenshots show a themed interface rather than a text dump.

The same kubeconfig files kubectl uses

Authentication is not reinvented. LFK uses ~/.kube/config and the ~/.kube/config.d/* directory, which is the standard layout, so a cluster you can reach with kubectl is a cluster LFK can reach.

You can also point it at specific contexts, namespaces and config files when you have several.

bash
# Start in a specific context / namespace
lfk --context my-cluster -n kube-system

# Use a specific kubeconfig
lfk --kubeconfig /path/to/kubeconfig
KUBECONFIG=/path/to/config1:/path/to/config2 lfk

# Use a custom directory for kubeconfigs (repeat the flag for multiple)
lfk --kubeconfig-dir /path/to/configs/
lfk --kubeconfig-dir /team-a/configs --kubeconfig-dir /team-b/configs
KUBECONFIG_DIR=/path/to/configs/ lfk
KUBECONFIG_DIR=/team-a/configs:/team-b/configs lfk

Note that both KUBECONFIG and KUBECONFIG_DIR accept multiple entries, and that the flag for a config directory can be repeated. Teams that keep separate kubeconfig directories per team or per environment are the audience for that, and it avoids the pattern of editing one file in place before every context switch.

One dependency is stated plainly and is not optional: kubectl is required and must be configured. helm and trivy are optional, and they enable the Helm management and the image vulnerability scanning features respectively. That dependency on external binaries is a deliberate design decision, and it has consequences in restricted environments where a compiled-in client would have been simpler.

Install paths from Homebrew to go install

The install section lists a package manager for every platform that matters, which is a sign of how much attention goes to distribution.

bash
# Homebrew (macOS / Linux)
brew install janosmiko/tap/lfk

# Scoop (Windows)
scoop bucket add janosmiko https://github.com/janosmiko/scoop-bucket && scoop install lfk

# Winget (Windows)
winget install janosmiko.lfk

# Chocolatey (Windows)
choco install lfk

# AUR (Arch)
yay -S lfk-bin

# APT (Debian / Ubuntu)
curl -1sLf 'https://dl.cloudsmith.io/public/janosmiko/lfk/setup.deb.sh' | sudo -E bash && sudo apt update && sudo apt install lfk

# DNF (Fedora / RHEL)
curl -1sLf 'https://dl.cloudsmith.io/public/janosmiko/lfk/setup.rpm.sh' | sudo -E bash && sudo dnf install lfk

# Go
go install github.com/janosmiko/lfk@latest

# Nix
nix run github:janosmiko/lfk

The Debian and Fedora lines pipe a Cloudsmith setup script into bash, so if you are wary of that pattern, the Go install is the one to use, and it needs only a Go toolchain.

The documentation set also covers Docker, NixOS and home-manager, binary releases and building from source, and the installation page lists the optional command line dependencies in full.

After installing, you run the binary with no arguments, or with a demo flag that runs against a built-in fake cluster so that no kubeconfig is needed at all.

bash
lfk
lfk --demo

That demo mode is the fastest way to evaluate the interface, and it also means you can learn the keybindings without touching a production cluster.

What the panes actually show

The feature list is broader than a resource browser, and it is organised by what kind of work the pane supports.

Exploration is the core: pods with a fullscreen view and an action menu, a cluster dashboard, an object explorer and an API explorer. The API explorer is the piece that stands out, since it means you can inspect the raw Kubernetes API from inside the interface rather than falling back to a kubectl get with an output format flag.

Viewers cover the two things you read most: a YAML viewer for rendered manifests and a log viewer with a log top mode for looking at the beginning of a crashing container rather than scrolling for it.

Integrations cover the two tools it shells out to. Helm integration gives you release management inside the interface, and there is an ArgoCD integration with a configuration view for ArgoCD auto-sync.

Analysis is where the tool starts to be more than a browser. There is a security dashboard built on built-in security heuristics, a crash investigator, a pod startup analysis, and a can-I RBAC permissions browser that answers what a given service account is actually allowed to do.

The workspace features are the ones that decide whether you keep the tool open all day: a label and annotation editor, quick filters, column visibility and reordering, bookmarks, and multi-tab support.

Runtime tuning and the options that keep it out of your way

The usage documentation lists a set of runtime tuning options, and they are worth reading because they reveal what the author expects to irritate people.

Mouse capture can be turned off, for people running LFK over SSH into a machine where the mouse should still select text. A no-color mode exists for terminals with a bad palette. There is a read-only mode, which is the important one for a tool that can act on a cluster: it lets you browse and read without the ability to mutate anything.

There is a watch-mode interval, which controls how often the interface refreshes from the API server, and that is the setting that decides whether LFK feels fast or feels like it is hammering your cluster. A discovery cache is also listed, which suggests resource discovery results are cached rather than recomputed on every navigation, and Secret lazy loading means secrets are not fetched until something asks for their content.

That last one is a sensible default for a Kubernetes tool. Secrets are the resource you least want to pull across the wire unnecessarily, and lazy loading means the bulk listing does not include them.

A dedicated file, docs/usage.md, holds the full CLI reference with the command line flags and these tuning options, and the README links to it rather than duplicating it.

The container image and how the binary is built

The Dockerfile shows a two stage build with a pinned base image for each stage. The builder is golang 1.27.2 on alpine with a pinned digest, and it adds git, copies the module files, downloads the modules, then builds with CGO disabled.

The release metadata is injected through linker flags rather than baked into the source.

dockerfile
RUN CGO_ENABLED=0 go build -ldflags "\
    -s -w \
    -X github.com/janosmiko/lfk/internal/version.Version=${VERSION} \
    -X github.com/janosmiko/lfk/internal/version.GitCommit=${GIT_COMMIT} \
    -X github.com/janosmiko/lfk/internal/version.BuildDate=${BUILD_DATE}" \
    -o /lfk .

The runtime stage is alpine 3.24 by digest, and it installs ca-certificates, helm and kubectl, which confirms the external binary dependency is deliberate and that the container bundles kubectl for you. A non-root user and group are created, the binary is copied to /usr/local/bin/lfk, the terminal environment is set to xterm-256color with truecolor, and there is a volume declared at /home/lfk/.kube as the default kubeconfig mount point.

dockerfile
VOLUME ["/home/lfk/.kube"]

ENTRYPOINT ["lfk"]

Running the container therefore means mounting your kubeconfig into that path, and because the process is not root, the mounted file needs to be readable by the lfk user.

The go.mod file declares go 1.27.1 with a go1.27.2 toolchain directive, and depends on the Kubernetes client libraries at k8s.io/api, k8s.io/apimachinery and k8s.io/client-go v0.37.1, plus cobra for the CLI, gopacket for packet work, and testify for tests.

Project state, licence and the funding question

The release cadence is fast. The listed versions are v0.19.8 from 2026-10-18, v0.19.7 from 2026-10-17 and v0.19.6 from 2026-10-16, and the last push was on 2026-10-20. The repository is not archived. Releases are managed with release-please and there is a .release-please-manifest.json alongside a CHANGELOG.md, so version bumps are automated from commit history.

The version numbers themselves are a signal. This is a 0.x project, so the API and the interface can still change between releases, and if you script against its output you should pin a version.

The licence is Apache-2.0, and the project says it stays free. The funding section is unusually direct about the economics: the author builds it in free time, the tools needed to build it are not free, sponsorship pays for IDE licences and AI assistants, and the request is that teams using LFK at work sponsor it. Package hosting is provided by Cloudsmith.

For a Kubernetes tool the security question is the one to ask first, and the project carries a SECURITY.md file and a SonarCloud integration for its security rating and vulnerability tracking, along with an OpenSSF Scorecard badge and a best practices badge. There is also a TESTS.md file and an e2e/ directory in the tree, plus a Makefile with e2e, coverage and fuzz targets, which tells you the project tests itself seriously even though it is young.

Editorial conclusion

Adopt LFK if you spend your day in a terminal and want to browse and act on cluster resources with keyboard navigation instead of remembering kubectl incantations, since the owner based grouping and the yazi style flow are the reason it exists. Do not adopt it as a replacement for kubectl in scripts, since it is an interactive tool that depends on kubectl being present and configured. Verify first that your clusters are reachable through the kubeconfig paths it reads, that kubectl is installed on the machine, that helm and trivy are installed if you want those integrations, and that the Go toolchain matches the go 1.27.1 directive with the go1.27.2 toolchain if you build from source.

Frequently asked questions

How do I install LFK on Linux?

On Debian or Ubuntu use the Cloudsmith setup script followed by apt install lfk, on Fedora or RHEL use the rpm setup script with dnf install lfk, on Arch use yay -S lfk-bin, and everywhere else go install github.com/janosmiko/lfk@latest or nix run github:janosmiko/lfk. Homebrew covers macOS and Linux.

Can I try LFK without a Kubernetes cluster?

Yes, running lfk --demo starts it against a built-in fake cluster, so no kubeconfig is needed. That makes it a way to learn the keybindings and the three column layout before pointing it at anything real.

What does LFK need beyond kubectl?

kubectl is required and must be configured. helm and trivy are optional and enable the Helm management and image vulnerability scanning features. The container image installs ca-certificates, helm and kubectl for you.

How does LFK read cluster credentials?

It uses ~/.kube/config and the ~/.kube/config.d/* directory, and accepts --context, --namespace, --kubeconfig, --kubeconfig-dir and the KUBECONFIG and KUBECONFIG_DIR environment variables, all of which accept multiple entries.

Official sources

  1. Issues
  2. janosmiko/lfk on GitHub
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/janosmiko-lfk.svg)](https://hysenlabs.com/projects/janosmiko-lfk)

Was this useful?