Helm — Structure#
Layout pattern#
Standard Go Layout (cmd/internal/pkg) — Helm follows the canonical Go project layout with a single binary entry point under cmd/helm/, shared public API under pkg/, and implementation details under internal/. The distinction between pkg/ and internal/ is used meaningfully: pkg/ contains the library API that external callers or tools could import (action, chart, kube, storage, etc.), while internal/ holds utilities and sub-systems that are not part of the public surface.
A notable twist is the presence of versioned sub-packages (pkg/chart/v2/, pkg/release/v1/, internal/release/v2/, internal/chart/v3/) indicating active API evolution toward Helm v4, where older format versions are carried alongside the current ones for compatibility.
Directory map#
helm/
├── cmd/
│ └── helm/ # Single binary entry point (main package)
│ ├── helm.go # main() — delegates to pkg/cmd
│ └── helm_test.go
├── internal/ # Private implementation packages
│ ├── chart/
│ │ └── v3/ # Internal chart v3 utilities (lint/rules, util)
│ ├── cli/
│ │ └── output/ # Output formatting helpers
│ ├── copystructure/ # Deep-copy utility (vendored from mitchellh)
│ ├── fileutil/ # File system helpers
│ ├── gates/ # Feature gate internals
│ ├── logging/ # Structured logging setup (log/slog)
│ ├── monocular/ # Helm Hub / Monocular search client
│ ├── plugin/
│ │ ├── cache/ # Plugin download cache
│ │ ├── installer/ # Plugin install/uninstall logic
│ │ └── schema/ # Plugin manifest schema
│ ├── release/
│ │ └── v2/ # Internal release type v2 (in-progress migration)
│ ├── resolver/ # Chart dependency resolver
│ ├── statusreaders/ # Custom Kubernetes status readers
│ ├── sympath/ # Symlink-safe path walking
│ ├── test/
│ │ └── ensure/ # Test helper utilities
│ ├── third_party/ # Inlined third-party code (dep, k8s.io fragments)
│ ├── tlsutil/ # TLS configuration helpers
│ ├── urlutil/ # URL manipulation helpers
│ └── version/ # Version info (populated via ldflags)
├── pkg/ # Public library packages
│ ├── action/ # Core Helm actions (install, upgrade, rollback, …)
│ ├── chart/
│ │ ├── common/ # Shared chart utilities (util, testdata)
│ │ ├── loader/
│ │ │ └── archive/ # Chart loader (dir, archive, stream)
│ │ └── v2/ # Chart format v2 (lint/rules, util)
│ ├── cli/
│ │ ├── output/ # Output table/JSON/YAML formatting
│ │ └── values/ # --set / --values flag parsing
│ ├── cmd/ # Cobra command definitions (one file per subcommand)
│ │ ├── require/ # Argument validation helpers
│ │ └── search/ # Hub/repo search logic
│ ├── downloader/ # Chart dependency downloader
│ ├── engine/ # Go template rendering engine (sprig)
│ ├── gates/ # Public feature gate API
│ ├── getter/ # Chart repository HTTP/OCI/file getters
│ ├── helmpath/
│ │ └── xdg/ # XDG base directory spec for Helm data paths
│ ├── ignore/ # .helmignore parser
│ ├── kube/
│ │ └── fake/ # Fake Kubernetes client for testing
│ ├── postrenderer/ # Post-render hook interface + exec implementation
│ ├── provenance/ # PGP chart provenance / signing
│ ├── pusher/ # Chart pusher interface (OCI)
│ ├── registry/ # OCI registry client (push, pull, login)
│ ├── release/
│ │ ├── common/ # Shared release constants
│ │ ├── v1/ # Release format v1 (Helm v3 compatible)
│ │ └── (root) # Current release types + interfaces
│ ├── repo/
│ │ └── v1/ # Repository index format v1
│ ├── storage/
│ │ └── driver/ # Release backends: secrets, configmaps, memory, SQL
│ ├── strvals/ # --set value parser (key=value, JSON, file refs)
│ └── uploader/ # Chart uploader interface
├── scripts/ # Shell scripts: install helpers, release notes
└── testdata/ # Top-level golden/fixture filesEntry points#
| File | Binary | Purpose |
|---|---|---|
cmd/helm/helm.go | helm | Single CLI entry point. Sets kube.ManagedFieldsManager = "helm", calls pkg/cmd.NewRootCmd, then executes. All command logic lives in pkg/cmd/. |
There is exactly one binary. Helm is a pure CLI tool; no daemon, no server process.
Package organization#
Internal packages (internal/)#
| Package | Purpose |
|---|---|
internal/chart/v3/ | V3 chart lint rules and chart utilities not exposed publicly |
internal/cli/output/ | Terminal output formatting (tables, etc.) |
internal/copystructure/ | Inlined deep-copy implementation |
internal/fileutil/ | File system path helpers |
internal/gates/ | Feature flag implementation details |
internal/logging/ | log/slog setup and handler initialization |
internal/monocular/ | Client for the Monocular chart search API (Helm Hub) |
internal/plugin/ | Plugin lifecycle: discovery, caching, installation, schema validation |
internal/release/v2/ | Experimental next-generation release record schema |
internal/resolver/ | Chart dependency resolution algorithm |
internal/statusreaders/ | Custom Kubernetes object status readers (for wait/rollout status) |
internal/sympath/ | Symlink-aware filepath walking |
internal/test/ensure/ | Test setup helpers (tempdir creation, etc.) |
internal/third_party/ | Vendored-inline code from dep and k8s.io |
internal/tlsutil/ | TLS config construction from cert/key paths |
internal/urlutil/ | URL path joining and normalization |
internal/version/ | Build-time version string (set via -ldflags) |
Public packages (pkg/)#
| Package | Purpose |
|---|---|
pkg/action/ | Heaviest package. One type per Helm action (Install, Upgrade, Rollback, Uninstall, List, Status, …). These are the core programmatic API for embedding Helm. |
pkg/chart/ | Chart type definitions, loader (dir + tgz archive), v2 lint rules, utilities |
pkg/cli/ | EnvSettings (from env vars + flags), output formatting, --values/--set handling |
pkg/cmd/ | Cobra command tree for the helm CLI; one file per top-level command or subcommand group |
pkg/downloader/ | Downloads chart dependencies declared in Chart.yaml |
pkg/engine/ | Go text/template + sprig rendering engine for Kubernetes manifests |
pkg/gates/ | Public feature gate definitions and checks |
pkg/getter/ | Pluggable chart source backends (HTTP, OCI, local file) |
pkg/helmpath/ | XDG-compliant path resolution for Helm’s data/config/cache dirs |
pkg/ignore/ | .helmignore file parser (gitignore semantics) |
pkg/kube/ | Kubernetes client abstraction used by actions; fake/ package for tests |
pkg/postrenderer/ | Interface + exec-based implementation for post-render hooks |
pkg/provenance/ | PGP signing and verification of chart packages |
pkg/pusher/ | Interface for chart upload backends |
pkg/registry/ | OCI registry client (ORAS-based) for push/pull/login/logout |
pkg/release/ | Release record types (status, manifest, hooks, metadata), v1 compat format |
pkg/repo/ | Chart repository index (index.yaml) parsing and management |
pkg/storage/ | Release storage abstraction; driver/ has: secrets, configmaps, memory, SQL backends |
pkg/strvals/ | Parses --set value syntax into Go maps |
pkg/uploader/ | Interface for chart upload (symmetric to pusher) |
Layering#
The architecture follows a clean layered pattern:
cmd/helm (main) → pkg/cmd (Cobra commands) → pkg/action (business logic)
↓
pkg/engine pkg/kube pkg/storage pkg/chart
↓ ↓ ↓
internal/* (utilities, helpers, versioned internals)pkg/cmd owns CLI concerns only; it delegates all logic to pkg/action. pkg/action is the programmatic API — it knows about chart loading, Kubernetes operations, and release storage, but does not import pkg/cmd. This separation means Helm can be embedded as a library via pkg/action alone.
Build system#
- Build tool: GNU Make (
Makefileat repo root), delegating togo build - Cross-compilation: Uses
goxfor multi-platform cross-compilation (12+ OS/arch combos) - Key targets:
make build— buildsbin/helmfrom./cmd/helm; also runsgo mod tidymake install— copies binary to/usr/local/binmake test— unit tests with race detector; also runs style checksmake test-acceptance— robot-framework acceptance tests against a live clustermake build-cross— static cross-compiled binaries for all targetsmake dist— packages cross-compiled binaries into tarballs/zips for releasemake format— runsgoimports
- Version injection: Build metadata (version, git commit, tree state) injected via
-ldflagsintointernal/versionpackage - Docker: No Dockerfile in the repository. Helm is distributed as a static binary, not as a container image.
Notable structural decisions#
pkg/actionas the embeddable API: The most architecturally intentional choice is the clean separation ofpkg/cmd(CLI) frompkg/action(logic). Tools like Flux, Argo CD, and others embed Helm by importingpkg/actiondirectly. This is a deliberate public API contract, as noted in the package doc: “This is a library for calling top-level Helm actions.”Versioned sub-packages for schema evolution: The presence of
pkg/chart/v2/,pkg/release/v1/,internal/release/v2/,internal/chart/v3/reveals an active effort to carry multiple format versions simultaneously. This allows Helm v4 to read/write older formats while introducing new schemas — a pattern common in protocol-heavy tools.Storage driver abstraction:
pkg/storage/driver/contains four backends — Kubernetes Secrets, ConfigMaps, in-memory, and SQL (PostgreSQL). The SQL backend is a v4 addition. This is a clean strategy pattern: actions use astorage.Storagewrapper that is backend-agnostic.Plugin system inlined in
internal/plugin/: Plugin management (discovery, schema, caching, installation via git/OCI/tar) is entirely internal. The WASM plugin runtime (noted in overview) is wired in via dependencies but the entrypoint is through this internal package.cmd/helm/is minimal by design: The main package is only ~50 lines. It sets one global variable, constructs the root command, and runs it. All complexity is delegated intopkg/cmdandpkg/action, keeping the entry point trivially testable and swappable.