Build-Time / DevOps DSLs Family Index
type: language-family-index family: build-devops languages_catalogued: 32 tags: [language-reference, family-index, build, devops, ci-cd, kubernetes, deployment]
Build-Time / DevOps DSLs — Family Index
Family overview
Build-time and DevOps DSLs cover the long tail of “languages no one calls a language but everyone writes” — the files that decide what gets built, in what order, in which container, and on which cluster. They form a layered spectrum. At the bottom sit file-target build tools (Make, Ninja, SCons) whose mental model is “given source file X, produce target Y, here’s the recipe.” Above them are the hermetic monorepo build systems (Bazel, Buck2, Pants, Please) — content-addressed, parallel, remote-cacheable engines that demand strict dependency declarations in exchange for sub-second incremental rebuilds across thousands of targets. In a separate cluster are task runners (Just, Task, Mage, doit, Rake, Cake, FAKE) — modern Make-replacements whose job is not to track file dependencies but to give engineers a discoverable, ergonomic CLI of named commands. Above all of those, containerized pipeline-as-code (Earthly, Dagger, Tilt) lifts the entire build into a reproducible container graph, and CI YAML (GitHub Actions, GitLab CI, CircleCI, Jenkins, Argo, Tekton) wires the whole machine into a triggered workflow. Crowning the stack are K8s manifest DSLs (Helm, Kustomize, Skaffold) and multi-cloud provisioning (CDK, Pulumi) that turn application packaging into a declarative artifact.
The recurring tension across the whole family is expressiveness vs. determinism. Bazel’s Starlark is deliberately a non-Turing-complete Python subset — no while, no recursion, no I/O — because the build engine needs to evaluate millions of rules deterministically and cache the results. CI YAML went the opposite way: pure declarative configuration that’s trivially parseable but rapidly unreadable once it grows past two screens of conditionals and matrix expansions. Helm’s Go-template-over-YAML is the worst-of-both-worlds outcome of that path — whitespace-fragile templating producing whitespace-significant YAML — and it’s the de facto K8s packaging format anyway.
The 2020s answer to YAML fatigue has been “use a real language.” Pulumi (2018) launched the wave for IaC, AWS CDK (2019) brought it to CloudFormation, CDK8s (2020) to Kubernetes manifests, and Dagger (2022) extended it to CI pipelines themselves — write your build/test/deploy graph in Go, Python, TypeScript, or Java, get type-checking, IDE completion, and unit tests for free. Earthly took the middle path: a DSL deliberately shaped like a hybrid of Make and Dockerfile, because containers turned out to be the lingua franca everyone agreed on. Whether the “real language” thesis kills YAML in CI the way HCL killed YAML in IaC is still open in 2026; GitHub Actions YAML’s network effect is enormous.
In our deep library
None of the tools in this family have dedicated deep notes — they’re build/DevOps DSLs rather than general-purpose languages. Cross-reference these:
- config-and-dsl — already catalogues CMake, Make, Ninja, Meson, Bazel, Buck2, SCons, Earthly, Helm, Kustomize, HCL, Pulumi, Starlark, Nix, Dhall. This index extends that work in the workflow / pipeline / CI direction; treat the two as complementary.
- groovy — Jenkinsfile and Gradle are Groovy-hosted DSLs.
- ruby — Rake is a Ruby internal DSL; Chef recipes too.
- python — SCons, Pants, doit, Meson all use Python or Python-flavored frontends.
- fsharp — FAKE (“F# Make”) is an F# build DSL.
- csharp — Cake (“C# Make”) and AWS CDK / Pulumi .NET targets.
- go — Mage, Task, Dagger Go SDK, Pulumi Go, CDK Go, Buildkit, Helm itself, Tekton.
- rust — Just is Rust-implemented; Buck2 is Rust-rewritten.
- typescript — AWS CDK, Pulumi, Dagger TS SDK, CDK8s.
Tier 3 family table
| Tool / DSL | First appeared | Language family | Domain | Status (2026) | URL |
|---|---|---|---|---|---|
| GNU Make | 1988 (Make: 1976) | Make-family DSL (tabs + macros + shell) | File-target build, universal orchestrator | Universal, immortal | https://www.gnu.org/software/make/manual/ |
| BSD make | 1980s | Make-family DSL (different macro/conditional syntax) | BSD / pkgsrc builds | Active in BSDs | https://man.freebsd.org/cgi/man.cgi?make(1) |
| NMAKE | 1987 | Make-family DSL (Microsoft variant) | MSVC builds, Win32 SDK | Mature, declining | https://learn.microsoft.com/en-us/cpp/build/reference/nmake-reference |
| Bazel BUILD + Starlark (.bzl) | 2015 (open-sourced from Blaze 2006) | Starlark (deterministic Python subset) | Hermetic monorepo build, remote cache + RBE | Active, dominant in its niche | https://bazel.build/ |
| Buck2 | 2023 (Buck1: 2013) | Starlark front-end, Rust DAG engine | Meta’s Bazel-class rewrite | Active | https://buck2.build/ |
| Pants 2 | 2020 (Pants 1: 2014) | Python BUILD files + Starlark-ish rules | Polyglot monorepo build (Python, Go, Java, Scala) | Active | https://www.pantsbuild.org/ |
| Please.build | 2017 | Go-implemented, BUILD files in Skylark/Starlark dialect | Bazel-flavored cross-language build | Active, niche | https://please.build/ |
| Earthly (Earthfile) | 2020 | Hybrid Make + Dockerfile DSL | Containerized portable build | Active | https://earthly.dev/ |
| Dagger SDK | 2022 | Real languages: Go / Python / TypeScript / Java / .NET | Containerized pipeline-as-code; runs on Buildkit | Active, growing | https://dagger.io/ |
| Tilt | 2018 | Starlark (Tiltfile) | K8s inner dev loop (live-reload into clusters) | Active | https://tilt.dev/ |
| Just | 2017 | Make-influenced DSL, Rust-implemented | Per-project task runner / command discovery | Active, very popular | https://just.systems/ |
| Task | 2017 | YAML (Taskfile.yml), Go-implemented | Cross-platform task runner | Active, growing | https://taskfile.dev/ |
| Mage | 2018 | Go (mage targets are Go funcs) | Go-native make replacement | Active, niche | https://magefile.org/ |
| doit | 2008 | Python (tasks are Python functions) | Build/automation in Python projects | Mature | https://pydoit.org/ |
| Rake | 2003 | Ruby internal DSL | Ruby-world build / task runner | Mature, ubiquitous in Ruby | https://ruby.github.io/rake/ |
| Cake | 2014 | C# DSL (cake script + addins) | .NET build automation | Active | https://cakebuild.net/ |
| FAKE | 2009 | F# DSL (“F# Make”) | .NET build automation, F# flavor | Active, niche | https://fake.build/ |
| SCons | 2000 | Python (SConstruct is a Python program) | Python-as-build-DSL | Mature | https://scons.org/ |
| Ninja | 2012 | Minimal low-level build description | Backend for CMake/Meson/gn; fastest incremental | Universal as backend | https://ninja-build.org/ |
| Meson | 2013 | Python-flavored DSL, Ninja backend | Modern meta-build (GNOME, systemd, GStreamer) | Active, growing | https://mesonbuild.com/ |
| CMake | 2000 | CMake DSL → Ninja/Make/MSBuild/Xcode | C/C++ meta-build (cross-ref config-and-dsl) | Dominant in C/C++ | https://cmake.org/cmake/help/latest/ |
| Helm chart templates | 2016 | Go templates over YAML | K8s packaging | Dominant | https://helm.sh/docs/ |
| Kustomize | 2018 | Pure YAML strategic-merge + patches | K8s overlay config | Dominant alongside Helm; built into kubectl | https://kustomize.io/ |
| Skaffold | 2018 | YAML | K8s build/push/deploy inner loop | Active | https://skaffold.dev/ |
| AWS CDK | 2019 | TS / Python / Go / Java / C# / .NET | Synthesizes CloudFormation from real code | Active, dominant in AWS shops | https://docs.aws.amazon.com/cdk/v2/guide/home.html |
| Pulumi | 2018 | TS / Python / Go / .NET / Java / YAML | Multi-cloud IaC in real languages | Active | https://www.pulumi.com/docs/ |
| Dockerfile | 2013 | Dockerfile DSL (instructions + shell) | Container image build | Universal | https://docs.docker.com/engine/reference/builder/ |
| Containerfile (Buildah/Podman) | 2017 | Dockerfile-compatible DSL | Daemonless OCI image build | Active | https://github.com/containers/common/blob/main/docs/Containerfile.5.md |
| Buildkit LLB | 2018 | Low-level Build (Go protobuf graph + frontends) | Buildkit’s IR; Dockerfile is a frontend, others possible | Universal as backend | https://github.com/moby/buildkit |
| GitHub Actions YAML | 2019 | YAML (workflows + reusable actions) | Hosted CI/CD | Dominant | https://docs.github.com/en/actions |
| GitLab CI YAML | 2015 | YAML (.gitlab-ci.yml) | GitLab-hosted CI/CD | Dominant in GitLab shops | https://docs.gitlab.com/ee/ci/yaml/ |
| Jenkinsfile | 2016 | Groovy DSL (declarative or scripted) | Self-hosted CI/CD (cross-ref groovy) | Mature, declining but huge install base | https://www.jenkins.io/doc/book/pipeline/jenkinsfile/ |
| CircleCI config YAML | 2014 | YAML (.circleci/config.yml) | Hosted CI/CD; orbs for reuse | Active | https://circleci.com/docs/configuration-reference/ |
| Argo Workflows | 2017 | YAML (K8s CRDs) | DAG / step workflow on Kubernetes | Active, CNCF graduated | https://argo-workflows.readthedocs.io/ |
| Tekton | 2019 | YAML (K8s CRDs: Task / Pipeline / PipelineRun) | K8s-native CI/CD primitives | Active, CNCF graduated | https://tekton.dev/ |
Notable threads
-
The hermetic-monorepo cluster (Bazel / Buck2 / Pants / Please). All four picked Starlark or a near-Starlark dialect because the engine needs to evaluate millions of rules deterministically and cache them by content hash. Starlark’s deliberate amputations (no
while, no recursion, no I/O, no global mutability) are the point: they let the engine treat rule evaluation as a pure function. Buck2 (Rust, 2023) is Meta’s bet that the original Buck/Bazel engine architecture was right but the implementation could be 5–10x faster; Pants 2 (2020) is the rewrite that made the design palatable to Python and JVM monorepos that didn’t want Google’s tooling tax. -
The “use a real language” thesis. Pulumi (2018) → AWS CDK (2019) → CDK8s (2020) → Dagger SDK (2022) is a single arc: every successive layer of YAML got a “write it in TS/Python/Go/Java instead” answer, motivated by the same complaints (no types, no IDE completion, no unit tests, no abstraction beyond YAML anchors). Whether this kills CI YAML the way HCL killed YAML for cloud provisioning is the open question of 2026.
-
Earthly and Dagger as containerized portable pipelines. Both treat the container as the unit of reproducibility. Earthly invented a DSL that fuses Makefile targets with Dockerfile syntax; Dagger went further and embedded the pipeline graph in a real language SDK that compiles to Buildkit LLB. Both replace the “works on my machine, fails in CI” problem with a graph that runs identically locally and in any CI provider — which sidesteps lock-in to GitHub Actions / GitLab CI / Jenkins specifics.
-
GitHub Actions YAML won the CI war despite obvious limitations. It’s not the most expressive (Jenkins Groovy), not the fastest (Buildkit-native systems), not the most reproducible (Earthly/Dagger), and not the most type-safe (Dagger SDKs). It won because GitHub is where the code is, the Marketplace gave it an enormous reusable-action ecosystem, and
uses: actions/checkout@v4is one line. Network effects beat language design — again. -
K8s YAML escape hatches. Helm’s Go-template-over-YAML is widely hated (whitespace-fragile templating producing whitespace-significant YAML), and the alternatives split three ways: Kustomize (no templating, pure overlay merging — built into kubectl), CDK8s / cdk8s+ (synthesize manifests from TypeScript/Python/Go/Java), and typed-config replacements (KCL, Cue, Pkl from config-and-dsl). Helm’s chart-repo network effect keeps it dominant despite the language complaints.
-
The Just / Task / Mage cluster as the modern Make-replacement. None of the three try to be a build system — they’re task runners, focused on the “type a command, run a recipe” use case Make also handles but with worse ergonomics (tabs! shell quoting! unintuitive variable expansion!). Just (Rust, 2017) won on UX polish and cross-platform portability. Task (Go, YAML, 2017) won the YAML-friendly crowd. Mage (Go, 2018) won the “I want my targets to be Go code” crowd. Rake (Ruby, 2003) and FAKE/Cake (.NET, 2009/2014) are the older language-native versions of the same idea.
-
Argo and Tekton: K8s-native CI primitives. Both are CNCF-graduated. Both express pipelines as Kubernetes Custom Resource Definitions, so the cluster’s scheduler runs the pipeline. Argo Workflows is more general (any DAG of pods); Tekton is more CI-focused (Tasks compose into Pipelines into PipelineRuns). They’re the answer to “what if your CI server is your Kubernetes cluster,” and they underpin most of the modern GitOps stack (Argo CD, Flux).
Citations
- GNU, “GNU Make Manual”, https://www.gnu.org/software/make/manual/
- FreeBSD, “make(1) — BSD make”, https://man.freebsd.org/cgi/man.cgi?make(1)
- Microsoft, “NMAKE Reference”, https://learn.microsoft.com/en-us/cpp/build/reference/nmake-reference
- Bazel Authors, “Bazel — a fast, scalable, multi-language build tool”, https://bazel.build/
- Bazel Authors, “Starlark Language”, https://bazel.build/rules/language
- Meta, “Buck2 — Fast, hermetic, multi-language build system”, https://buck2.build/
- Toolchain Inc, “Pants 2 — Scalable build system for monorepos”, https://www.pantsbuild.org/
- Thought Machine, “Please — A high-performance, cross-language build system”, https://please.build/
- Earthly Technologies, “Earthly — like Makefile + Dockerfile”, https://earthly.dev/
- Dagger Inc, “Dagger — programmable CI/CD engine”, https://dagger.io/
- Tilt Dev, “Tilt — multi-service development with no stress”, https://tilt.dev/
- Casey Rodarmor, “just — a command runner”, https://just.systems/
- Andrey Nering, “Task — a task runner / build tool”, https://taskfile.dev/
- Magefile Authors, “Mage — a Make/rake-like build tool using Go”, https://magefile.org/
- doit Authors, “doit — automation tool”, https://pydoit.org/
- Jim Weirich et al., “Rake — Ruby Make”, https://ruby.github.io/rake/
- Cake Authors, “Cake — Cross-platform build automation”, https://cakebuild.net/
- FAKE Authors, “FAKE — F# Make”, https://fake.build/
- SCons Foundation, “SCons — A software construction tool”, https://scons.org/
- Ninja Authors, “Ninja — a small build system with a focus on speed”, https://ninja-build.org/
- Meson Build, “The Meson Build System”, https://mesonbuild.com/
- Kitware, “CMake”, https://cmake.org/cmake/help/latest/
- Helm Authors, “Helm Documentation”, https://helm.sh/docs/
- Kustomize Authors, “Kustomize — Kubernetes native configuration management”, https://kustomize.io/
- Skaffold Authors, “Skaffold — Easy and Repeatable Kubernetes Development”, https://skaffold.dev/
- AWS, “AWS Cloud Development Kit (CDK) v2 Developer Guide”, https://docs.aws.amazon.com/cdk/v2/guide/home.html
- Pulumi Corp, “Pulumi Documentation”, https://www.pulumi.com/docs/
- Docker Inc, “Dockerfile reference”, https://docs.docker.com/engine/reference/builder/
- Containers Project, “Containerfile(5)”, https://github.com/containers/common/blob/main/docs/Containerfile.5.md
- Moby Project, “BuildKit — concurrent, cache-efficient, Dockerfile-agnostic builder toolkit”, https://github.com/moby/buildkit
- GitHub, “GitHub Actions Documentation”, https://docs.github.com/en/actions
- GitLab, “GitLab CI/CD YAML syntax reference”, https://docs.gitlab.com/ee/ci/yaml/
- Jenkins Project, “Pipeline / Jenkinsfile”, https://www.jenkins.io/doc/book/pipeline/jenkinsfile/
- CircleCI, “Configuration reference”, https://circleci.com/docs/configuration-reference/
- Argo Project (CNCF), “Argo Workflows Documentation”, https://argo-workflows.readthedocs.io/
- Tekton Authors (CNCF), “Tekton Pipelines Documentation”, https://tekton.dev/