Helm Charts Demystified: What They Actually Do and When to Skip Them
A package manager for Kubernetes, minus the cargo-culting

Everybody installs things on Kubernetes the same way. You find the project, you scroll to the README, and there it is: helm repo add, helm install, done. Three commands and a workload appears, fully wired with services, config maps, secrets and a horizontal pod autoscaler you didn’t ask for. Helm has become the default, and like most defaults it’s reached for without much thought about what it actually is or whether you need it.
So let’s pull it apart. Helm is a templating engine with a release ledger bolted on. That’s the whole trick. Understanding those two halves tells you exactly when it earns its keep and when it’s a layer of indirection you’ll come to resent.
1 What a chart actually is
A chart is a directory of YAML templates plus a values.yaml file of defaults. When you run helm install, Helm reads your values, renders the templates into plain Kubernetes manifests, and applies them. There is no magic in the cluster — the API server only ever sees ordinary Deployments and Services. The magic is purely client-side string substitution.
A trimmed template looks like this:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-web
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
resources:
{{- toYaml .Values.resources | nindent 12 }}You override the defaults at install time, either with flags or your own values file:
helm install myapp ./mychart \
--set replicaCount=3 \
--values production-values.yamlThat {{ .Values.replicaCount }} is the entire value proposition. One chart, many environments, no copy-pasted manifests drifting out of sync.
2 The release ledger is the underrated bit
The templating gets the attention, but the release tracking is where Helm quietly earns its place. Every install creates a release — a named, versioned snapshot of what got applied — stored as a secret in the cluster. This gives you three genuinely useful things.
helm list # what's installed and which revision
helm upgrade myapp ./mychart # render again, diff, apply changes
helm rollback myapp 2 # go back to revision 2 if it all went wrong
helm uninstall myapp # delete everything the release createdThat last one matters more than it sounds. kubectl apply -f is happy to create resources but has no idea what belonged to what, so cleaning up is a manual scavenger hunt. Helm knows precisely which objects it owns and can remove them cleanly. The rollback is honest, too — it re-applies the previous manifests, so if your bad upgrade was a config change, you’re back in seconds.
3 When Helm is the right call
Helm shines when you’re consuming other people’s software. Installing ingress-nginx, cert-manager, Prometheus or a database operator via its official chart means someone has already done the tedious work of parameterising fifty resources sensibly. You set a handful of values and get a battle-tested deployment. Reinventing that by hand would be slow and worse.
It also shines when you genuinely run the same application across dev, staging and production with only values differing. One chart, three values files, and your environments stay structurally identical. That’s a real maintenance win.
4 When to skip it
If you’re deploying a single app you wrote, with a handful of manifests that rarely change, Helm is overhead. You’ve taken readable YAML and buried it under Go templating syntax that turns a missing space into a baffling render error. Debugging nindent alignment at 11pm is nobody’s idea of fun.
For that case, plain manifests with Kustomize are often the better fit. Kustomize patches a base with overlays using ordinary YAML — no templating language, no release secrets, and kubectl has it built in. You lose the rollback ledger, but you gain manifests you can read without rendering them first.
A useful habit, even when you do use Helm, is to render before you apply so you can see exactly what’s about to hit the cluster:
helm template myapp ./mychart --values production-values.yaml | lessNo surprises, no trusting the template blindly.
5 The honest verdict
Helm is worth learning, full stop — too much of the ecosystem ships as charts to avoid it. But it is a tool, not a religion. Use it to consume third-party software and to manage genuinely multi-environment apps, where its templating and rollback ledger pay for themselves. Reach for Kustomize or plain manifests when your needs are simpler than the abstraction.
The failure mode I see most often is people writing elaborate charts for a single in-house service that gets deployed to exactly one place, then spending more time fighting whitespace in templates than they ever spent on the app. If you find yourself there, you’ve out-engineered the problem. Strip it back. The best infrastructure tool is the smallest one that does the job, and sometimes that’s a folder of honest YAML and a kubectl apply.




