The Problem

Engineers need real-time Kubernetes visibility without cluster-side agents, CRDs, or cloud dependencies. Traditional tools often require installation on the cluster, introduce latency, or depend on external services. This repo solves that by providing a local-first binary that queries the K8s API directly and streams updates to the browser via SSE, with zero cluster-side installation.

What This Does

Radar is a collection of 5 self-contained projects delivering a desktop and CLI tool for Kubernetes inspection. The web/ directory (277 files, 254 code files) contains the React + Tailwind frontend that renders topology, event timelines, and service traffic. The internal/ directory (135 files) provides the Go backend: server routing, K8s client wrappers, Helm management, and cloud connections. packages/ (250 files) and pkg/ (73 files) hold shared utilities and middleware. The cmd/desktop/ entry point (5 files) boots the Wails-based desktop app. A Helm chart under deploy/helm/radar/ enables in-cluster deployment for team access. The binary runs on the developer laptop, talks directly to the K8s API, and requires no agents or CRDs on the cluster.

How It Is Wired

Execution starts at cmd/desktop/main.go:28 (main), which reaches 262 functions and is called by nothing else in the repo. From there, internal/server/server.go defines the HTTP route setup (spaHandler, Start, StartWithReady) and is called from 34 other files. The server builds topology via internal/k8s/topology_adapter.go (28 functions, called from 43 files), which defines Pods, Services, Deployments, and DaemonSets providers. Resource counts flow through buildResourcesTopology (calling List x44, MatchesNamespaceFilter x55, GetGVR x28). Traffic topology is built by buildTrafficTopology (calling MatchesNamespaceFilter x21). The call graph shows writeJSON called from 122 places and writeError from 121 places, indicating widespread I/O patterns. The most connected module is packages/k8s-ui/src/components/resources/renderers/index (Ca 1, Ce 135, instability 0.99), meaning 135 downstream modules depend on it—a high-blast-radius hub. A circular dependency cycle exists through packages/k8s-ui/src/components/resources/resource-utils (Ca 51, Ce 10, instability 0.16), involving resource-utils-velero.ts and useLogBuffer.ts. Paths to external effects: main -> Load [os.ReadFile], Start -> initCachedTopology -> Build -> buildResourcesTopology [crypto via b.provider.Secrets], handleApplyResource -> ApplyResourceWithClient -> ApplyResource [network via client.Patch], and handleCAPIClusterConnect -> Secrets [crypto via a.cache.Secrets].

How To Use It

Setup:

# Quick install (from README)
curl -fsSL https://raw.githubusercontent.com/skyhook-io/radar/main/install.sh | bash && kubectl radar

Alternatively, install via Homebrew: brew install skyhook-io/tap/radar then run kubectl radar. For the desktop app: brew install --cask skyhook-io/tap/radar-desktop (macOS) or download from GitHub Releases.

Configuration: No cluster-side setup required. The binary reads the local kubeconfig to discover clusters (internal/k8s/client.go defines discoverKubeconfigs). Environment variables or flags are not required for basic operation.

Running it:

kubectl radar          # opens browser, starts SSE stream
# Or via desktop app binary
radar                  # CLI alternative

Real-World Use

An on-call engineer runs kubectl radar after a deployment incident. The topology view instantly shows which pods, services, and deployments are affected. They stream logs from a specific pod, exec into it, and forward ports—all from the browser UI. If a Helm release needs rollback, the integrated Helm manager lists releases and allows actions without leaving the app. For airgapped environments, the binary works offline after the initial kubeconfig fetch, making it suitable for classified or disconnected clusters.

Code Health & Issues

The static analysis identified the following measured findings:

  • [HIGH/cognitive_load] Oversized file x6: packages/k8s-ui/src/components/ui/drawer-components.tsx, packages/k8s-ui/src/components/resources/resource-utils.ts, web/src/api/client.ts (812 code lines each). Fix: Split into cohesive units by responsibility.
  • [HIGH/soundness] Import cycle member x12: resource-utils.ts, resource-utils-velero.ts, useLogBuffer.ts. Fix: Break the cycle by extracting shared types or inverting a dependency.
  • [HIGH/clarity] Hub module x10: drawer-components.tsx, resource-utils.ts, web/src/api/client.ts. 121 modules depend on these; churn here has high-blast-radius. Fix: Keep stable and small; move volatile logic out.
  • [HIGH/cognitive_load] Deep nesting x17: web/src/components/traffic/TrafficView.tsx, web/src/components/portforward/PortForwardManager.tsx, packages/k8s-ui/src/components/shared/ResourceActionsBar.tsx. Max indentation depth 9. Fix: Flatten with guard clauses; extract inner blocks.
  • [MEDIUM/cognitive_load] High branching density x15: resource-utils.ts, resource-utils-capi.ts, resource-utils-knative.ts (782 branch points over 1369 lines). Fix: Decompose decision logic; consider table/strategy dispatch.

SDLC observations: Tests present (51 files), CI present (GitHub Actions), Dockerfile present, license present, lockfile present. No committed secrets found.

The Bottom Line

This repo delivers a polished, local-first Kubernetes observability tool that hits the sweet spot between CLI raw power and UI usability. The Go backend is well-structured and the React frontend is functional, though the TypeScript side shows signs of rapid feature accumulation—oversized files, import cycles, and a high-instability hub module mean changes to resource-utils or drawer-components ripple widely. The code health gaps (pinned Action SHAs, image digests, dependency scanning) are standard for an active project and can be addressed with Dependabot. It’s a solid choice for teams wanting a zero-agent, single-binary Kubernetes view without cluster modifications; the desktop app and Helm in-cluster mode add useful flexibility.