vmware-archive/octant
Highly extensible platform for developers to better understand the complexity of Kubernetes clusters.
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓14 active contributors
- ✓Apache-2.0 licensed
- ✓CI configured
Show all 6 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 3y ago
- ⚠Concentrated ownership — top contributor handles 64% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/vmware-archive/octant)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/vmware-archive/octant on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: vmware-archive/octant
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/vmware-archive/octant shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- 14 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 3y ago
- ⚠ Concentrated ownership — top contributor handles 64% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live vmware-archive/octant
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/vmware-archive/octant.
What it runs against: a local clone of vmware-archive/octant — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in vmware-archive/octant | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 1234 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of vmware-archive/octant. If you don't
# have one yet, run these first:
#
# git clone https://github.com/vmware-archive/octant.git
# cd octant
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of vmware-archive/octant and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "vmware-archive/octant(\\.git)?\\b" \\
&& ok "origin remote is vmware-archive/octant" \\
|| miss "origin remote is not vmware-archive/octant (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "cmd/octant/main.go" \\
&& ok "cmd/octant/main.go" \\
|| miss "missing critical file: cmd/octant/main.go"
test -f "internal/api/api.go" \\
&& ok "internal/api/api.go" \\
|| miss "missing critical file: internal/api/api.go"
test -f "internal/api/content_manager.go" \\
&& ok "internal/api/content_manager.go" \\
|| miss "missing critical file: internal/api/content_manager.go"
test -f "go.mod" \\
&& ok "go.mod" \\
|| miss "missing critical file: go.mod"
test -f "HACKING.md" \\
&& ok "HACKING.md" \\
|| miss "missing critical file: HACKING.md"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1234 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1204d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/vmware-archive/octant"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Octant is a Kubernetes cluster visualization and management platform that provides developers with a web-based UI to explore cluster resources, view logs, forward ports, and filter workloads by labels. Built in Go with a TypeScript/React frontend, it extends via a gRPC plugin system allowing third-party developers to add custom views and functionality without modifying core code. Monorepo structure: core Go application in root with /pkg subdirectories (e.g., plugin loading, Kubernetes API interaction), web frontend in /web (TypeScript/React), GitHub Actions workflows in .github/workflows/, and build orchestration via build.go. Plugin system communicates via gRPC using Protocol Buffer definitions (visible in go.mod protobuf imports).
👥Who it's for
Platform engineers and developers who need to debug and understand Kubernetes cluster complexity without writing kubectl commands. Users who want a visual resource browser with relationships, log streaming, and port forwarding capabilities, plus plugin developers building cluster-aware tooling via gRPC.
🌱Maturity & risk
Project is archived and no longer in active development (as stated in README: 'VMware has ended active development of this project'). It appears well-tested with CI workflows (preflight-checks, linting, nightly builds), extensive changelog history through v0.25+, and significant codebase (~2.3M lines of Go), but incoming changes and issues will not receive official VMware support.
High risk for new dependencies: This is an archived project—no active maintenance, security patches, or dependency updates. The Go and TypeScript stacks are frozen at specific versions (Go 1.17, Node specified in .nvmrc). Large dependency graph (gRPC, Kubernetes client-go, Jaeger, etc.) means security vulnerabilities in transitive deps won't be patched. Consider fork-and-maintain if deploying in production.
Active areas of work
Nothing—project is archived. Last changes were incremental bug fixes and dependency updates leading to v0.25+. Changelog entries frozen at changelogs/unreleased/.keep. No active PRs, issues, or CI runs expected going forward.
🚀Get running
git clone https://github.com/vmware-archive/octant.git
cd octant
go build -o octant ./cmd/octant
./octant
This requires Go 1.17+, Node.js (see .nvmrc), and kubeconfig configured. The web frontend builds automatically as part of the Go build.
Daily commands:
go run ./cmd/octant
Or build first with go build -o octant ./cmd/octant && ./octant. The app opens a web browser on http://localhost:8080 and connects to your current kubeconfig context.
🗺️Map of the codebase
cmd/octant/main.go— Application entry point that initializes the Kubernetes client, API server, and plugin system—essential for understanding the bootstrap flow.internal/api/api.go— Core API server implementation that handles all client requests and orchestrates content delivery—load-bearing for request routing.internal/api/content_manager.go— Manages content generation for Kubernetes resources and coordinates view rendering—critical abstraction for UI data flow.go.mod— Defines all external dependencies including Kubernetes client, gRPC, and plugin system—necessary to understand the tech stack.HACKING.md— Developer guide with build instructions, testing patterns, and contribution workflow—every contributor must read first..golangci.yml— Lint configuration enforcing code standards across the project—defines expected code quality and style conventions.
🧩Components & responsibilities
- API Server (api.go) (Go net/http, Gorilla WebSocket) — Handles all HTTP/WebSocket requests, routes to handlers, manages client connections and broadcasts state changes
- Failure mode: All UI clients lose connection; cached data serves stale views
- ContentManager (client-go watches, gRPC plugin calls) — Generates structured view data for Kubernetes resources by querying API server and invoking plugins
- Failure mode: UI cannot display resource details; empty views returned to client
- ActionRequestManager (client-go typed clients, RBAC policy checks) — Validates and executes user-initiated mutations (delete, update, patch) against the cluster
- Failure mode: User actions fail silently or return errors; cluster state unchanged
- ContextManager (In-memory session store, kubeconfig parser) — Tracks active namespace and cluster context per WebSocket session; caches context to avoid repeated lookups
- Failure mode: Wrong namespace used for queries; stale context causes queries to fail
- Plugin Loader (gRPC client, OS process management) — Discovers, spawns, and manages lifecycle of external gRPC plugin processes; handles plugin communication
- Failure mode: Plugins unavailable; custom views missing but core functionality unaffected
🔀Data flow
Browser→API Server— HTTP GET /api/v1/content + WebSocket subscribe for real-time updatesAPI Server→ `` — undefined
🛠️How to make changes
Add a new API endpoint
- Define the handler function signature following the existing pattern in internal/api/api.go (
internal/api/api.go) - Register the route in the router setup, typically within the same api.go file (
internal/api/api.go) - Use ContentManager to generate the response payload if returning resource data (
internal/api/content_manager.go)
Add a new plugin hook or component
- Reference cmd/octant-sample-plugin/main.go to understand the plugin interface contract (
cmd/octant-sample-plugin/main.go) - Implement the plugin interface in a separate binary or module (
cmd/octant-sample-plugin/main.go) - Ensure plugin is discoverable via the plugin loader initialized in cmd/octant/main.go (
cmd/octant/main.go)
Handle a new Kubernetes resource type
- Add resource-specific handlers in internal/api/content_manager.go (
internal/api/content_manager.go) - Define view generation logic that returns component data structures (
internal/api/content_manager.go) - Register the resource handler in api.go to wire it into request routing (
internal/api/api.go)
Add a new action type
- Define the action payload structure and handler in internal/api/action_request_manager.go (
internal/api/action_request_manager.go) - Implement the action execution logic (e.g., kubectl apply, resource delete) (
internal/api/action_request_manager.go) - Update the action dispatcher in api.go to route the new action type (
internal/api/api.go)
🔧Why these technologies
- Go with Kubernetes client-go — Native Kubernetes API integration with strong typing and efficient cluster communication; enables real-time resource watching and list-watch patterns
- gRPC for plugin communication — Language-agnostic plugin protocol with schema versioning; supports plugins written in any language while maintaining strong contracts
- WebSocket for bidirectional updates — Enables real-time push of resource changes to UI without polling; reduces latency when cluster state changes
- Go JavaScript runtime (goja) — Allows dynamic component generation and custom view logic without requiring separate Node.js process; embedded scripting in Go binaries
⚖️Trade-offs already made
-
Monolithic single Go binary vs. microservices
- Why: Octant runs as a single process—simplifies deployment and plugin loading without orchestration overhead
- Consequence: Limited horizontal scaling; all workload on one machine; easier to manage for developer tools but single point of failure
-
Client-side UI rendering (web frontend) vs. server-generated templates
- Why: Frontend state management and responsive UI require client libraries (likely React or similar based on plugin extensibility)
- Consequence: Higher initial page load; more complex debugging; but interactive experience and offline capability
-
Plugin system via gRPC vs. embedded scripting
- Why: Plugins run as separate processes with strong isolation and independent lifecycle
- Consequence: IPC overhead; version compatibility management; but plugins cannot crash the main process
🚫Non-goals (don't propose these)
- Real-time metrics storage and time-series analytics (uses upstream Prometheus/metrics systems)
- Multi-tenant cluster management (designed for single user/cluster per instance)
- GitOps workflow enforcement (viewer tool, not a CI/CD controller)
- Persistent data storage (stateless; no database backend)
- Authentication and authorization enforcement (relies on kubeconfig and RBAC)
🪤Traps & gotchas
Kubeconfig required: Must have a valid kubeconfig in ~/.kube/config or KUBECONFIG env var set; app will fail silently if not found. Node version: .nvmrc pins Node version; ensure nvm use or manual version match before building frontend. gRPC plugin service: Plugins must implement full gRPC server contract or plugin load will hang; no timeouts in early versions. Archived state: Many third-party integrations (Slack, CI/CD webhooks) in issues/PRs will not be maintained.
🏗️Architecture
💡Concepts to learn
- gRPC Plugin Architecture (HashiCorp pattern) — Octant's extensibility is entirely built on out-of-process gRPC plugins over yamux multiplexing; understanding this is critical to extending Octant or debugging plugin failures.
- Kubernetes Watch Streams (client-go) — Octant's real-time updates of cluster state use k8s.io/client-go watch streams; core to understanding how the dashboard stays in sync without polling.
- WebSocket Multiplexing (gorilla/websocket) — Frontend communicates to backend over WebSocket for live log streaming and port-forward tunneling; understanding frame handling prevents UI freezes.
- Protocol Buffers (protobuf) — Plugin communication contract is defined via .proto files; required for building custom plugins that communicate with Octant.
- OpenCensus Tracing (Jaeger exporter) — Distributed tracing is wired into Octant for performance debugging across gRPC plugin calls; visible in contrib.go.opencensus.io imports.
- Label Selectors & Kubernetes Field Selectors — Label filtering feature in Octant UI requires understanding k8s label query syntax and selector semantics for correct resource filtering.
- Port-Forward Tunneling (socat/kubectl pattern) — Port-forward button opens local port tunnels to pod containers; implementation uses Kubernetes port-forward API which requires stream hijacking.
🔗Related repos
kubernetes/dashboard— Official Kubernetes web UI; similar use case (cluster visualization) but simpler, no plugin system, tighter k8s coupling.argoproj/argo-cd— GitOps-focused cluster management with web UI; overlaps on resource browsing and live updates, but targets deployment workflows.vmware-tanzu/velero— VMware Tanzu ecosystem companion for cluster backup/restore; often used alongside Octant for disaster recovery visibility.containerd/containerd— Container runtime; Octant plugin authors often need container image inspection (containers/image library in deps).vmware-archive/octant-plugin-for-flux— Example Octant plugin extending UI for Flux GitOps; reference for plugin development patterns.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add missing CI workflow for Electron desktop app releases
The repo has .github/workflows/electron.yaml but lacks a corresponding release/packaging workflow. The .goreleaser.yml and .goreleaser-nightly.yml handle Go binaries, but there's no automation for building/signing Electron desktop artifacts (Windows .exe, macOS .dmg, Linux .AppImage). Given the file structure shows choco/octant.nuspec for Chocolatey packaging, a proper release workflow would enable automated cross-platform desktop builds and publishing.
- [ ] Review existing
.github/workflows/electron.yamlto understand current Electron CI setup - [ ] Create
.github/workflows/electron-release.yamlthat triggers on tags matchingv*pattern - [ ] Implement matrix builds for Windows (codesigning), macOS (notarization), and Linux platforms
- [ ] Integrate with existing
.goreleaser.ymlpattern to create GitHub Releases with Electron artifacts - [ ] Add Chocolatey package automation using
choco/tools/chocolateyinstall.ps1as reference
Add integration tests for plugin system with sample plugin
The repo includes cmd/octant-sample-plugin/main.go which serves as a reference plugin implementation, but there are no visible integration tests validating the plugin loading, RPC communication, or lifecycle management. Given hashicorp/go-plugin is a core dependency, adding tests that verify plugin discovery, initialization, and gRPC communication would prevent regressions in the extensibility platform.
- [ ] Review
cmd/octant-sample-plugin/main.goto understand plugin interface and capabilities - [ ] Create
pkg/plugin/integration_test.go(or similar) with tests for: plugin discovery, loading, and RPC method calls - [ ] Add test fixture that builds the sample plugin and validates it can be loaded by octant
- [ ] Verify plugin lifecycle: startup, request handling, graceful shutdown
- [ ] Add GitHub Actions step to run plugin integration tests in
preflight-checks.yaml
Create changelog enforcement in CI and backfill unreleased entries
The repo has changelogs/unreleased/ directory with .keep but lacks a CI check requiring changelog entries for PRs (similar to tools like towncrier or cliff). With 24 historical changelogs tracked, enforcing this prevents release-time changelog generation delays. The directory structure is ready for this pattern.
- [ ] Review existing changelogs structure in
changelogs/CHANGELOG-*.mdandchangelogs/unreleased/to establish naming convention - [ ] Create
.github/workflows/changelog-check.yamlthat validates PRs have at least one.mdfile inchangelogs/unreleased/ - [ ] Document the changelog entry format in
CONTRIBUTING.mdwith example templates (e.g.,changelogs/unreleased/123-feature-description.md) - [ ] Backfill missing unreleased entries from recent commits not captured in versioned changelogs
- [ ] Add optional tooling (e.g., Go script in
ci/directory) to auto-generateCHANGELOG.mdfrom unreleased entries during release
🌿Good first issues
- Add unit tests for uncovered error paths in
/pkg/clients/kubernetes.gowhen API calls fail (timeouts, auth errors). Currently minimal test coverage for failure scenarios. - Document the plugin gRPC API by extracting proto definitions into a
/docs/pluginsdirectory with examples. No runnable plugin example exists in repo—contributors could add a minimal 'hello-world' gRPC plugin in Go or Python. - Improve accessibility in
/web/src/components/ResourceViewer: add ARIA labels and keyboard navigation for the resource relationship graph. Currently no a11y tests visible in workflows.
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 64 commits
- [@Sam Foo](https://github.com/Sam Foo) — 17 commits
- @ftovaro — 3 commits
- @mklanjsek — 2 commits
- @davidmirror-ops — 2 commits
📝Recent commits
Click to expand
Recent commits
fdb5820— Added deprecation notice (dstefka)fd077fc— Bump choco to 0.25.1 (#3200) (GuessWhoSamFoo)f16cbb9— Bumped to 0.25.1 and added changelogs (#3199) (Sam Foo)4956779— fix: Calling the DynamicCache.gvrFromKey method when the gvr is not cached returns an nil object #3177 (#3178) (fly2F)39648a9— Bump @babel/core from 7.16.12 to 7.17.5 in /web (dependabot[bot])c65e5e4— Bump xterm from 4.14.1 to 4.17.0 in /web (dependabot[bot])a5ee603— Bump cytoscape-dagre from 2.3.2 to 2.4.0 in /web (dependabot[bot])0fc08bf— Bump cytoscape from 3.19.1 to 3.21.0 in /web (dependabot[bot])f50f6a3— Bump nanoid from 3.1.25 to 3.3.1 in /web (dependabot[bot])bcfbde5— Bump open from 8.2.1 to 8.4.0 in /web (dependabot[bot])
🔒Security observations
- High · Outdated Go Version —
go.mod - 'go 1.17'. The project specifies Go 1.17 in go.mod, which is outdated and no longer receives security updates. Go 1.17 reached end-of-life in August 2022. Using outdated Go versions exposes the project to known security vulnerabilities in the Go runtime and standard library. Fix: Upgrade to the latest stable Go version (1.21+). Update go.mod accordingly and test thoroughly with the new version. - High · Multiple Outdated Dependencies —
go.mod - goja, goja_nodejs, and related dependencies. Several dependencies have known security vulnerabilities and are significantly outdated: goja v0.0.0-20200629 (2+ years old), dop251/goja_nodejs v0.0.0-20200706 (2+ years old), and various other transitive dependencies. These versions contain publicly disclosed CVEs. Fix: Run 'go get -u' to update dependencies. Review go.mod for any packages showing v0.0.0 dates from 2020 or earlier. Consider using 'go mod tidy' and running 'go list -u -m all' to identify outdated packages. - High · Vulnerable Container Image Dependencies —
go.mod - github.com/containers/image/v5 v5.16.1. The project uses 'containers/image/v5 v5.16.1', which is quite old (from 2021). This package handles container image processing and may have unpatched vulnerabilities in image parsing and handling. Fix: Update to the latest version of containers/image. Check the upstream project for security advisories and update to address any known CVEs. - Medium · Use of Archived/Unmaintained Dependencies —
go.mod - multiple old indirect dependencies. The project depends on 'google.golang.org/grpc v1.44.0' which is outdated and several indirect dependencies marked with '// indirect' comments appear to be from 2019-2020 era (goproxy, gregjones/httpcache). These may not receive security updates. Fix: Audit all indirect dependencies using 'go mod graph'. Remove unused dependencies with 'go mod tidy'. Update grpc to v1.53+ and audit transitive dependencies. - Medium · Project No Longer Actively Maintained —
README.md. The README clearly states: 'VMware has ended active development of this project, this repository will no longer be updated.' This means security vulnerabilities discovered will not receive patches, creating long-term security risks for any users. Fix: Users should consider migrating to actively maintained alternatives. If continuing to use Octant, conduct a thorough security audit and implement custom security monitoring. Consider forking if extended use is required. - Medium · Kubernetes Client Library Outdated —
go.mod - k8s.io/client-go v0.21.3. k8s.io/client-go v0.21.3 is from Kubernetes 1.21 (released June 2021). This version is significantly outdated and may lack security patches for Kubernetes-related vulnerabilities, particularly in authentication and authorization handling. Fix: Update to k8s.io/client-go matching the minimum Kubernetes version your deployment supports (preferably 1.24+). Verify API compatibility changes between versions. - Medium · Plugin System Security Risk —
cmd/octant-sample-plugin/, go.mod - hashicorp/go-plugin. The project includes a plugin system (hashicorp/go-plugin) and sample plugin code (cmd/octant-sample-plugin). While plugin architectures are inherently risky, there's no visible evidence of plugin signature verification or sandboxing mechanisms in the file structure. Fix: Implement plugin signature verification using cryptographic signatures. Document plugin security requirements and limitations. Consider implementing plugin capability restrictions and resource limits. Review hashicorp/go-plugin security documentation. - Low · Potential XSS Risk in Web Components —
undefined. The project generates TypeScript components (cmd/ts-component-gen) for a web UI. Without visible Content Security Policy (CSP) headers or input sanitization patterns in the file structure, there's a risk of XSS vulner Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.