---
title: "Kapitan vs Helm vs Kustomize: When to Use Each Tool"
description: "Compare Kapitan, Helm, and Kustomize for Kubernetes configuration management. Learn the tradeoffs, when each tool shines, and how they can work together."
---

# :kapitan-logo: **Kapitan vs Helm vs Kustomize**

Kapitan, Helm, and Kustomize all help you manage Kubernetes configuration, but they solve different problems at different layers. Choosing the right tool—or combining them—depends on your team's size, the complexity of your environments, and how much reuse you need across infrastructure systems.

## Quick comparison

| | **Helm** | **Kustomize** | **Kapitan** |
|---|---|---|---|
| **Primary goal** | Package and distribute Kubernetes applications | Patch and customize existing manifests | Generate and organize configuration across environments and tools |
| **Templating** | Go templates (`values.yaml`) | None (pure YAML overlays) | Jsonnet, Jinja2, Kadet, Helm, Kustomize, CUE |
| **Reuse across environments** | One chart, many `values.yaml` files | Bases and overlays per environment | Hierarchical inventory with classes and targets |
| **Multi-tool workflows** | Kubernetes only | Kubernetes only | Kubernetes, Terraform, scripts, docs, secrets |
| **Secrets management** | External tools (Sealed Secrets, Vault Agent, etc.) | External tools | Built-in references (GPG, KMS, Vault) |
| **Best for** | Distributing reusable charts | Overlaying environment-specific patches | Complex, multi-environment, multi-tool configuration |

## When to use Helm

Helm is the Kubernetes package manager. It is the best choice when:

- You want to install third-party software on your cluster (for example, Prometheus, nginx-ingress, cert-manager).
- You are building a reusable application chart that other teams will install with different `values.yaml` files.
- You need versioning and rollback for releases.

Helm's strength is packaging. Its weakness is that every environment needs its own `values.yaml` file, and values are not easily shared with non-Helm tools. If you have fifty microservices and each needs a slightly different Helm values file, you can end up with a lot of similar YAML that is hard to keep consistent.

Kapitan can help here: you can [render Helm charts inside Kapitan](input_types/helm.md) using the Helm input type, drive the values from the Kapitan inventory, and keep the chart configuration alongside your other infrastructure configuration.

## When to use Kustomize

Kustomize is built into `kubectl` and is the best choice when:

- You already have plain Kubernetes YAML manifests that you want to customize per environment.
- You prefer patch-based customization over templating.
- You want a tool that is simple, Kubernetes-native, and does not introduce a new language.

Kustomize's strength is simplicity. Its weakness is that it only works with existing YAML files, and it does not help you generate configuration from scratch or share data with Terraform, scripts, or documentation. As your environments grow, the number of overlays and patches can become difficult to manage.

Kapitan can help here: you can [use Kustomize as an input type](input_types/kustomize.md) to apply patches to manifests generated by other Kapitan input types, or you can generate the base manifests with Jsonnet or Kadet and then patch them with Kustomize.

## When to use Kapitan

Kapitan is a configuration management framework. It is the best choice when:

- You manage Kubernetes manifests, Terraform resources, scripts, and documentation in the same repository.
- You need a single source of truth for values that are reused across Helm charts, Kustomize overlays, Jsonnet templates, and Terraform modules.
- You want built-in secrets management that works with GPG, AWS KMS, GCP KMS, Azure Key Vault, or HashiCorp Vault.
- You have many environments (development, staging, production, multiple regions) and want to model them with a hierarchical inventory instead of many similar values files.

Kapitan does not replace Helm or Kustomize. It integrates with both. You can use Kapitan to:

- Generate Helm `values.yaml` files from the inventory and then render the chart with the Helm input type.
- Generate base Kubernetes manifests with Jsonnet and patch them with Kustomize.
- Keep your `bucket_name`, `namespace`, and `replica_count` in one place and use them in Kubernetes ConfigMaps, Terraform resources, and Helm values at the same time.

## Common patterns

### Helm inside Kapitan

Use the [Helm input type](input_types/helm.md) to render an upstream chart while overriding values from the Kapitan inventory:

```yaml
parameters:
  kapitan:
    compile:
      - output_path: .
        input_type: helm
        input_paths:
          - components/charts/nginx-ingress
        helm_values:
          controller:
            name: my-controller
        helm_params:
          name: my-release
          namespace: my-namespace
```

### Kustomize inside Kapitan

Use the [Kustomize input type](input_types/kustomize.md) to apply patches to manifests generated by another Kapitan input type:

```yaml
parameters:
  kapitan:
    compile:
      - output_path: manifests
        input_type: kustomize
        input_paths:
          - components/kustomize/overlays/production
```

### Plain YAML vs Kapitan inventory

Without Kapitan, you might copy `namespace: production` into every Helm values file, Kustomize overlay, and Terraform variable file. With Kapitan, you define it once in an inventory class and reference it everywhere:

```yaml
# inventory/classes/environments/production.yml
parameters:
  environment: production
  namespace: production
```

```yaml
# inventory/targets/web.yml
classes:
  - environments.production
  - components.web

parameters:
  kapitan:
    compile:
      - output_path: manifests
        input_type: jinja2
        input_paths:
          - templates/deployment.yml.j2
```

## Summary

- Use **Helm** for packaging and distributing Kubernetes applications.
- Use **Kustomize** for patching existing manifests per environment.
- Use **Kapitan** when you need a unified inventory that drives Helm, Kustomize, Jsonnet, Terraform, and secrets together.

---

## Next steps

- Learn how [Kapitan inventory](inventory/introduction.md) models environments with targets and classes.
- Explore [Kapitan input types](input_types/introduction.md): [Jsonnet](input_types/jsonnet.md), [Jinja](input_types/jinja.md), [Kadet](input_types/kadet.md), [Helm](input_types/helm.md), and [Kustomize](input_types/kustomize.md).
- See [Kapitan examples](kapitan_examples.md) for real-world setups.
