# torloejborg/easykube architecture

> Architecture diagram of the GitHub repository torloejborg/easykube, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-17). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/torloejborg/easykube
- Repository: https://github.com/torloejborg/easykube

## Overview

1. **What this repo is**
   - Easykube is a Go CLI for creating and managing a local Kubernetes development environment.
   - It combines a **Kind-based cluster**, a **Zot pull-through registry**, and an **addon system** that lets users compose stacks of Kubernetes app logic.

2. **Primary entrypoint and CLI surface**
   - `main.go` and `cmd/root.go` define the binary and command tree.
   - The subcommands in `cmd/` are the user-facing operations: `boot`, `start`, `stop`, `destroy`, `add`, `remove`, `list`, `status`, `config`, `skaffold`, and `version`.
   - This is a classic CLI boundary: command parsing stays at the edge, while orchestration and domain logic live below it.

3. **Orchestration layer**
   - `pkg/core` is the central coordination layer.
   - It models the repository’s domain concepts: **addons**, **stacks**, **task execution**, and **dependency resolution**.
   - This is where the project decides *what* to do with a cluster or addon, without directly embedding tool-specific details.

4. **Addon model and dependency graph**
   - Addons appear to be the core unit of composition.
   - `pkg/core/dependency_resolver.go`, `pkg/core/addon.go`, and `pkg/core/stack.go` suggest addons can depend on one another, form stacks, and be executed in dependency order.
   - The `test_addons/` fixtures include circular, diamond, and broken dependency cases, showing that dependency correctness is an important architectural concern.

5. **Scripted addon execution boundary**
   - `pkg/js` is the execution/runtime boundary for addon behavior.
   - Easykube uses **Goja** to run JavaScript addon scripts, exposing a curated API such as Helm, Kustomize, Kubernetes operations, environment access, Git checkout, HTTP, skopeo, image preloading, secret creation, deployment waiting, and process execution.
   - This means addon authors write behavior in JS, while Go provides the host runtime and safe integration points.

6. **External tool abstraction**
   - `pkg/ez` is a helper/integration layer around local and cluster-facing tooling.
   - It contains wrappers for Kubernetes utilities, container runtime detection, skaffold handling, OS/version detection, and cluster/config helpers.
   - Architecturally, this is the “tooling adapter” layer that isolates the rest of the code from direct dependence on binaries like `docker`, `kubectl`, `helm`, `kustomize`, and `skaffold`.

7. **Bootstrap and cluster lifecycle**
   - The `boot` command is the most infrastructure-heavy flow.
   - README indicates it creates a **Kind cluster** named `easykube-kind` and a companion **Zot registry** configured as a pull-through cache.
   - The cluster lifecycle commands (`boot`, `start`, `stop`, `destroy`, `status`) are distinct from addon operations, but both converge on the same underlying environment/config state.

8. **Configuration and persistent state**
   - `cmd/config*` and `pkg/ez/config_utils.go` handle generation, editing, and use of configuration.
   - The repo intentionally keeps its own config separate from the user’s existing kubeconfig, using a dedicated config directory under `~/.config/easykube` and a separate kubeconfig under `~/.kube/easykube`.
   - This separation is an important boundary for diagrams: Easykube owns its own state and does not directly mutate the user’s primary Kubernetes context.

9. **Templates and bundled runtime assets**
   - `pkg/resources/data/` contains the static assets that bootstrap the environment: cluster/config templates, Coredns data, certs, skaffold manifests, and Zot config templates.
   - These assets are embedded into the binary and then materialized into files or cluster resources during setup.
   - The repo therefore has a “compiled-in defaults” architecture rather than relying entirely on external config files.

10. **Certificates and local HTTPS support**
   - `cert/` and `pkg/resources/data/cert/` contain a local CA and generated cert material used for secure local access.
   - The certificate subsystem supports the local development story, especially because many addons expect HTTPS and registry access.
   - In diagrams, this is part of the bootstrap infrastructure, not a standalone application feature.

11. **Skaffold and application deployment path**
   - The `skaffold` command and the `pkg/resources/data/skaffold/` bundle indicate a dedicated path for deploying/managing app workloads using Skaffold alongside Kustomize manifests.
   - This is likely the bridge from addon definitions to running application resources in the cluster.
   - The presence of `pkg/js/ek_skaffold.go` and related JS helpers suggests addon scripts can trigger deployment workflows rather than only declaratively defining them.

12. **Testing and verification**
   - Tests are split across helper-layer tests (`pkg/ez`, `pkg/js`) and fixture-based addon tests (`test_addons/`).
   - There is also a `mock/` package for interface-based mocking, suggesting core orchestration depends on abstractions rather than hard-coded binaries.
   - CI includes Go tests and CodeQL, reinforcing that the repo’s correctness depends heavily on dependency resolution, scripting runtime behavior, and tool integration.

13. **External dependencies and runtime assumptions**
   - The runtime assumes the presence of local developer tools: Docker or Podman, Kind via Docker, Kubernetes clients, Helm, Kustomize, and optionally Skaffold.
   - External services may be mirrored locally through Zot, and private registries can be configured in the Easykube config.
   - Easykube is therefore not a hosted service; it is a local orchestration tool that stitches together local binaries, local cluster state, and addon scripts.

14. **High-level data flow**
   - User command enters `cmd/` → command logic calls `pkg/core` orchestration → `pkg/ez` resolves local tooling/config/cluster details → `pkg/js` executes addon scripts → scripts call back into Kubernetes/tool helpers → external binaries and the Kind/Zot/Kubernetes environment perform the actual work.
   - The main architectural boundary is between **CLI/orchestration code** and the **external local dev environment** it controls.

Main entry points: [`pkg/core/task_manager.go`](https://github.com/torloejborg/easykube/blob/main/pkg/core/task_manager.go) (Task manager), [`cmd/root.go`](https://github.com/torloejborg/easykube/blob/main/cmd/root.go) (Root cmd), [`pkg/js/ek_helm.go`](https://github.com/torloejborg/easykube/blob/main/pkg/js/ek_helm.go) (Addon ops), [`pkg/ez/cluster_utils.go`](https://github.com/torloejborg/easykube/blob/main/pkg/ez/cluster_utils.go) (Cluster utils)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_grp_cli["CLI"]
  node_main["main.go<br/>entrypoint<br/>[main.go]"]
  node_cmd_root["Root cmd<br/>cobra root<br/>[root.go]"]
  node_cmd_cluster["Cluster cmds<br/>lifecycle commands<br/>[boot.go]"]
  node_cmd_addons["Addon cmds<br/>addon commands<br/>[add.go]"]
  node_cmd_skaffold["Skaffold cmd<br/>deployment command<br/>[skaffold.go]"]
  node_cmd_version["Version cmd<br/>info command<br/>[version.go]"]
end

subgraph group_grp_core["Core"]
  node_core_addon["Addon model<br/>domain model<br/>[addon.go]"]
  node_core_stack["Stacks<br/>composition model<br/>[stack.go]"]
  node_core_deps{{"Resolver<br/>dependency graph"}}
  node_core_tasks["Task manager<br/>orchestration engine<br/>[task_manager.go]"]
  node_core_interfaces["Core APIs<br/>abstractions<br/>[interfaces.go]"]
end

subgraph group_grp_runtime["Runtime"]
  node_js_runner["JS runner<br/>script runtime<br/>[jsrunner.go]"]
  node_js_easykube["Host API<br/>js bindings<br/>[easykube.go]"]
  node_js_apis{{"Addon ops<br/>js integrations<br/>[ek_helm.go]"}}
end

subgraph group_grp_tools["Tooling"]
  node_ez_config["Config<br/>[config_utils.go]"]
  node_ez_cluster["Cluster utils<br/>cluster adapter<br/>[cluster_utils.go]"]
  node_ez_k8s["K8s utils<br/>kubernetes adapter<br/>[k8s_utils.go]"]
  node_ez_runtime["Runtime tools<br/>tool adapter"]
  node_ez_status["Status builder<br/>presentation adapter<br/>[status_builder.go]"]
end

subgraph group_grp_assets["Assets"]
  node_res_data["Bundled data<br/>embedded assets"]
  node_res_skaffold["Skaffold assets<br/>embedded manifests<br/>[ek.js]"]
  node_res_cert["Cert assets<br/>embedded certs<br/>[localtest.me.crt]"]
end

subgraph group_grp_tests["Fixtures"]
  node_fx_dep["Dep fixtures<br/>addon fixtures<br/>[a.ek.js]"]
  node_fx_exec["Exec fixtures<br/>addon fixtures<br/>[a.ek.js]"]
end

node_main -->|"starts"| node_cmd_root
node_cmd_root -->|"wires"| node_cmd_cluster
node_cmd_root -->|"wires"| node_cmd_addons
node_cmd_root -->|"wires"| node_cmd_skaffold
node_cmd_root -->|"wires"| node_cmd_version
node_cmd_cluster -->|"calls"| node_core_tasks
node_cmd_addons -->|"calls"| node_core_tasks
node_cmd_skaffold -->|"uses"| node_ez_runtime
node_core_tasks -->|"operates on"| node_core_addon
node_core_tasks -->|"organizes"| node_core_stack
node_core_tasks -->|"orders"| node_core_deps
node_core_tasks -->|"depends on"| node_core_interfaces
node_core_deps -->|"analyzes"| node_core_addon
node_core_stack -->|"contains"| node_core_addon
node_core_addon -->|"executes in"| node_js_runner
node_js_runner -->|"exposes"| node_js_easykube
node_js_easykube -->|"binds"| node_js_apis
node_js_apis -->|"uses"| node_ez_k8s
node_js_apis -->|"uses"| node_ez_cluster
node_js_apis -->|"uses"| node_ez_runtime
node_ez_cluster -->|"reads"| node_ez_config
node_ez_k8s -->|"reads"| node_ez_config
node_ez_runtime -->|"reads"| node_ez_config
node_ez_status -->|"summarizes"| node_ez_cluster
node_ez_status -->|"summarizes"| node_ez_k8s
node_ez_config -->|"materializes"| node_res_data
node_ez_cluster -->|"uses"| node_res_data
node_res_data -->|"includes"| node_res_skaffold
node_res_data -->|"includes"| node_res_cert
node_fx_dep -.->|"verifies"| node_core_deps
node_fx_exec -.->|"verifies"| node_js_runner

click node_main "https://github.com/torloejborg/easykube/blob/main/main.go"
click node_cmd_root "https://github.com/torloejborg/easykube/blob/main/cmd/root.go"
click node_cmd_cluster "https://github.com/torloejborg/easykube/blob/main/cmd/boot.go"
click node_cmd_addons "https://github.com/torloejborg/easykube/blob/main/cmd/add.go"
click node_cmd_skaffold "https://github.com/torloejborg/easykube/blob/main/cmd/skaffold.go"
click node_cmd_version "https://github.com/torloejborg/easykube/blob/main/cmd/version.go"
click node_core_addon "https://github.com/torloejborg/easykube/blob/main/pkg/core/addon.go"
click node_core_stack "https://github.com/torloejborg/easykube/blob/main/pkg/core/stack.go"
click node_core_deps "https://github.com/torloejborg/easykube/blob/main/pkg/core/dependency_resolver.go"
click node_core_tasks "https://github.com/torloejborg/easykube/blob/main/pkg/core/task_manager.go"
click node_core_interfaces "https://github.com/torloejborg/easykube/blob/main/pkg/core/interfaces.go"
click node_js_runner "https://github.com/torloejborg/easykube/blob/main/pkg/js/jsrunner.go"
click node_js_easykube "https://github.com/torloejborg/easykube/blob/main/pkg/js/easykube.go"
click node_js_apis "https://github.com/torloejborg/easykube/blob/main/pkg/js/ek_helm.go"
click node_ez_config "https://github.com/torloejborg/easykube/blob/main/pkg/ez/config_utils.go"
click node_ez_cluster "https://github.com/torloejborg/easykube/blob/main/pkg/ez/cluster_utils.go"
click node_ez_k8s "https://github.com/torloejborg/easykube/blob/main/pkg/ez/k8s_utils.go"
click node_ez_runtime "https://github.com/torloejborg/easykube/blob/main/pkg/ez/container_runtime.go"
click node_ez_status "https://github.com/torloejborg/easykube/blob/main/pkg/ez/status_builder.go"
click node_res_data "https://github.com/torloejborg/easykube/tree/main/pkg/resources/data"
click node_res_skaffold "https://github.com/torloejborg/easykube/blob/main/pkg/resources/data/skaffold/ek.js"
click node_res_cert "https://github.com/torloejborg/easykube/blob/main/pkg/resources/data/cert/localtest.me.crt"
click node_fx_dep "https://github.com/torloejborg/easykube/blob/main/test_addons/diamond/a/a.ek.js"
click node_fx_exec "https://github.com/torloejborg/easykube/blob/main/test_addons/exec/a/a.ek.js"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_main,node_cmd_root,node_cmd_cluster,node_cmd_addons,node_cmd_skaffold,node_cmd_version toneBlue
class node_core_addon,node_core_stack,node_core_deps,node_core_tasks,node_core_interfaces toneAmber
class node_js_runner,node_js_easykube,node_js_apis toneMint
class node_ez_config,node_ez_cluster,node_ez_k8s,node_ez_runtime,node_ez_status toneRose
class node_res_data,node_res_skaffold,node_res_cert toneIndigo
class node_fx_dep,node_fx_exec toneTeal
```

## Components

### CLI

User-facing command tree and binary entrypoints.

- [main.go](https://github.com/torloejborg/easykube/blob/main/main.go): entrypoint · Binary entrypoint that hands off into the command tree. · `main.go`
- [Root cmd](https://github.com/torloejborg/easykube/blob/main/cmd/root.go): cobra root · Top-level command wiring and shared CLI setup. · `cmd/root.go`
- [Cluster cmds](https://github.com/torloejborg/easykube/blob/main/cmd/boot.go): lifecycle commands · Boot, start, stop, destroy, status commands for managing the local Kubernetes environment. · `cmd/boot.go`
- [Addon cmds](https://github.com/torloejborg/easykube/blob/main/cmd/add.go): addon commands · Add, remove, list, and config operations for addon composition. · `cmd/add.go`
- [Skaffold cmd](https://github.com/torloejborg/easykube/blob/main/cmd/skaffold.go): deployment command · CLI surface for skaffold-driven workload management. · `cmd/skaffold.go`
- [Version cmd](https://github.com/torloejborg/easykube/blob/main/cmd/version.go): info command · Prints binary and environment version information. · `cmd/version.go`

### Core

Orchestration, addon model, dependency resolution, and task execution.

- [Addon model](https://github.com/torloejborg/easykube/blob/main/pkg/core/addon.go): domain model · Represents an addon as a unit of composition and execution. · `pkg/core/addon.go`
- [Stacks](https://github.com/torloejborg/easykube/blob/main/pkg/core/stack.go): composition model · Groups addons into ordered stacks for coordinated execution. · `pkg/core/stack.go`
- [Resolver](https://github.com/torloejborg/easykube/blob/main/pkg/core/dependency_resolver.go): dependency graph · Resolves addon dependencies and execution order, including cycle handling. · `pkg/core/dependency_resolver.go`
- [Task manager](https://github.com/torloejborg/easykube/blob/main/pkg/core/task_manager.go): orchestration engine · Runs coordinated operations across addons and cluster actions. · `pkg/core/task_manager.go`
- [Core APIs](https://github.com/torloejborg/easykube/blob/main/pkg/core/interfaces.go): abstractions · Shared interfaces used to decouple orchestration from concrete tooling. · `pkg/core/interfaces.go`

### Runtime

JavaScript addon execution and host API surface.

- [JS runner](https://github.com/torloejborg/easykube/blob/main/pkg/js/jsrunner.go): script runtime · Executes addon scripts through Goja and bridges host APIs into JavaScript. · `pkg/js/jsrunner.go`
- [Host API](https://github.com/torloejborg/easykube/blob/main/pkg/js/easykube.go): js bindings · Exports the Easykube JS surface and shared script helpers. · `pkg/js/easykube.go`
- [Addon ops](https://github.com/torloejborg/easykube/blob/main/pkg/js/ek_helm.go): js integrations · Representative JS helpers for Helm, Kustomize, Git, HTTP, secrets, image preload, and process/deployment actions. · `pkg/js/ek_helm.go`

### Tooling

Adapters around Kubernetes, cluster, and local developer tools.

- [Config](https://github.com/torloejborg/easykube/blob/main/pkg/ez/config_utils.go): config/state · Owns Easykube configuration, paths, and persistent environment state. · `pkg/ez/config_utils.go`
- [Cluster utils](https://github.com/torloejborg/easykube/blob/main/pkg/ez/cluster_utils.go): cluster adapter · Wraps Kind, kubeconfig, and cluster lifecycle helpers. · `pkg/ez/cluster_utils.go`
- [K8s utils](https://github.com/torloejborg/easykube/blob/main/pkg/ez/k8s_utils.go): kubernetes adapter · Helpers for Kubernetes client operations and cluster-facing actions. · `pkg/ez/k8s_utils.go`
- [Runtime tools](https://github.com/torloejborg/easykube/blob/main/pkg/ez/container_runtime.go): tool adapter · Detects container runtime, OS details, skaffold availability, and external binary behavior. · `pkg/ez/container_runtime.go`
- [Status builder](https://github.com/torloejborg/easykube/blob/main/pkg/ez/status_builder.go): presentation adapter · Builds status views from cluster and addon state. · `pkg/ez/status_builder.go`

### Assets

Embedded templates, manifests, certificates, and bundled runtime data.

- [Bundled data](https://github.com/torloejborg/easykube/tree/main/pkg/resources/data): embedded assets · Embedded templates and manifests for cluster config, DNS, certificates, skaffold, and Zot. · `pkg/resources/data`
- [Skaffold assets](https://github.com/torloejborg/easykube/blob/main/pkg/resources/data/skaffold/ek.js): embedded manifests · Bundled skaffold manifest set used to deploy example workloads. · `pkg/resources/data/skaffold/ek.js`
- [Cert assets](https://github.com/torloejborg/easykube/blob/main/pkg/resources/data/cert/localtest.me.crt): embedded certs · Local CA and certificate material for HTTPS-enabled local development. · `pkg/resources/data/cert/localtest.me.crt`

### Fixtures

Representative addon fixtures used to verify dependency and execution behavior.

- [Dep fixtures](https://github.com/torloejborg/easykube/blob/main/test_addons/diamond/a/a.ek.js): addon fixtures · Fixture addon graphs for dependency validation, including diamond and circular cases. · `test_addons/diamond/a/a.ek.js`
- [Exec fixtures](https://github.com/torloejborg/easykube/blob/main/test_addons/exec/a/a.ek.js): addon fixtures · Fixture addons that exercise execution, manifests, and port configuration behavior. · `test_addons/exec/a/a.ek.js`

## Connections

- main.go → Root cmd: starts · The binary initializes the root command tree.
- Root cmd → Cluster cmds: wires · Root command exposes cluster lifecycle subcommands.
- Root cmd → Addon cmds: wires · Root command exposes addon composition subcommands.
- Root cmd → Skaffold cmd: wires · Root command exposes skaffold-specific operations.
- Root cmd → Version cmd: wires · Root command exposes version reporting.
- Cluster cmds → Task manager: calls · Cluster operations delegate into orchestration.
- Addon cmds → Task manager: calls · Addon operations delegate into orchestration.
- Skaffold cmd → Runtime tools: uses · Skaffold command depends on external tool detection and execution helpers.
- Task manager → Addon model: operates on · Task execution is centered on addon units.
- Task manager → Stacks: organizes · Tasks work across addon stacks.
- Task manager → Resolver: orders · Dependency resolution determines execution sequence.
- Task manager → Core APIs: depends on · Task orchestration is abstracted through interfaces.
- Resolver → Addon model: analyzes · The resolver inspects addon dependency metadata.
- Stacks → Addon model: contains · Stacks are composed from addons.
- Addon model → JS runner: executes in · Addon behavior is implemented as JS scripts.
- JS runner → Host API: exposes · The runtime publishes the Easykube host API to scripts.
- Host API → Addon ops: binds · Host API includes integrations for cluster and tooling actions.
- Addon ops → K8s utils: uses · JS helpers call into Kubernetes utilities.
- Addon ops → Cluster utils: uses · JS helpers rely on cluster lifecycle and environment helpers.
- Addon ops → Runtime tools: uses · JS helpers can invoke local tools and runtime-dependent operations.
- Cluster utils → Config: reads · Cluster lifecycle is driven by Easykube configuration and state.
- K8s utils → Config: reads · Kubernetes helpers use Easykube config and paths.
- Runtime tools → Config: reads · Runtime/tool detection depends on configuration and environment state.
- Status builder → Cluster utils: summarizes · Status views are built from cluster lifecycle state.
- Status builder → K8s utils: summarizes · Status views incorporate Kubernetes resource state.
- Config → Bundled data: materializes · Configuration and bootstrap state are generated from embedded templates.
- Cluster utils → Bundled data: uses · Cluster bootstrap relies on embedded cluster and Zot assets.
- Bundled data → Skaffold assets: includes · Bundled runtime data includes skaffold manifests and script entrypoints.
- Bundled data → Cert assets: includes · Bundled runtime data includes local certificate material.
- Dep fixtures → Resolver: verifies · Dependency fixtures exercise ordering and cycle resolution.
- Exec fixtures → JS runner: verifies · Execution fixtures exercise JS addon runtime behavior.
