What Are Helm Charts? Kubernetes Packaging Explained
A Helm chart bundles a Kubernetes application's manifests into a templated, versioned package you can install, upgrade, and roll back as one unit.
A Helm chart is a package of templated Kubernetes manifests — the YAML files that define pods, deployments, and services — bundled together with a set of configurable values, so an entire application can be installed, upgraded, or removed as a single unit instead of applying a dozen separate YAML files by hand. Helm itself is the package manager that reads a chart and turns it into running resources on a cluster; the chart is the package it installs, the same way an npm package is what npm install acts on.
Why raw manifests aren’t enough
A moderately complex application on Kubernetes easily needs a Deployment, a Service, a ConfigMap, a Secret reference, maybe an Ingress and a few RBAC rules — each as its own YAML file. Applying them with kubectl apply works, but it leaves real gaps: there’s no built-in way to parameterize values (a replica count, an image tag, an environment-specific hostname) without hand-editing files, no atomic way to roll back a bad deployment across all those resources at once, and no version history of what was actually running at a given point in time.
Helm addresses all three. Charts use a templating language to inject variables into manifests at install time, Helm tracks each install as a numbered “release” so upgrades and rollbacks are single commands, and a chart can be versioned, published, and reused across environments and teams the same way a library package is.
What’s inside a chart
A chart is a directory with a defined structure:
Chart.yaml— metadata: the chart’s name, version, and a short description.values.yaml— the default configuration values a user can override at install time (replica count, image name and tag, resource limits, feature flags).templates/— the actual Kubernetes manifests, written with placeholders ({{ .Values.replicaCount }}) that get filled in fromvalues.yamlor command-line overrides when the chart is rendered.charts/(optional) — sub-charts, letting one chart depend on others, which is how a chart for a full application stack can bundle its own database or cache chart as a dependency.
Installing a chart renders every template against the supplied values, producing plain Kubernetes YAML, and applies the result to the cluster in one atomic operation Helm tracks as a release.
Upgrades and rollbacks
Because Helm tracks every install and upgrade as a numbered release with its rendered manifests stored in history, helm upgrade re-renders the templates against new values (a new image tag, an increased replica count) and applies the diff, while helm rollback reverts the entire release — every resource the chart manages — back to a previous numbered state in one command. This is a meaningfully different experience from manually tracking which of several YAML files changed between two deploys and reverting them individually.
Helm charts vs raw manifests vs Kustomize
Raw kubectl apply | Helm charts | Kustomize | |
|---|---|---|---|
| Templating/variables | None — edit files directly | Full templating language | Overlay-based patches, no templating |
| Versioned releases | No | Yes, with rollback | No built-in release tracking |
| Packaging & reuse | Copy/paste YAML | Publish and install a chart by name | Compose overlays, less portable as a package |
| Dependency bundling | Manual | Sub-charts | Not built in |
| Learning curve | Lowest | Moderate — a templating DSL to learn | Moderate — overlay/patch model |
Kustomize takes a different approach — patching a base set of manifests per environment without a templating language — and some teams use both together, or one instead of the other, depending on whether they want templating power or a patch-based, template-free model.
Environment-specific values
A single chart is usually installed multiple times with different values — once per environment. Rather than maintaining separate copies of the chart for staging and production, teams keep one chart and layer environment-specific override files on top of the defaults in values.yaml (a values-staging.yaml with fewer replicas and a smaller resource footprint, a values-production.yaml with more of both). The chart’s templates stay identical across environments; only the values feeding them change, which keeps configuration drift between environments visible as a diff between two small values files rather than buried across two forked copies of the underlying manifests.
Where Helm fits in a broader pipeline
Helm charts are commonly the deployment artifact a CI/CD pipeline produces and applies, often as part of a GitOps workflow where a chart’s values are updated in a Git repository and a controller in the cluster reconciles the live state to match. Public chart repositories also make Helm a common way to install popular infrastructure components — ingress controllers, monitoring stacks, databases — without hand-writing their manifests, which is one of the main reasons it became close to a default for anyone running a non-trivial Kubernetes workload.
Testing and linting a chart before it ships
Because a chart is ultimately just templates that render into YAML, it’s easy for a small templating mistake — a missing value, a typo in a variable name — to render silently wrong instead of failing loudly. Helm’s tooling includes a linter that checks a chart’s structure and templates for common mistakes before install, and a “dry run” mode that renders the final manifests without applying them, so a chart author can inspect exactly what would be sent to the cluster. Treating a chart with the same review discipline as any other piece of infrastructure code — rendering and diffing changes before they touch a live cluster — catches most of the class of bugs that would otherwise only surface as a failed or partially-applied release.
The takeaway
A Helm chart packages a Kubernetes application’s manifests into a templated, versioned unit that can be installed, upgraded, and rolled back atomically, solving the parameterization and release-tracking gaps that raw kubectl apply leaves open. Reach for it when an application has enough moving Kubernetes resources that hand-editing YAML per environment becomes error-prone, or when you want to install existing infrastructure components without writing their manifests yourself.
Tagged
Keep reading
Chisato · · 4 min read Kubernetes ConfigMaps vs Secrets: What's the Difference
ConfigMaps store non-sensitive configuration; Secrets store credentials with base64 encoding and tighter access controls. When to use each.
Chisato · · 4 min read Kubernetes StatefulSets vs Deployments Explained
Deployments manage interchangeable, stateless pods; StatefulSets give each pod a stable identity and storage. When each one actually belongs.
Chisato · · 5 min read What Is a Kubernetes Operator?
A Kubernetes operator encodes operational knowledge into software, automating tasks a human admin would otherwise do by hand for a specific application.