Self-hosted service
garden-io/garden avatar
garden-io/garden

Garden: a YAML action graph for Kubernetes dev, test and CI

Automation for Kubernetes development and testing. Spin up production-like environments for development, testing, and CI on demand. Use the same configuration and workflows at every step of the process. Speed up your builds and test runs via shared result caching

3,614 stars296 forksTypeScriptMPL-2.0

At a glance

What is it?
Garden Core is a TypeScript-built CLI that describes a Kubernetes stack as typed actions in garden.yml and executes them in dependency order. It is worth adopting if your dev loop and your CI pipeline currently run different tooling; it is the wrong tool if you only need to apply manifests to a cluster.
Who is it for?
Adopt Garden if your team already runs Kubernetes and you want the same garden.yml to drive both a developer's inner loop and the CI pipeline, with Build, Deploy and Test actions wired by explicit dependencies. Do not adopt it if your deployment surface is a handful of manifests that kubectl apply handles, or if you need a hosted control plane and cannot run the Garden Core binary yourself.
Can I use it commercially?
Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 23 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

The problem Garden targets: two toolchains for one stack

Most Kubernetes teams end up maintaining two descriptions of the same system. One lives in a developer's head and shell history: port-forwards, local image builds, a Helm install for the database. The other lives in CI: a pipeline that builds images, tags them, applies manifests, and runs integration tests. The two drift, and the drift shows up as the classic failure where a change passes locally and breaks the pipeline, or the reverse. Garden's stated goal is to collapse that split. The README frames it as spinning up production-like environments for development, testing and CI on demand, and using the same configuration and workflows at every stage of software delivery. The audience is therefore teams that already run Kubernetes and have enough moving parts (multiple services, a database dependency, integration tests) that the ordering between those parts matters. A single-container app with one manifest is not the target reader.

The action graph, and why dependencies are declared rather than inferred

Garden's configuration framework is a set of YAML documents, each with a kind, a name and a type. The README's example shows four: a Deploy named db of type helm that points at the Bitnami postgres chart, a Build named api of type container with a source path, a Deploy named api of type kubernetes with manifestFiles, and a Test named integ of type container that runs npm run test:integ. The mechanism that ties them together is what the README calls the action graph. Edges are explicit: the api Deploy lists dependencies: [build.api, deploy.postgres], and the Test lists dependencies: [deploy.api]. Garden walks that graph and executes actions in order, and the README states that it tracks changes to avoid unnecessary builds, deploys and test runs. That is the caching claim in its concrete form: an action whose inputs have not changed does not re-run. The design choice worth noting is that dependencies are hand-written strings, not derived from file contents or image references. That gives you control over ordering across repositories, which the README calls out as a supported case, but it also means a missed dependency is a silent correctness bug rather than a parse error. Nothing in the material suggests Garden validates that deploy.api actually corresponds to a running workload before the Test fires.

Getting from zero to a running environment

The README points to a quickstart guide on docs.garden.io as the fastest path, and does not reproduce installation steps, so treat the docs as the source for binary installation. What the README does give is the command surface. Build and deploy the example project with garden deploy. Run the test actions with garden test. Create a per-pull-request environment by adding garden deploy --env preview to a CI pipeline; the env flag is how the same config produces a differently named environment. For the inner loop there are two modes. garden deploy --sync enables what the README calls sync mode, which live reloads changes to running services. garden dev starts an interactive console from which you can build, deploy and test. Configuration is read from garden.yml files, and the README notes they can be split up and co-located with the relevant parts of the stack, including across multiple repositories. The plugin decides what an action of a given type actually does: the README names Kubernetes as the most used plugin, followed by Terraform and Pulumi, and links separate guide pages for each.

Where the model strains: sync mode, plugins and hidden state

Sync mode is the feature most likely to disappoint on first contact, and the README does not set expectations about it. Live reloading a running service depends on the plugin knowing how to push changed files into a container, which is straightforward for a container action with a predictable filesystem layout and awkward for anything else. The documentation for the Kubernetes plugin is where that detail would live, not the README. The plugin boundary is the second source of friction. Because how actions are executed depends on the plugin, the behaviour of a Deploy of type kubernetes is not defined by Garden Core; it is defined by the plugin version shipped with the binary you installed. A Garden upgrade can therefore change how an existing garden.yml behaves without any edit to the file. The third constraint is state. Change tracking and result caching imply Garden keeps a record of what it has run and with which inputs. The README does not describe where that record lives, how it is shared between a developer machine and CI, or how to invalidate it when it goes wrong. For a team evaluating Garden, that is the single biggest unknown: the caching is the selling point, and its invalidation semantics are not in the material.

Garden against a plain Helm plus kubectl workflow

The most common alternative is not another product but the combination most Kubernetes teams already have: Helm charts applied with helm upgrade --install, manifests applied with kubectl, and a Makefile or shell script that sequences them. That approach has no action graph and no cache, but it also has no new configuration format and no plugin layer between you and the cluster. The difference in approach is where ordering lives. With Helm and kubectl, ordering is encoded in the script that calls them, and it re-runs in full every time unless you write your own guards. With Garden, ordering is encoded in dependencies: entries inside the YAML, and Garden decides what to skip. That trade is favourable when your graph is large enough that full re-runs are slow and when the same graph needs to run in two places. It is unfavourable when the graph is three actions long, because you have added a config format and a binary to maintain in exchange for skipping very little. Terraform and Pulumi users should note that Garden's own plugins for those tools mean the two can coexist rather than compete: Garden can treat a Terraform action as one node in the graph alongside Kubernetes deploys.

Licence, release cadence and what upgrading costs

Garden is licensed under MPL-2.0, the Mozilla Public License 2.0. MPL-2.0 is a file-level copyleft licence: modifications to files that are part of the covered source must be made available under the same licence, while larger works that combine Garden with separate files can be distributed under other terms. That matters if you fork the CLI or ship a patched binary internally. It does not restrict writing garden.yml files or plugins that call the binary, though the plugin interface itself is part of the covered code. This is a description of the licence text, not legal advice; get counsel if you plan to redistribute a modified Garden. On cadence, the supplied release list shows 0.13.65 dated 2026-08-24, 0.13.64 dated 2026-06-11, and an edge-bonsai tag dated 2023-02-01. The README's example links point at a 0.14.20 tree, so the documentation and the 0.13.x release line are not obviously in step, and the version you install should be checked against the docs you read. The upgrade cost is concentrated in the plugin boundary described above: a minor-version bump can change Deploy behaviour for a config you did not touch, so pinning the binary version in CI and reading the release notes before moving is the practical discipline.

Who this fits, and the first three things to check

Garden fits teams with a multi-service Kubernetes stack, an existing CI pipeline, and a genuine desire to stop maintaining separate dev and CI tooling. It fits less well if you need a managed control plane rather than a binary you run yourself; the README advertises Garden Cloud as a separate product at app.garden.io but says nothing about what it adds or what it costs, so that decision cannot be made from this material. It does not fit a team whose deployment is a handful of static manifests, because the action graph has nothing to order. The first thing to verify is connectivity: whether the Kubernetes plugin can reach your cluster context from both a laptop and a CI runner. The second is environment isolation, by running garden deploy --env preview and confirming you get the namespace separation you assume. The third is the cache, specifically where it is stored and how to clear it, since the README documents that caching exists and tracks changes but not how to reset it when a stale result is the reason a test passes.

Editorial conclusion

Adopt Garden if your team already runs Kubernetes and you want the same garden.yml to drive both a developer's inner loop and the CI pipeline, with Build, Deploy and Test actions wired by explicit dependencies. Do not adopt it if your deployment surface is a handful of manifests that kubectl apply handles, or if you need a hosted control plane and cannot run the Garden Core binary yourself. Before committing, verify three things in your own cluster: that the Kubernetes plugin can reach your context, that garden deploy --env preview produces the isolated namespace you expect, and that your CI runner has the credentials to push the images your Build actions produce.

Official sources

  1. garden-io/garden on GitHub
  2. License: MPL-2.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes