Helm vs Kustomize in 2026: Templating vs Patching After Helm 4
The question I get asked most by teams standing up their first GitOps repo is not which cluster or which CI system. It is "Helm or Kustomize?", usually asked after someone has already written forty lines of Go template to change one replica count. Both tools turn files in Git into Kubernetes manifests, both are maintained by Kubernetes-adjacent projects, and both had meaningful releases in the last twelve months. This post explains the actual difference between Helm and Kustomize (templating versus patching), what Helm 4 and kustomize 5.8 changed in 2026, the version gap between standalone kustomize and the one inside kubectl, how Argo CD and Flux treat each, and the combination I would pick for most teams today.
Helm vs Kustomize: what is the actual difference?
Helm is a package manager. A chart is a directory of Go templates plus a values.yaml; you render it with values and Helm produces YAML. When you helm install or helm upgrade, Helm also records a release in the cluster (a Secret of type helm.sh/release.v1 per revision), which is what gives you helm history and helm rollback. The chart author decides which knobs exist. If they did not template the field you need, you fork, post-render, or file an issue.
Kustomize is a patcher. You keep plain, valid Kubernetes YAML in a base directory and write overlays that say "take the base, set the namespace, change the image tag, apply this patch". There are no variables and no templating language. Every input file is something kubectl apply would accept on its own, which is why it reads so easily in review. Kustomize has been built into kubectl since Kubernetes 1.14 in March 2019, as kubectl apply -k and kubectl kustomize. It keeps no state in the cluster. Your Git history, or your GitOps controller, is the record of what was deployed.
That one difference explains most of the arguments. Helm is good at distributing software to people you will never meet, because the chart author can hide complexity behind a values schema. Kustomize is good at managing your own manifests across environments, because the person reading the overlay sees exactly what changes. They solve different problems, and the friction starts when a team uses one for the other's job: Helm charts written for a single internal app with three environments, or Kustomize overlays trying to package a product for strangers.
What changed in 2026: Helm 4, kustomize 5.8 and the kubectl version gap
Helm 4.0.0 shipped on 12 November 2025. The changes that matter for this comparison: Helm now uses server-side apply for new installs, waits on resources with kstatus, and post-renderers are now plugins rather than any executable on your path. That last one breaks the classic "pipe Helm output through a kustomize script" trick until you wrap the script as a plugin. I covered the rest of the upgrade in Helm 4 vs Helm 3. The current release is 4.3.1 from 15 October 2026, and Helm 3 gets security fixes only until 10 February 2027 according to the Helm 3 end-of-life post.
Kustomize had a quieter but bumpier year. 5.8.0 (9 November 2025) let replacements reach inside YAML or JSON stored in string fields, and shipped with a namespace propagation regression its own release notes told people to avoid. 5.8.1 (9 February 2026) fixed that and added Helm 4 support to --enable-helm, which had failed because Helm 4 removed the helm version -c flag kustomize called (issue #6013). 5.8.2 added kustomize edit add configuration and kustomize edit remove component, and notes that the built-in OpenAPI schema is still based on Kubernetes v1.21.2. 5.8.3 (8 October 2026) is a dependency cleanup (its notes say "No functional changes in kustomize"), done to make the bump into kubectl easier.
That bump matters because most people run the kustomize inside kubectl, not the standalone binary, and the two drift. I checked staging/src/k8s.io/kubectl/go.mod at each release tag:
| Tool | Version (date) | Embedded or bundled kustomize | Source |
|---|---|---|---|
| Helm | 4.3.1 (15 Oct 2026) | n/a, also 3.22.1 for Helm 3 | helm releases |
| kustomize (standalone) | 5.8.3 (8 Oct 2026) | itself | kustomize release |
| kubectl 1.37.2 / 1.36.6 | 28 Oct 2026 | kustomize 5.8.1 | kubectl go.mod v1.37.2 |
| kubectl 1.35.10 / 1.34.13 | 28 Oct 2026 | kustomize 5.7.1 | kubectl go.mod v1.35.10 |
| kubectl 1.38.0-beta.0 | 6 Nov 2026 (pre-release) | kustomize 5.8.3 | kubectl go.mod v1.38.0-beta.0 |
| Argo CD 3.6.1 | 4 Nov 2026 | kustomize 5.8.3, Helm 4.3.1 | tool-versions.sh |
| Flux kustomize-controller 1.10.1 | 26 Oct 2026 (Flux 2.10.0) | kustomize api pinned to 5.8.1 | go.mod |
So a developer on kubectl 1.35 renders with 5.7.1, Argo CD renders with 5.8.3, and the namespace and replacement behaviour changed in between. Check before you trust a local render:
# Which kustomize does my kubectl embed? (prints "Kustomize Version: v5.x.y")
kubectl version --client
# Standalone binary, if installed separately
kustomize version
# Pin the standalone binary in CI to what your GitOps controller runs.
# Argo CD 3.6.x bundles kustomize 5.8.3 (hack/tool-versions.sh in the argo-cd repo).
KUSTOMIZE_VERSION=5.8.3
curl -sSLo kustomize.tar.gz \
"https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv${KUSTOMIZE_VERSION}/kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz"
tar -xzf kustomize.tar.gz kustomize && ./kustomize version
On my laptop, kubectl 1.32.3 reports Kustomize Version: v5.5.0, which is a good reminder that "it renders on my machine" means very little until the versions match.
Can you use Helm and Kustomize together?
Yes, and for most real platforms you will. Vendor software (ingress controllers, cert-manager, Prometheus) arrives as Helm charts; your own services are better as plain YAML. There are three ways to combine them, and they behave differently.
1. Kustomize inflates the chart (helmCharts). Kustomize's built-in HelmChartInflationGenerator runs helm template for you when you pass --enable-helm, then applies your patches to the output. The helmCharts reference lists fields such as name, repo, version, releaseName, namespace, valuesInline, valuesFile and includeCRDs:
# kustomization.yaml, rendered with: kustomize build --enable-helm .
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: kube-system
helmCharts:
- name: metrics-server
repo: https://kubernetes-sigs.github.io/metrics-server/
version: 3.14.0 # pin the chart; latest in the repo index on 10 Nov 2026
releaseName: metrics-server
namespace: kube-system # set it here too; see open issue #6058
valuesInline:
args:
- --kubelet-insecure-tls
patches:
- target:
kind: Deployment
name: metrics-server
patch: |-
- op: add
path: /spec/template/spec/priorityClassName
value: system-cluster-critical
The catch: --enable-helm executes the helm binary on whatever machine renders, with arguments built from your kustomization file. A flag-injection report against helmCharts[].releaseName was filed on 31 August 2026 and fixed on 15 September; the fix ships in 5.8.2 and later, so the 5.8.1 embedded in kubectl 1.36 and 1.37 does not have it. And there are open regressions since 5.8.0 where namespaces (#6058) and generated ConfigMap hash suffixes (#6189) do not propagate into chart output the way they used to.
2. Helm renders, Kustomize post-renders. helm upgrade --post-renderer hands the rendered manifests to a program that can run kustomize build. You keep Helm's release history and rollback. In Helm 4 that program must be packaged as a postrenderer/v1 plugin, so budget a small piece of work if your pipelines rely on a shell script today.
3. Let the GitOps controller do it. This is usually the cleanest, and it is the next section.
How do Argo CD and Flux handle Helm and Kustomize?
Argo CD detects a kustomization.yaml in an Application's path and runs kustomize; for charts it runs Helm, but only helm template, so Argo CD owns the lifecycle and helm ls shows nothing. That surprises people the first time. To use helmCharts inside a kustomization, Argo CD's Kustomize docs say --enable-helm is not an Application option: you either write a config management plugin or set kustomize.buildOptions: --enable-helm globally in the argocd-cm ConfigMap. Argo CD also accepts inline patches, images, replicas and components in the Application spec, which is handy with ApplicationSets but spreads configuration across two places. I compared the controllers in more depth in Argo CD vs Flux.
Flux takes a firmer line. Its FAQ says Flux does not allow kustomize plugins that shell out to binaries inside kustomize-controller, for security and performance reasons, so helmCharts does not work there. You use a HelmRelease for the chart, and if you need to patch its output, the HelmRelease has spec.postRenderers with built-in Kustomize patches and images, no external binary involved. Flux 2.10.0 shipped on 26 October 2026.
My reading of the two: Flux's split (HelmRelease for charts, Kustomization for your YAML, kustomize patches as post-renderers) is the more defensible security model. Argo CD's global --enable-helm is convenient but turns on binary execution for every Kustomize app on the instance.
When does Helm hurt, and when does Kustomize hurt?
Helm hurts when the chart is yours and the audience is you. Templating YAML with a whitespace-sensitive text engine produces {{- include "app.labels" . | nindent 4 }} everywhere, values files grow into an undocumented second API, and a reviewer cannot tell what a values change does without rendering it. Helm also stores state: release Secrets accumulate, a failed upgrade can leave a release in pending-upgrade, and Helm 4's switch to server-side apply surfaces field ownership conflicts that client-side apply used to paper over. If you just want to fix these, the Helm UPGRADE FAILED guide goes cause by cause.
Kustomize hurts in different places. It has no parameters, so anything that varies by more than a handful of fields across many environments turns into a pile of near-identical patches. Strategic merge patches depend on schema knowledge (the built-in schema is still Kubernetes 1.21.2 based), so a patch to a custom resource list can replace the list instead of merging it. Generated ConfigMap names with hash suffixes are great for rollouts and confusing in incident calls. Old fields still work but warn: when I rendered an older overlay, kubectl's embedded kustomize printed that commonLabels and patchesStrategicMerge are deprecated and suggested kustomize edit fix. And there is no release, so rollback means reverting a commit and letting the controller sync.
Helm or Kustomize: which should you use in 2026?
The rule I use is about who writes the inputs and who consumes them:
- Software other people install (an operator, a product, a shared platform add-on): Helm chart, published to an OCI registry, with a values schema.
- Your own services across dev, staging and prod: Kustomize base and overlays. Plain YAML, small diffs, readable reviews. The paired Kustomize overlays tutorial builds exactly this layout step by step.
- Vendor charts you need to tweak: Helm for the chart, Kustomize patches for the tweak, with the GitOps controller doing the composition (Flux HelmRelease post-renderers, or Argo CD multi-source Applications). Use
helmChartsin kustomize only where you accept the binary execution and the open regressions. - Hundreds of near-identical environments: neither scales well by hand. That is where an ApplicationSet generator or a typed configuration tool earns its place.
Whatever you pick, the discipline is the same one platform teams have argued for since before GitOps had a name: pin every version (chart, kustomize, Helm, controller), render in CI with the same binary the controller uses, and diff the rendered output on every pull request. In a year when agents open a growing share of pull requests, a rendered diff is the only thing a reviewer can actually check.
FAQ
Is Kustomize better than Helm?
Neither is better in general. Kustomize is better for managing your own manifests across environments because it uses plain YAML and patches. Helm is better for packaging and distributing software, and it adds release history and rollback, which Kustomize does not have.
Does kubectl include Kustomize?
Yes. kubectl has embedded Kustomize since Kubernetes 1.14, available as kubectl apply -k and kubectl kustomize. The embedded version lags the standalone binary: kubectl 1.36 and 1.37 ship kustomize 5.8.1, while the standalone release is 5.8.3. Run kubectl version --client to see yours.
Can Kustomize render Helm charts?
Yes, through the helmCharts field and the --enable-helm flag, which runs the helm binary for you. Kustomize 5.8.1 or later is needed for Helm 4. Flux does not allow it, and Argo CD needs kustomize.buildOptions: --enable-helm set globally in argocd-cm.
Does Argo CD use helm install?
No. Argo CD renders charts with helm template and applies the output itself, so releases do not appear in helm ls and Helm's rollback does not apply. Rollback happens through Argo CD's own history or a Git revert.
This quarter I would do three things in any repo that mixes both: pin the standalone kustomize in CI to the version the GitOps controller bundles (5.8.3 for Argo CD 3.6), grep for helmCharts and decide deliberately whether binary execution in the controller is acceptable, and move any Helm 3 --post-renderer scripts to Helm 4 plugins before the February cutoff. Then I would stop writing Helm charts for services that only my team deploys.
Related: Helm 4 vs Helm 3: What Changed, and Why Helm 3 Ends in February 2027, Argo CD vs Flux in 2026: GitOps After Argo CD 3.5 and Flux 2.9 and How to Set Up Argo CD for GitOps: Step-by-Step Guide (2026).
Spot an error or something out of date? Email me and I will fix it and log it on the corrections page.
I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents, and write about the infrastructure and tooling around it.
Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.
Related
Best DevOps and Cloud Certifications 2026: 16 Exams, Prices, Validity
The DevOps and cloud certifications worth paying for in 2026: CKA, CKAD and CKS on Kubernetes v1.37, AWS SAA, CloudOps and DevOps Pro, the new AI exams, Azure, GCP and Terraform 004, with verified prices, validity and what hiring managers value.
13 minOct 20, 2026Terraform vs Pulumi vs Crossplane in 2026: Which to Choose
Terraform, OpenTofu, Pulumi and Crossplane compared as of October 2026: how each handles state and drift, what it costs, and which team fits which tool.
12 minOct 20, 2026Argo CD vs Flux in 2026: GitOps After Argo CD 3.5 and Flux 2.9
Argo CD vs Flux in 2026: what changed in Argo CD 3.0 to 3.5 and Flux 2.6 to 2.9, who maintains Flux after Weaveworks, what the CNCF surveys say about adoption, how each handles multi-cluster and secrets, and where GitOps costs more than it saves.
13 min