A tour of Helm 4
What Helm is, how a release differs from a chart, and the install, list, status and uninstall cycle on a public OCI chart, plus what changed from Helm 3 to Helm 4.
Before writing a chart of your own, use somebody else’s. This chapter installs podinfo, a small public web application, straight from an OCI registry, follows the release through its whole lifecycle, and ends with a table of what Helm 4 changed. The new idea is the separation of three things: a chart, a release, and the cluster state that proves the release exists.
The code is in examples/02-helm-tour/. ./demo.sh offline renders the chart without a cluster; ./demo.sh installs it into hfd-02. Chapter 01 builds the lab this chapter runs on.
What Helm is
Helm is a package manager for Kubernetes with three nouns.
- A chart is a versioned package:
Chart.yamlmetadata, defaultvalues.yaml, and atemplates/directory of Go templates that render to Kubernetes manifests. - A release is one installation of a chart into one namespace under a name you choose. The same chart installed twice with different names is two releases.
- A repository or registry stores charts. Classic repositories serve an
index.yamlover HTTP; OCI registries store a chart as an artifact. This chapter uses OCI; chapters 19 and 20 cover both in depth.
Helm itself is only a command-line client. Nothing runs in the cluster on its behalf. When you run helm install, the client pulls the chart, merges values, renders the templates locally, sends the objects to the API server, and records the outcome as a release record. By default that record is a Secret named sh.helm.release.v1.<release>.v<revision> in the release namespace, which is why helm list works from any machine with cluster access. Chapter 04 opens one up.
The chart you will install
oci://ghcr.io/stefanprodan/charts/podinfo is published by the podinfo maintainer and needs no login. The lab pins version 6.15.0, the latest at the time of writing (2026-10-08). Always pass --version: without it Helm takes the newest tag, and your output stops matching this page the day a new release lands.
The chart is a v1 chart (apiVersion: v1 in its Chart.yaml). Helm 4 installs it unchanged, and the Helm 4 overview states that v2 charts continue to work unchanged while a v3 chart API is experimental. Your own charts in the chapters that follow use apiVersion: v2.
How the code works
The demo is one script and one values file.
values-tour.yaml
replicaCount: 2
ui:
message: "Helm for Developers, chapter 02"
Values layer on top of the chart’s values.yaml. Anything you do not set keeps the chart default, so these two keys are the only thing recorded as “your” values; helm get values later prints exactly them. Two replicas make the rollout visibly more than one pod. The ui.message key proves a value reaches a rendered template. Chapter 05 covers precedence rules for the real services.
demo.sh offline
[host]$ helm show chart oci://ghcr.io/stefanprodan/charts/podinfo --version 6.15.0
[host]$ helm template podinfo oci://ghcr.io/stefanprodan/charts/podinfo --version 6.15.0 -n hfd-02 -f values-tour.yaml
helm show chart prints Chart.yaml and fails the demo unless version: 6.15.0 is present. helm show values prints the defaults you may override; run it before writing any values file. helm template renders locally with no cluster connection, so the demo checks replicas: 2 appears in the output. It then pipes the manifests through kubeconform -strict, which validates each object against the Kubernetes schemas. A run found five resources and all valid: one Service, one Deployment and three Pods. The Pods are the chart’s test hooks, which helm test runs on demand.
demo.sh (full run)
[host]$ helm install podinfo oci://ghcr.io/stefanprodan/charts/podinfo --version 6.15.0 --kube-context helm4dev -n hfd-02 --create-namespace -f values-tour.yaml --wait --rollback-on-failure --timeout 3m
Each flag has a job.
podinfois the release name. Charts derive object names from it; because the release name already contains the chart name, podinfo’s naming helper does not repeat it, and the Deployment is namedpodinfo(a release namedpodwould givepod-podinfo). Chapter 07 writes that helper.--kube-context helm4devpins the cluster. The lab pins it on every command so a stale current context cannot send an install to the wrong cluster.-n hfd-02 --create-namespacescopes the release and creates the namespace if absent.--waitmakes Helm block until the resources are ready. In Helm 4 the wait is driven by a kstatus-based watcher;helm install --helplists three strategies,watcher,hookOnlyandlegacy, and--waitalone selectswatcher.--rollback-on-failureis the Helm 4 name for what Helm 3 called--atomic. A failed install is removed instead of left in afailedstate.--timeout 3mbounds the wait.
After the install the script runs helm list, helm status, kubectl get secret -l owner=helm and helm get values, then probes the application with podcli check http localhost:9898/healthz inside the pod, and finishes with helm uninstall --wait. The probe uses the in-pod podcli binary so the chapter needs no host access. ./demo.sh clean runs helm uninstall --ignore-not-found and deletes the namespace.
Server-side apply is the other change visible here. For a new release Helm 4 now applies objects with server-side apply by default; helm install --help shows --server-side defaulting to true.
Build, run, observe
[host]$ cd examples/02-helm-tour && ./demo.sh offline
Then, with the lab from chapter 01 running:
[host]$ ./demo.sh
Expect helm list to show podinfo in hfd-02 with status deployed and chart podinfo-6.15.0. helm status podinfo prints the revision, the last deployed time and any NOTES. kubectl get secret -l owner=helm shows one release record. After helm uninstall, helm list returns an empty table and the Secret is gone.
Cross-check
Compare what Helm says with what Kubernetes says. helm get manifest podinfo -n hfd-02 prints the rendered objects Helm stored; kubectl -n hfd-02 get deploy podinfo -o yaml shows the live object, which should contain replicas: 2 and the same image ghcr.io/stefanprodan/podinfo:6.15.0. The two differ in server-populated fields such as status and managedFields, and agree on everything you set.
Helm 3 to Helm 4 at a glance
Changed behavior cites official sources. The full migration reference is chapter 28.
| Area | Helm 3 | Helm 4 | Source |
|---|---|---|---|
| Rollback on failure | --atomic |
--rollback-on-failure; the old flag remains and warns that it is deprecated |
Overview |
| Replace on conflict | --force |
--force-replace; the old flag remains and warns |
Overview |
| Apply method | Client-side three-way merge | Server-side apply for new releases; upgrades follow the release’s previous method | Overview |
| Waiting | Legacy readiness polling | kstatus-based watcher; --wait takes watcher, hookOnly or legacy |
helm install |
| Plugins | One subprocess model | New plugin system with an optional Wasm runtime; CLI, getter and post-renderer types | Overview, HIP-0026 |
| Post-renderers | Any executable path | Plugin name only | Overview |
| Registry login | Accepted a URL | Domain name only | Overview |
| OCI install | By tag | Also by digest, oci://...@sha256:... |
Overview |
| Values | One YAML document per file | Multi-document values files | Overview |
| Chart caching | Archive cache | Content-based local cache | Overview |
| Chart API | v2 |
v2 unchanged; experimental v3 behind HELM_EXPERIMENTAL_CHART_V3 |
Overview |
| Logging | Not slog based |
slog |
Release post |
Helm 3 receives bug fixes until July 8th 2026 and security fixes until November 11th 2026, per the release post.
What you learned
- A chart is a package, a release is one named installation of it, and the release record lives in the cluster as a Secret, so Helm itself needs no server.
- An install with a pinned
--version,--waitand--rollback-on-failureis the baseline command later chapters extend. helm show chart,show valuesandtemplateinspect a chart before anything touches a cluster.- Helm 4 renamed
--atomicand--force, defaults to server-side apply for new releases, and rebuilt plugins and post-renderers.
Chapter 03 returns to the shipping service and deploys it as raw manifests, so the problem a chart solves is concrete.
Further reading
- Matt Butcher, Matt Farina, Josh Dolitsky, Learning Helm (O’Reilly, 2021), ISBN 9781492083641. Used here for: package-manager concepts, charts, releases and repositories.
- Helm project, Helm 4 overview and Helm 4 released: the changes in the table above.
- Helm project, Using Helm: the install, list and uninstall workflow.
Verification status: verified on 2026-10-08, evidence _plans/evidence/02-helm-tour.txt. The install reached deployed with two ready pods, the sh.helm.release.v1.podinfo.v1 Secret existed and was gone after uninstall, podcli check http returned 200 in-pod, and helm get manifest matched the live Deployment (2 replicas, image ghcr.io/stefanprodan/podinfo:6.15.0). Re-run on r1.1 on 2026-10-08 on the recreated helm4dev profile; this chapter makes no host requests, so only the cluster changed, and the behaviour above held.