Devtools

The curated install recipes a workstation can declare: what each one installs, its version behaviour, and its configuration blob.

devtools is the install channel of a Workstation or a WorkstationConfig. Each entry names a curated recipe that the in-VM agent runs to put a tool on the workstation. Unlike packages (a flat name handed to the system package manager), a devtool encapsulates whatever the tool actually needs: an upstream repository and signing key, a static binary download, a global npm install, a systemd unit, a shell-integration snippet, or a running Kubernetes cluster.

devtools:
  - name: docker
  - name: nodejs
    version: "24"
  - name: playwright
    config:
      browsers: [chromium, firefox]

Each entry accepts exactly three keys — a typo in any other key is rejected:

FieldTypeDescription
namestringThe recipe name. Must be one of the recipes below; an unknown name fails setup.
versionstringOptional version. What it means is recipe-specific (see each page); omit it for the recipe’s default.
configobjectOptional opaque blob, interpreted only by a config-aware recipe. Today that is kind and playwright.

The recipes

Languages and toolchains

  • go — the Go toolchain, pinned from upstream or from the distribution.
  • golangci-lint — the Go linter, installed with the Go toolchain.
  • nodejs — Node.js and npm, distribution or a pinned major.

Containers and Kubernetes

  • docker — engine, CLI, Compose v2, and buildx.
  • kind — the kind binary, and optionally a whole cluster with ingress and a load balancer.
  • kubectl — the Kubernetes CLI.
  • helm — Helm 3.
  • kubectx — fast context switching.
  • kubens — fast namespace switching.

AI coding tools and editors

  • claude-code — the Claude Code CLI.
  • codex — the Codex CLI.
  • vscode-web — the code-server browser IDE, autostarted, with the Claude Code extension.

Cloud CLIs

  • gcloud — the Google Cloud CLI.
  • aws — the AWS CLI v2.
  • az — the Azure CLI.

Version control

  • git — git itself.
  • gh — the GitHub CLI.

Testing and shell

  • playwright — the Playwright CLI plus browser engines and their OS dependencies.
  • fzf — the fuzzy finder, wired into login shells.

Host integration

How devtools behave

They install in declared order. A recipe that depends on another tool ensures it itself (claude-code will install Node.js if it is missing), but declaring the dependency first makes the order explicit and lets you pin its version.

They are deduplicated by name across layers, last-wins on the whole entry. If a workstation and two configs all declare nodejs, one nodejs install happens, using the entry from the highest-priority layer — including its version and config. Position in the merged list follows where the name was first seen.

They install after packages and before files, sources, scripts, and services. So a provisioning script can assume docker compose or go build works the very first time the workstation sets itself up.

They are gated on the workstation’s real state, not just bookkeeping. Before running a recipe the agent probes whether the tool is genuinely present (for docker, that includes docker compose and docker buildx; for a configured kind, that the cluster still exists). A tool removed out-of-band is reinstalled the next time the workstation applies its configuration, and an already-installed tool is a fast no-op.

Changing version or config re-runs the recipe. The entry’s identity folds its version and its config blob, so editing either makes the next setup run apply it.

An unknown name is a loud failure. A typo does not silently no-op; the workstation reports the failing step and stays Configured: False.

Devtools versus tool configuration

A devtool installs software. A toolconfig configures software that is already installed — it writes the tool’s dotfiles on every setup run and installs nothing. Several names appear in both channels (claude-code, codex, vscode-web, git, gh) and are meant to be used together:

devtools:
  - name: git                    # install git
toolconfigs:
  - name: git                    # give it an identity
    config:
      userName: Ada Lovelace
      userEmail: ada@example.com

Distribution support

Every recipe supports Debian and Ubuntu. Most also work on Alpine, using apk packages. Three do not and fail with a clear message on a musl workstation: gcloud, aws, and az. Each page states its support.

Downloads always resolve the workstation’s architecture (amd64 or arm64) at install time, so the same manifest works on an x86 cloud VM and an Apple-Silicon local VM.