Self-hosted service
carvel-dev/kapp avatar
carvel-dev/kapp

kapp treats a labelled resource set as one Kubernetes application

kapp is a simple deployment tool focused on the concept of "Kubernetes application" — a set of resources with the same label

1,099 stars135 forksGoApache-2.0

At a glance

What is it?
kapp is a deployment CLI built around a single idea, that a set of resources sharing a label is an application that can be diffed and applied as a unit. It deliberately leaves templating and packaging to other tools, and it needs no controller in the cluster and no cluster-admin rights.
Who is it for?
kapp suits a team that already produces plain Kubernetes YAML and wants a deploy step that shows a diff, orders resource creation, waits for readiness and records history, without installing an operator in the cluster. It is the wrong tool when the deployment artefact is a template that must be rendered with values, since kapp explicitly leaves templating outside its scope.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The unit of work is a label, not a directory

kapp is described as a simple deployment tool focused on the concept of a Kubernetes application, which it defines as a set of resources with the same label. That definition is the whole design.

The consequences follow from it. A deploy does not mean one directory of manifests; it means every resource in the cluster carrying a particular label, which kapp finds and treats as a set. The documentation notes that it works with any group of labelled resources, and the example given is inspecting the resources selected by `label:tier=web`.

That is a different model from a file tree. It means the source of truth for what an application contains is the live cluster plus the files you give kapp, and the reconciliation is between the two, which the feature list describes as converging application resources by creating, updating and deleting them based on a comparison between the provided files and the live objects.

The audience is a Kubernetes user who wants bulk resource management and who is comfortable with labels as the grouping mechanism. The project is part of Carvel, and the site, the Slack channel and the community meetings are all organised around that.

The CLI is pronounced `kap`, which is the kind of small thing that tells you how the project treats itself.

Diff and apply are separate commands on purpose

The clearest thing about kapp is that calculating the change and applying the change are two distinct stages, and the feature list calls this out as a separate item. The documentation directory holds a page for each, `docs/diff.md` and `docs/apply.md`.

Separating them has a practical payoff. A diff run shows what kapp intends to change against what is running, with no cluster mutation, and the apply run then performs those changes. In a pipeline that means the change set can be reviewed, or produced as an artifact, before anything is written.

The same two-phase shape is what makes the other features work. Waiting for resources to become ready is part of the apply stage rather than a separate script, and change ordering, where CRDs and Namespaces are created first and other ordering can be specified, is resolved as part of computing the apply plan rather than left to the user to sequence by hand.

The repository's `examples/` directory shows what that means in practice, with directories for resource ordering, a deployment with a custom wait, jobs, and two generations of several real projects, including `cert-manager-v0.15.1` alongside `cert-manager-v1.6.1` and `istio-v1.12.2` alongside `istio-v1.16.0`. Having both an old and a new version of the same project in the tree is a useful signal about the range of manifests this is expected to handle.

No controller in the cluster and no admin rights needed

Two of the feature bullets are about what kapp does not need, and they matter more than they look.

The first is that kapp works without server-side components. There is no operator, no custom resource definitions, no controller reconciling anything on your behalf. Everything happens in the CLI process during a deploy. The second is that it works without admin privileges and does not use custom CRDs, which the documentation says makes it possible to use kapp as a regular user in a single namespace.

Compare that with a model where a controller in the cluster owns a custom resource and reconciles it. That model buys continuous reconciliation and a declarative desired state, and it costs cluster installation, elevated rights, and a component whose behaviour you do not control. kapp's model is the opposite: a stateless command that reads the cluster and writes to it, and that can be run by someone with ordinary permissions in the namespace they own.

The trade is continuity. Because nothing is running in the cluster between deploys, kapp does not detect drift or roll back on its own. It is a deployment tool, not a reconciler, and the project is explicit that it focuses on the deployment workflow.

History, version triggers and log streaming

Three smaller capabilities round out the workflow.

kapp records application deployment history, so a deploy leaves a trail that can be inspected later. The opt-in resource version management feature is the interesting one: the documentation gives the example of triggering a Deployment rollout when a ConfigMap changes. Since Kubernetes does not roll a Deployment when the content of a ConfigMap it mounts changes, something has to break the tie, and this is the mechanism, and it is opt-in rather than default, which means it is applied only where you ask for it.

The CLI can also optionally stream Pod logs during a deploy, which turns the apply step into something you can watch rather than something you wait for blindly.

The grouping model also extends to selection. The documentation notes that kapp works with any group of labelled resources, and the GitOps friendly example in the feature list is `kapp app-group deploy -g all-apps --directory .`, which deploys a directory of configuration as a named app group. That is the shape that fits a repository of manifests per environment: one directory, one group name, one command.

None of these are the reason to pick kapp over anything else. The diff and apply split, the ordering, and the absence of a controller are the reasons. The rest is convenience.

Installing the binary and running the first commands

There is no package to install and no chart to apply. The documentation says to grab prebuilt binaries from the releases page, or use the Homebrew Carvel tap.

The tap lives in the carvel-dev homebrew repository, though the exact formula name is not given in the project documentation, so the releases page is the safer starting point for a first install. A Go developer can also build from source, since the project is a Go module named `carvel.dev/kapp`, and the build instructions and code structure are described in `docs/dev.md`.

The first command worth running is an inspection, which reads the live cluster and shows the resources kapp considers part of an application:

bash
kapp -a label:tier=web inspect -t

The `-a` flag names the application, the label selector says which resources belong to it, and `-t` asks for the tree view, which is the picture of the application's structure with the relationships between the resources. That command changes nothing, which makes it the right first thing to run and the right thing to run when a deploy is not doing what you expected.

For a directory of configuration, the documented GitOps form is:

bash
kapp app-group deploy -g all-apps --directory .

The `diff` and `apply` documents under `docs/` describe the individual stages in detail, and the project website carries a full example workflow.

Templating is deliberately out of scope

The clearest statement of kapp's limits is in the project description itself. Unlike tools such as Helm, kapp considers YAML templating and management of packages outside of its scope, though it works well with tools that generate Kubernetes configuration.

This is the limitation to internalise before adopting. If your deployment artefact is a template with values, something has to render it before kapp sees it, and that something is a separate tool in the pipeline. The project names ytt as the example of a tool that produces Kubernetes configuration and plays well with kapp, and the Go module reflects the relationship, since carvel.dev/ytt and carvel.dev/kapp-controller are both direct dependencies of carvel.dev/kapp, alongside vendir as an indirect one.

The alternative approach, and the one Helm represents, folds templating and packaging into the deployment tool. The deploy step is then coupled to the template format and to the packaging model that produced the artefact.

kapp's approach is to be a plain consumer of YAML. It works with standard Kubernetes YAML, it does not require the resources to be arranged in any particular shape, and it converges them against the cluster. The cost is that the value-substitution step, the environment matrix and the release history of the package all live somewhere else.

There is a second limit worth stating. Because kapp is not a reconciler, nothing detects drift between deploys. A resource changed by hand in the cluster stays changed until the next deploy, and the next diff is where you find out.

Two release lines, a Go 1.27 floor and Apache 2.0

The maintenance picture is a little unusual. The recent releases are v0.65.5 on 2026-10-15, v0.66.1 on 2026-10-13, and v0.65.4 on 2026-08-25, so two lines are being released from in parallel, with the 0.66 line ahead on the minor version and the 0.65 line receiving a patch after it.

That kind of parallel versioning usually means a 0.65 series is maintained for a while after 0.66 appears, and it means the choice of line is a decision rather than a default. The repository is not archived and the last push was on 2026-10-15, so both lines are receiving work. The default branch is `develop`, which is worth knowing before you file a pull request against the wrong branch.

The Go requirement has moved. The module declares `go 1.27.2`, and it depends on the Kubernetes libraries at 0.35.9, so the tool is built against a current Kubernetes client and needs a current Go toolchain to build from source. The dependency list also shows carvel.dev/kapp-controller v0.59.7 and carvel.dev/ytt v0.55.3, which is how the relationship with the rest of Carvel is expressed in code.

The licence is Apache-2.0, with a LICENSE file, a NOTICE file and a MAINTAINERS.md in the repository root. The project also carries a code of conduct, a governance file, a security policy and a roadmap, and it is registered with the OpenSSF Best Practices badge, which is the kind of signal a platform team looks for when adding a tool to a supply chain.

Editorial conclusion

kapp suits a team that already produces plain Kubernetes YAML and wants a deploy step that shows a diff, orders resource creation, waits for readiness and records history, without installing an operator in the cluster. It is the wrong tool when the deployment artefact is a template that must be rendered with values, since kapp explicitly leaves templating outside its scope. Check first that your resources carry the label kapp will select on, then run the diff stage on its own before the apply stage, since the two are separate commands precisely so that the change set can be reviewed.

Frequently asked questions

What does kapp consider a Kubernetes application?

A set of resources with the same label. kapp manages such a set in bulk, and the documentation shows selecting one by label with `kapp -a label:tier=web inspect -t`.

Does kapp need to be installed in the cluster?

No. The project states that kapp works without server-side components and does not use custom CRDs, and that it works without admin privileges, which makes it possible to use it as a regular user in a single namespace.

How do I install kapp?

Grab a prebuilt binary from the repository's releases page, or install it from the Homebrew Carvel tap. The source is a Go module named `carvel.dev/kapp`, and the build instructions are in `docs/dev.md`.

Can kapp render Helm style templates?

No. The project states that, unlike tools such as Helm, kapp considers YAML templating and management of packages outside of its scope, though it works well with tools that generate Kubernetes configuration, such as ytt.

Official sources

  1. carvel-dev/kapp on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/carvel-dev-kapp.svg)](https://hysenlabs.com/projects/carvel-dev-kapp)

Was this useful?