Helm Charts & Tools in 2026: The Complete Developer Guide
A comprehensive guide to Helm 3 charts, essential Helm plugins, chart repositories, and best practices for managing Kubernetes applications in 2026.
Helm has become the de facto package manager for Kubernetes. Whether you are deploying a single microservice or managing a hundred-chart repository across multiple environments, Helm streamlines the entire lifecycle β from templating and versioning to rollbacks and distribution. In 2026, the Helm ecosystem is richer than ever, with a mature Helm 3 at its core, a growing library of community charts, and powerful plugins that fill gaps in the default experience.
This guide covers everything you need to be effective with Helm in a modern Kubernetes workflow: chart anatomy, writing production-grade charts, essential tools and plugins, repository management, GitOps integration, and security hardening.
What Is Helm and Why It Matters in 2026
Kubernetes manifests are verbose and repetitive. A typical microservice deployment involves ConfigMaps, Secrets, Services, Ingresses, HorizontalPodAutoscalers, and more β multiplied across dev, staging, and production environments. Helm solves this by introducing a templating layer backed by a packaging format called a chart.
A Helm chart is a collection of YAML templates plus a values file that parameterizes them. Helmβs Go-based templating engine renders the final Kubernetes manifests at install time. Because charts are versioned and installable as a single unit, Helm brings the βaptβ or βbrewβ experience to Kubernetes.
The benefits are tangible:
- Reproducibility β Same chart, same version, same output across every environment.
- Parameterized configuration β Environment-specific values via or .
- Lifecycle management β Upgrade, rollback, and uninstall with atomic semantics.
- Reusability β Share charts via repositories or Git registries.
- Rollback support β One command to revert to any previous release revision.
Helm 3 Architecture: Key Differences from Helm 2
If you are still on Helm 2, upgrade immediately. Helm 3 removed the server-side Tiller component entirely, which was a security nightmare β anyone with access to Tiller could deploy anywhere in the cluster. Helm 3 uses a client-only architecture with cluster-side information stored in ConfigMaps and Secrets in the namespace being managed.
Key architectural changes:
- No Tiller β Helm 3 performs all operations client-side. Cluster access is via the same kubeconfig you already use.
- Three-way strategic merge patch β Helm 3 intelligently merges changes made by both you and other tooling, reducing conflicts on upgrade.
- Multiple cluster support β The same Helm client can manage releases in any cluster its kubeconfig can reach.
- Release names are scoped to namespaces β You can have a release named βredisβ in both the βcacheβ namespace and the βdataβ namespace.
Chart Directory Structure
A Helm chart lives in a directory that follows this canonical structure:
mychart/
Chart.yaml # Chart metadata (name, version, dependencies)
values.yaml # Default configuration values
charts/ # Local dependency charts (rarely used now)
templates/ # Kubernetes manifest templates
templates/NOTES.txt # Optional human-readable install notes
.helmignore # Files to exclude from the chart package
The most critical file is . It declares the chartβs identity and dependencies:
apiVersion: v2
name: my-frontend
description: Frontend service chart for the e-commerce platform
type: application
version: 1.3.0
appVersion: "2.1.0"
keywords:
- frontend
- react
- nginx
dependencies:
- name: postgresql
version: "12.5.0"
repository: "https://charts.bitnami.com"
The field distinguishes v1 charts (deprecated, Helm 2 era) from v2 charts (current). Use v2 for any new chart you create.
Writing Production-Grade Templates
Helm templates live in . Every file is processed by Goβs engine before being submitted to Kubernetes. A minimal template looks like:
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-config
namespace: {{ .Release.Namespace }}
data:
{{ .Values.app.name | default "myapp" }}: |
{{ .Values.app.config | default "default config" }}
The built-in objects available in every template are:
- β Name, Namespace, Revision, Service, IsUpgrade, IsRollback
- β User-supplied values merged over defaults
- β Metadata from Chart.yaml (name, version, etc.)
- β Access to chart files from directory
- β Information about the Kubernetes cluster (APIVersions, KubeVersion)
- β Current template context
Conditionals and Control Flow
Helmβs templating supports the full range of Go template functions plus Sprigβs library extension:
{{- if .Values.replicaCount gt 1 }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ .Chart.Name }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ .Chart.Name }}
minReplicas: {{ .Values.replicaCount }}
maxReplicas: {{ .Values.replicaCount | default 3 | add 2 }}
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
{{- end }}
Note the syntax β the dash followed by a space trims preceding whitespace, which is essential for clean YAML indentation in the rendered output.
Named Templates (Partial Includes)
For reusable snippet logic β label generators, common annotations, sidecar injectors β define named templates in :
# templates/_helpers.tpl
{{/*
Expand the name of the chart.
*/}}
{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "mychart.labels" -}}
app.kubernetes.io/name: {{ include "mychart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
Reference them in your templates with {{ include "mychart.labels" . }}:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "mychart.name" . }}
labels:
{{ include "mychart.labels" . | indent 4 }}
values.yaml: Structuring Configuration
The file is the backbone of a chartβs configurability. Structure it logically, group related values, and provide sensible defaults:
# Default configuration for my-frontend
replicaCount: 2
image:
repository: ghcr.io/myorg/frontend
pullPolicy: IfNotPresent
tag: ""
service:
type: ClusterIP
port: 8080
ingress:
enabled: true
className: nginx
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: frontend.example.com
paths:
- path: /
pathType: Prefix
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
nodeSelector: {}
tolerations: []
affinity: {}
Environment-Specific Values
Override defaults by providing additional values files:
helm install myfrontend ./charts/my-frontend -f values.prod.yaml
helm upgrade myfrontend ./charts/my-frontend -f values.staging.yaml -f values.override.yaml
Helm merges values in order: chart defaults β parent values file β child values file β flags (highest precedence).
A common pattern is environment-specific subdirectories:
my-frontend/
values.yaml # Base defaults
values.staging.yaml # Staging overrides
values.prod.yaml # Production overrides
Essential Helm Plugins
Helmβs plugin architecture extends the CLI without forking the codebase. Install plugins with:
helm plugin install https://github.com/chartmuseum/helm-push
helm plugin install https://github.com/helm/helm-secrets
helm plugin install https://github.com/helm-unittest/helm-unittest
helm-secrets
Manage sensitive configuration β API keys, database passwords, TLS certificates β directly in your values files, encrypted at rest with SOPS (and backends like GCS, AWS KMS, or Vault):
helm secrets upgrade myrelease ./charts/myapp -f secrets.prod.yaml
The plugin decrypts on the fly before passing values to Helm. Your Git repository stores only encrypted blobs, which is critical for GitOps workflows.
helm-unittest
Unit-test your chart templates in YAML without deploying to a real cluster:
helm unittest mychart
Tests are defined in and use a familiar assert-style syntax:
suite: MyChart Test Suite
templates:
- deployment.yaml
tests:
- it: should render a deployment with 2 replicas
asserts:
- equal:
path: spec.replicas
value: 2
helm-diff
Preview what an upgrade would change before executing it β invaluable for CI/CD safety:
helm diff upgrade myrelease ./charts/myapp -f values.prod.yaml
helm-push
Push charts to private registries like ChartMuseum or Harbor with a single command:
helm push mychart-1.0.0.tgz chartmuseum://myrepo/mychart
Chart Repositories
A chart repository is a simple HTTP server that serves an and a collection of packaged charts ( files). The official Artifact Hub (artifacthub.io) indexes thousands of community charts.
Setting Up a Simple Chart Repository
# Package your chart
helm package ./charts/mychart
# Create or update the index
helm repo index mycharts/ --url https://charts.example.com/mycharts
# Serve locally for testing
python3 -m http.server 8080 --directory mycharts
Using OCI Registries
Helm 3 supports OCI registries (the same Docker distribution spec) for chart storage. This is the recommended approach for enterprise workflows:
export HELM_EXPERIMENTAL_OCI=1
helm chart save ./charts/mychart ghcr.io/myorg/mychart:1.0.0
helm chart push ghcr.io/myorg/mychart:1.0.0
helm chart pull ghcr.io/myorg/mychart:1.0.0
helm chart export ghcr.io/myorg/mychart:1.0.0 ./imported/
OCI registry support makes it possible to store charts in the same container registry as your application images, using the same authentication credentials.
GitOps with Helm and ArgoCD
In a GitOps workflow, your Git repository is the single source of truth. ArgoCD (or Flux) continuously reconciles the cluster state with the desired state declared in Git.
Helm integrates cleanly with ArgoCD. You can register a Helm chart as an Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: myfrontend-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.bitnami.com
chart: nginx
targetRevision: "18.0.0"
helm:
valueFiles:
- values.prod.yaml
parameters:
- name: service.type
value: ClusterIP
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
For custom charts in Git, reference the repository URL pointing to your Git repo. ArgoCD renders the Helm templates server-side, so no local Helm installation is needed on the cluster.
Linting and Validation
Before publishing or deploying any chart, always run lint:
helm lint ./charts/mychart
helm template myrelease ./charts/mychart --debug --dry-run
renders the charts locally and outputs the Kubernetes manifests, which is perfect for CI/CD pipelines that cannot access the target cluster at plan time. Combine with or for schema validation:
helm template myrelease ./charts/mychart | kubeconform --strict -
Library Charts for Shared Logic
A powerful but underused feature is the library chart β a chart of type that defines reusable template snippets without deploying any Kubernetes resources. Other charts can declare it as a dependency and include its named templates:
# Chart.yaml of the consuming chart
dependencies:
- name: common
version: "1.2.0"
repository: "https://charts.example.com"
condition: common.enabled
This lets you centralize label generation, pod annotations, security contexts, and other boilerplate in one place, updating all dependent charts by bumping a single version number.
Security Best Practices
- Never store plaintext secrets in values files β Use SOPS + helm-secrets or external secret operators.
- Pin chart versions β In production, always specify not just . Unpinned aliases can silently pull new versions.
- Validate with helm template + kubeval β Never deploy an unvalidated chart.
- Use a policy engine β Tools like Datree or Styra DAS enforce Helm-specific policies in CI.
- Review rendered manifests before install β is your window into what actually gets deployed.
Versioning and Changelog
Maintain a within the chart directory. Helm does not enforce this, but it is essential for downstream users:
## 1.3.0
- Add HPA support with configurable average CPU utilization
- Update default image tag to AppVersion
- Fix tolerations template syntax
## 1.2.0
- Add ingressClassName support
- Deprecateζ§η approach
Closing Thoughts
Helm in 2026 is mature, powerful, and deeply integrated into the Kubernetes ecosystem. Whether you are a platform engineer maintaining a shared chart repository or a developer templating your first service, the patterns in this guide β structured values files, named templates, unit tests, linting, and GitOps integration β will help you build charts that are reliable, auditable, and maintainable at scale. Invest in chart quality upfront; it pays dividends every time someone runs .
50 CLI Commands That Save Hours Every Week
The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.
- Git mastery (10 cmds)
- File & search wizardry
- Docker & DevOps tricks
- Process & network tools
- Productivity boosters
- macOS & Linux install guide
No spam. 1 email/week max. Unsubscribe anytime.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links β we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.