Back to Blog
Garden.io: The Kubernetes Developer Experience I've Been Waiting For
6 min readJun 29, 20261 views

Garden.io: The Kubernetes Developer Experience I've Been Waiting For

Kubernetes is powerful, but its local development story has always been a mess. Garden.io promises to fix that by streamlining builds, deployments, and testing into a unified workflow, making K8s development feel less like a chore.

ToolingFull-StackAutomationSoftware DesignKubernetes
Share

by Sunil Band

Kubernetes Local Development Sucks. There, I Said It.

Kubernetes has become the de facto operating system for cloud-native applications, and for good reason. It offers incredible power, resilience, and scalability. But let's be honest: for all its benefits in production, local development with Kubernetes is often a slow, frustrating mess. You spend more time wrestling with YAML, waiting for image builds, and trying to replicate a "production-like" environment than you do actually coding.

I've seen countless teams try to paper over these issues. Minikube, Docker Desktop with K8s enabled, Skaffold, Telepresence – they all help to varying degrees, but none felt like a cohesive, end-to-end solution. The mental overhead of switching between docker build, kubectl apply, helm install, and local test runners is a significant drag on developer velocity. It's a problem I've grappled with on almost every project that adopted K8s, and frankly, I was getting tired of it.

This is why Garden.io caught my eye. It's not just another tool to add to the sprawling K8s ecosystem; it aims to be the orchestrator for your entire development workflow, from code changes to local testing to CI. It promises a unified approach to building, deploying, and testing your services across different environments, all while leveraging shared caching to drastically speed things up. That's a bold claim, and one I immediately wanted to investigate.

The Core Problem: Environmental Drift and Slow Feedback Loops

The biggest pain point in Kubernetes development, in my opinion, is the constant battle against environmental drift. What works on your machine often breaks in a shared dev cluster, or worse, in CI. The traditional approach involves manually building Docker images, pushing them to a registry, updating K8s manifests, and then waiting for your changes to propagate. This cycle is agonizingly slow, especially when you're iterating rapidly on a new feature or debugging a complex interaction between services.

Compounding this is the lack of a consistent way to run tests. Unit tests are local, integration tests might hit a local K8s cluster, and end-to-end tests often require a full deployment. Each stage has its own setup, its own configuration, and its own set of scripts. This fragmentation makes it hard to maintain a high level of confidence in your changes, and even harder to onboard new developers.

Garden.io tackles this by introducing a declarative configuration language that describes your entire project – services, dependencies, tests, and deployments – in a single source of truth. It then uses this definition to orchestrate everything, intelligently rebuilding and redeploying only what's necessary, and crucially, doing it in a consistent manner across local, CI, and even preview environments.

How Garden.io Aims to Solve It: A Unified Workflow

At its heart, Garden.io uses a project-level configuration that defines your modules. A module can be anything from a microservice, a database, a frontend application, or even a test suite. Each module specifies its build steps (e.g., Dockerfile, npm build), its dependencies on other modules, and how it should be deployed (e.g., Kubernetes Deployment, Helm Chart).

Let's consider a simple scenario: a backend API written in Go and a frontend application built with Next.js, both deployed to Kubernetes. Without Garden, you'd have separate Dockerfiles, separate kubectl commands, and separate test runners. With Garden, you define them as modules:

yaml
# garden.yml - Top-level Garden project configuration
project:
  name: my-fullstack-app
  environments:
    dev:
      kubernetes: {}
      values:
        api_replica_count: 1
        web_replica_count: 1
    ci:
      kubernetes:
        # Connect to your CI's K8s cluster
        context: my-ci-cluster
      values:
        api_replica_count: 2
        web_replica_count: 2

# modules/api/garden.yml
modules:
  - name: api
    type: container
    source: .
    build:
      dockerfile: Dockerfile
      context: .
    deploy:
      kubernetes:
        # Reference a Helm chart or raw K8s manifests
        manifests:
          - deployment.yaml
          - service.yaml
        # Garden can automatically inject image tags into your manifests
        replace: 
          image: '{{ .module.image }}'
    dependencies:
      - module: database # Assuming a 'database' module is also defined

# modules/web/garden.yml
modules:
  - name: web
    type: container
    source: .
    build:
      dockerfile: Dockerfile
      context: .
      target: production
      # Automatically run `npm install` and `npm build` inside the container
      commands:
        - npm install
        - npm run build
    deploy:
      kubernetes:
        manifests:
          - deployment.yaml
          - service.yaml
        replace:
          image: '{{ .module.image }}'
    dependencies:
      - module: api # Frontend depends on the backend API

# modules/api/tests/garden.yml
modules:
  - name: api-integration-tests
    type: container # Run tests in a dedicated container
    source: .
    build:
      dockerfile: Dockerfile.tests
      context: .
    test:
      command: go test ./...
      dependencies:
        - module: api # Tests depend on the API being deployed
        - module: database

With this setup, running garden deploy dev would build your api and web images (and database if defined), push them (if configured), and then apply the Kubernetes manifests to your local dev environment. When you make a code change in the api directory, Garden detects it, rebuilds only the api module, and redeploys it. It's smart enough to know that the web module doesn't need to be touched. This intelligent dependency graph and caching is where the real speedup comes from.

The Dev Loop: garden deploy and garden dev-up

The two primary commands you'll use are garden deploy <environment> and garden dev-up <environment>. garden deploy is for one-off deployments, building everything from scratch if necessary. garden dev-up is where the magic for local iteration happens. It starts a continuous development loop:

  1. Watches for file changes: As soon as you save a file in a module, Garden detects it.
  2. Intelligent rebuild: It rebuilds only the affected module and its dependents, leveraging a powerful build cache.
  3. Hot reloading/re-deployment: It re-deploys the updated services to your target K8s cluster (local or remote). For local development, this is often configured to use kubectl port-forward or similar to expose services.
  4. Test execution: It can optionally run associated tests after a successful deployment, providing immediate feedback.

This workflow radically shortens the feedback loop. Instead of waiting minutes for a full image build and deployment, you can often see changes reflected in seconds, especially with a warm cache. It's like having nodemon or Webpack's hot reloading for your entire microservices architecture.

The Secret Sauce: Caching and Consistency

Garden's caching mechanism is a huge differentiator. It hashes your module's source code, Dockerfile, and dependencies. If nothing relevant has changed, it reuses the previous build artifact. This applies not just to image builds but also to deployments and test results. This dramatically speeds up CI pipelines and ensures that developers aren't wasting time rebuilding things that haven't changed.

The consistency comes from using the same garden.yml definitions for every environment. Your local dev environment, a shared staging cluster, and your CI pipeline all use the identical blueprint. This minimizes the

More from the blog
Available for projectsReady to make something fun 🎈

Ready to build the next system?Wanna build something awesome together?

Currently accepting high-impact opportunities in frontend engineering and scalable web applications.Got a cool idea rattling around? Let's grab a virtual coffee and turn it into something people love. ☕