# Helmfile: a declarative spec for deploying Helm charts, Kustomize configs and raw manifests

> Helmfile wraps Helm, helm-diff and Kustomize behind one version-controlled state file. Here is how the mechanism works, how to get a first release running, and where the tool stops being the right answer.

**helmfile/helmfile** — Declaratively deploy your Kubernetes manifests, Kustomize configs, and Charts as Helm releases. Generate all-in-one manifests for use with ArgoCD.

- Repository: https://github.com/helmfile/helmfile
- Website: https://helmfile.readthedocs.io
- Stars: 5,213 · Forks: 370
- Language: Go
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/helmfile-helmfile

## The problem Helmfile solves: many charts, one reviewable file

A single Helm chart is easy to reason about. A platform made of thirty charts is not. Each chart has its own values file, its own namespace, its own install order, and its own set of flags you have to remember. Teams end up with a shell script that runs helm upgrade once per component, and that script becomes the real source of truth, unversioned in any meaningful sense and impossible to diff before it runs.

Helmfile replaces that script with a YAML file. The README describes it as "a declarative spec for deploying helm charts" and lists the intended workflow: keep a directory of chart value files under version control, apply CI/CD to configuration changes, and periodically sync so environments do not drift apart. The unit of work is the release, declared with a name, a namespace, a chart reference and values. Everything Helm can install, Helmfile can declare.

The audience is platform and infrastructure engineers who already use Helm and want the declarative file to be the thing they review. If you have never run helm install, Helmfile adds a layer before the layer you have not learned yet. Its own documentation points at Helm's install guide as a prerequisite.

## How Helmfile works: a wrapper over helm, helm-diff and Kustomize

The README is explicit that Helmfile does not reimplement Helm. To avoid upgrades for each iteration of helm, the helmfile executable delegates to helm. That delegation is the whole architecture. Helmfile reads helmfile.yaml, resolves repositories, environments, values and templates, then shells out to the helm binary for the actual install, upgrade and uninstall operations. Two dependencies are named as required: helm itself and the helm-diff plugin.

Because it delegates, Helmfile inherits Helm's behaviour rather than redefining it. Release state lives in the cluster, in Helm's own release records, not in a Helmfile database. That is why the README tells you to run helmfile init once after installation, since the diff plugin has to be present before Helmfile can show you what a change would do.

The file is not just a list. The README's highlights name four capabilities. Declarative state files for reproducibility. Modules, which let you modularize common patterns and distribute them over Git or S3 for reuse across a company. Versatility, meaning a single file can manage charts, Kustomize configs and plain directories of Kubernetes resources, all turned into Helm releases. And patching: JSON or strategic-merge patches applied to Kubernetes resources before helm install, so you can adjust an upstream chart without forking it.

That last point is the most interesting design choice. Patching after rendering but before install means the modified object is what Helm records as the release, which keeps helm get manifest honest. The trade-off is that your patch is now part of the deployment path, and a patch written against one chart version can silently stop matching after an upstream change.

## Installing Helmfile and running a first helmfile apply

The README gives four installation routes. Download a binary from the releases page. Use a package manager: pacman on Arch Linux, zypper on openSUSE, scoop on Windows, brew on macOS, or mise on Linux, macOS and Windows. Run it as a container, with details in the documentation under running as a container. Or build from source with Go.

The package manager route on macOS is a single command:

```bash
brew install helmfile
```

After any of these, the README says to run helmfile init once, because Helmfile uses the helm-diff plugin. That step is not optional; diff-based commands depend on it.

```bash
helmfile init
```

You can also scaffold a project rather than writing the file by hand. The README's getting-started section shows this command, which generates a directory structure following the project's own best-practice layout:

```bash
helmfile create my-project && cd my-project
```

If you prefer to write the file yourself, the README's example declares a chart repository and one release. The release sets a single value inline, turning off RBAC creation for a Prometheus install:

```yaml
repositories:
- name: prometheus-community
  url: https://prometheus-community.github.io/helm-charts

releases:
- name: prom-norbac-ubuntu
  namespace: prometheus
  chart: prometheus-community/prometheus
  set:
  - name: rbac.create
    value: false
```

With that file in place, the README's sync command is:

```bash
helmfile apply
```

According to the README, you should then have your first Prometheus deployment running inside your cluster. The distinction between apply and sync matters and is worth checking in the CLI reference before you run either against a shared cluster: apply is the diff-aware path, sync is the direct one. The README's own getting-started flow uses apply, and the diff plugin is the reason init comes first.

## Where Helmfile is the wrong tool

Helmfile is a CLI. It runs when you run it. Nothing in the README claims a controller, a reconciliation loop, or a daemon that notices drift and corrects it. The README suggests periodically syncing to avoid skew in environments, which is an instruction to you or to your scheduler, not a feature of the binary. If your requirement is that the cluster converges on its own after someone edits a resource by hand, Helmfile does not do that on its own.

There is a second boundary. Helmfile delegates to helm, so it adds nothing to Helm's own failure modes. A release that is stuck in a failed state is still a Helm release in a failed state. Helmfile can show you the diff and run the upgrade; it cannot reason about why the chart's hooks timed out.

The dependency chain is a third constraint. helm and helm-diff must both be present and working. In a locked-down CI image, that means the image has to carry both, plus whatever credentials the charts need. The repository's own Dockerfile shows how much goes into a working image: it installs ca-certificates, git, bash, curl, jq, yq, openssh-client and gnupg, then downloads a specific Helm version and verifies it against a SHA256 checksum before extracting it. That is a reasonable image, but it is not a small one, and it tells you what Helmfile assumes is available around it.

## Helmfile against plain Helm and against Argo CD

The honest alternative for a single release is plain Helm. helm install with a values file is fewer moving parts, one binary, one file, no init step. The difference in approach is scope: Helm operates on one release per invocation, and Helmfile operates on a declared set of releases per invocation. If your deployment is genuinely one chart, Helmfile is a wrapper you do not need yet. It becomes worth the extra dependency the moment you have a set of releases that must be reasoned about together, because that is when the shell script appears.

The more interesting comparison is Argo CD. Argo CD is a controller that watches a Git repository and reconciles the cluster toward it continuously. Helmfile is a command you run. The README does not position Helmfile as a replacement for that; it says Helmfile can generate all-in-one manifests for use with Argo CD. So the two compose rather than compete: Helmfile renders, Argo CD reconciles. If you want the render step to happen inside the cluster rather than in CI, that composition is the path, and the README's description of the project is the only claim made about it here.

## Maintenance, upgrades and the MIT licence

The repository is not archived, and the last push was on 2026-09-20. Releases are frequent: v1.8.0 on 2026-09-13, v1.7.4 on 2026-08-16 and v1.7.3 on 2026-08-04. For a tool that sits in a deployment path, that cadence is the relevant fact, because it means the version you pin is a version you will be moving off sooner rather than later.

The upgrade cost is concentrated in one place. The README's status section notes that v1.0 and v1.1 have been released and recommends upgrading directly to v1.1 if you are still on v0.x, and it points at a proposal document describing a small list of breaking changes. If you are starting fresh, that migration does not concern you. If you are inheriting a v0.x helmfile.yaml, read that proposal before you touch the file, because the breaking changes are in the spec you are editing.

Helmfile is MIT licensed. In practical terms that permits reuse and modification with the licence and copyright notice retained, but the repository also ships a SECURITY.md and a CODEOWNERS file, which is where you should look for how the project wants vulnerabilities reported. Nothing here is legal advice; if you are redistributing a modified Helmfile inside a product, read the LICENSE file itself rather than a summary.

## Conclusion

Adopt Helmfile if you already run Helm and want the set of releases for an environment expressed as a reviewable file rather than a sequence of shell commands, and if you are willing to install helm-diff alongside it. Do not adopt it if you want a controller that reconciles the cluster continuously while nobody is watching; Helmfile is a CLI you invoke. Before committing, verify three things yourself: that helmfile init has installed the helm-diff plugin, that helmfile diff against a scratch namespace shows the changes you expect, and that the release set in your helmfile.yaml matches what is actually running in the cluster.

## FAQ

### What is a helmfile?

It is a declarative spec for deploying Helm charts, kept as a YAML file in version control. The helmfile executable reads that file and delegates the actual install and upgrade work to helm.

### Can Argo CD be used with Helmfile?

Yes. The project description says Helmfile can generate all-in-one manifests for use with Argo CD, so Helmfile handles rendering and Argo CD handles reconciliation.

### How do I install Helmfile?

Download a binary from the releases page, use a package manager such as brew, pacman, zypper, scoop or mise, run it as a container, or build from source with Go. The README says to run helmfile init once afterwards, because Helmfile uses the helm-diff plugin.

### What does helmfile sync do?

The README's getting-started flow uses helmfile apply to bring the cluster in line with the declared releases. Both commands appear in the CLI reference, and the README does not spell out the difference between them, so check that reference before running either against a shared cluster.

### What is Helmfile used for?

It keeps a directory of chart value files under version control, applies CI/CD to configuration changes, and lets you periodically sync so environments do not drift apart. It can manage charts, Kustomize configs and directories of Kubernetes resources as Helm releases.

### What is helmfile yaml?

It is the state file Helmfile reads, holding repositories and releases. The README's example declares a chart repository by name and URL, then a release with a name, namespace, chart reference and inline values.

## Sources

- [helmfile/helmfile on GitHub](https://github.com/helmfile/helmfile)
- [License: MIT](https://github.com/helmfile/helmfile/blob/main/LICENSE)
- [Project website](https://helmfile.readthedocs.io)
- [README](https://github.com/helmfile/helmfile/blob/main/README.md)
- [Releases](https://github.com/helmfile/helmfile/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/helmfile-helmfile
