Monorepo & Workspace Tooling
A breadth-first survey of monorepo workspace features, task orchestration, and polyglot build architectures across 44 package managers, build systems, task runners, and remote-execution backends — mapped against five recurring dimensions (workspace declaration, dependency isolation, task DAG, caching/remote execution, and filter ergonomics) to inform a phased, native workspace/monorepo proposal for dub, the D package manager and build tool.
This is the master index for the monorepo-tooling research tree. Each row links to a deep-dive that was written and fact-checked independently against the tool's own source tree or official documentation; where this index summarizes a system, the deep-dive is the source of truth.
This survey answers six questions:
- Vocabulary — what is a workspace, a virtual root, a task DAG, dependency hoisting vs. a virtual store, content-addressed caching, REAPI, and the
workspace:-protocol family of local cross-references? See concepts. - What
dubdoes today — how does the D package manager handle multi-package projects, sub-packages,path=overrides, anddub.selections.json, and where are the gaps? See thedubbaseline. - How 44 tools answer the five dimensions — workspace declaration, dependency isolation, task orchestration, caching/remote execution, and CLI filter ergonomics. See the master catalog and each linked deep-dive.
- What the field agrees on, and where it splits — the consensus standard, the explicit-graph (Bazel/Buck2) vs. minimalist vs. language-lockfile (Cargo/uv) trade-offs, and "the
dubdelta." See the comparison. - When key capabilities landed across ecosystems — workspaces, topological
foreach, content-addressed caches, REAPI remote execution. See Milestones. - What
dubshould adopt, and in what order — the milestoned enhancement proposal, from layout primitives to git-ref change detection. See thedubproposal.
Scope note. The 44 tools span ten categories — JS/TS and Python package managers, language build systems, JS/TS and polyglot orchestrators, container/CI engines, generic task runners, native build systems, REAPI backends, minimalist/research tools, and Nix as polyglot glue.
dubitself is the system under improvement and is written up only in the baseline, not as a catalog row.
Last reviewed: June 5, 2026
Master Catalog
One row per surveyed tool. Task DAG? answers whether the tool builds a graph of tasks (not merely a dependency graph) and schedules it concurrently in topological order. Caching classifies the deepest tier reached: none → install/download only → local task-output → remote cache → REAPI remote execution. Local cross-refs names the mechanism a member uses to depend on a sibling without publishing. Sample? flags whether a runnable sample/ workspace ships with the deep-dive.
| Tool | Ecosystem | Category | Workspace model | Task DAG? | Caching | Local cross-refs | Sample? | Link |
|---|---|---|---|---|---|---|---|---|
| npm | JS/TS | JS/TS package manager | Root-package: workspaces glob in package.json | No | Install only (_cacache) | Plain semver; symlink if satisfied | ✅ | npm |
| Yarn Berry | JS/TS | JS/TS package manager | Root-package: workspaces glob; workspace: protocol | Yes | Install only (.yarn/cache) | workspace: protocol + portal: | ✅ | Yarn Berry |
| pnpm | JS/TS | JS/TS package manager | Virtual root: pnpm-workspace.yaml globs | Yes (pkg) | Install only (CAS store) | workspace: protocol + catalog: | ✅ | pnpm |
| Bun | JS/TS | JS/TS package manager | Root/virtual: npm workspaces glob; bun.lock | Yes (pkg) | Install only (clonefile store) | workspace: protocol + catalog: | — | Bun |
| uv | Python (Rust) | Python package manager | Cargo-inspired [tool.uv.workspace]; one uv.lock, one venv | No | Local CAS (~/.cache/uv) | [tool.uv.sources] {workspace = true} | ✅ | uv |
| Poetry | Python | Python package manager | None native; per-project pyproject.toml + plugins | No | Download only | Relative path dep (develop = true) | — | Poetry |
| Hatch | Python | Python package manager | Env-scoped workspace.members (1.16.0) | No | Env + download | Editable workspace.members + path | — | Hatch |
| Cargo | Rust | Language build system | Root [workspace]; root-package or virtual; one Cargo.lock | Yes | Local (target/ + fingerprints) | path + [workspace.dependencies] | ✅ | Cargo |
Go (go.work) | Go | Language build system | Virtual root go.work use-list of local modules (MVS) | No | Local CAS ($GOCACHE) | Implicit: every used module is local | ✅ | Go go.work |
| Gradle | JVM | Language build system | Multi-project include() + composite includeBuild() | Yes | Local + remote build cache | project(":path") + substitution | — | Gradle |
| Maven | JVM | Language build system | Aggregator pom.xml <modules> (the reactor) | Yes | Download (cache = extension) | GAV coordinate via ReactorReader | — | Maven |
| sbt | Scala/JVM | Language build system | Multi-project build.sbt; aggregate/dependsOn | Yes | 2.x: REAPI ActionCache | dependsOn(project) value reference | — | sbt |
| Mill | Scala/JVM | Language build system | Module tree of Scala objects; moduleDeps | Yes | Local content-hash (universal) | moduleDeps value reference | — | Mill |
| Composer | PHP | Language build system | None native; path repositories + replace | No | Download only | path repository (symlink into vendor) | — | Composer |
| Nx | JS/TS | JS/TS orchestrator | Inherited from package manager + inference plugins | Yes | Local + remote (Nx Cloud) | Delegated to package-manager symlinks | ✅ | Nx |
| Turborepo | JS/TS | JS/TS orchestrator | Inherited; adds only turbo.json task layer | Yes | Local + HTTP remote cache | Package-manager workspace:/* | ✅ | Turborepo |
| Lerna | JS/TS | JS/TS orchestrator | Inherited + optional lerna.json packages glob | Yes (Nx) | Inherited from Nx | Delegated to package-manager symlinks | — | Lerna |
| Rush | JS/TS | JS/TS orchestrator | Explicit rush.json projects[] registry | Yes | Local + cloud + cobuilds | Package-manager workspace: (pnpm) | — | Rush |
| Lage | JS/TS | JS/TS orchestrator | Parasitic: reads host package-manager workspaces | Yes | Local + remote (backfill) | Host workspace: deps (edges only) | — | Lage |
| Wireit | JS/TS | JS/TS orchestrator | Inherited; wireit block inside package.json | Yes | Local + GitHub Actions cache | Relative ../core:build path+script | — | Wireit |
| Bazel | Polyglot | Polyglot orchestrator | Single repo at MODULE.bazel; //-label packages | Yes | REAPI (cache + execution) | //path:target label | ✅ | Bazel |
| Buck2 | Polyglot | Polyglot orchestrator | One project at .buckconfig; tree of cells | Yes | REAPI-first (CAS + ActionCache) | cell//path:target label | — | Buck2 |
| Pants | Polyglot | Polyglot orchestrator | Single repo at pants.toml; inferred from imports | Yes | Local LMDB + REAPI | Inferred from import statements | — | Pants |
| Please | Polyglot | Polyglot orchestrator | Single repo at .plzconfig; BUILD-file packages | Yes | Local + HTTP + REAPI v2.1 | //path:target label | — | Please |
| moon | Polyglot | Polyglot orchestrator | Root .moon/; moon.yml id→path map / globs | Yes | Local + REAPI v2 cache | Host workspace:* + dependsOn | ✅ | moon |
| GN + Ninja | Polyglot | Polyglot orchestrator | Single tree at .gn; BUILD.gn packages × toolchain | Yes | None native (mtime only) | //path:target label | — | GN + Ninja |
| Dagger | Polyglot | Container / CI | Module graph: per-component dagger.json dependencies | Yes | BuildKit CAS + CacheVolume | dagger install ./path (same repo) | — | Dagger |
| Earthly | Polyglot / CI | Container / CI | Emergent +target graph across Earthfiles | Yes | BuildKit + registry remote cache | +target (file/dir/repo edges) | — | Earthly |
| Garden | Polyglot / k8s | Container / CI | Repo-wide Stack Graph of *.garden.yml actions | Yes | Version-hash + cluster caches | <kind>.<name> action edges | — | Garden |
| Task (go-task) | Go | Generic task runner | None native; root Taskfile.yml includes | Yes | Local skip-only (.task/) | None; includes + deps task edges | — | Task |
| Just | Polyglot | Generic task runner | None native; justfile mod namespace tree | Yes | None | None; recipe edges (: / &&) | — | Just |
| mise | Polyglot | Generic task runner | Hierarchical mise.toml; opt-in monorepo mode | Yes | Local skip-only (blake3) | None; //libs/core:build task edges | — | mise |
| Make | Polyglot | Generic task runner | None; one makefile or recursive $(MAKE) -C | Yes | None (mtime only) | None; file/order prerequisites | — | Make |
| Meson | C/C++/native | Native build system | Root meson.build + subprojects/ .wrap manifests | Yes | Ninja mtime/depfile only | .wrap [provide] name mapping | — | Meson |
| CMake | C/C++/native | Native build system | None native; add_subdirectory() into one target graph | Target | None native (mtime backend) | Target name in global namespace | — | CMake |
| SCons | C/C++/native | Native build system | Single tree at SConstruct; SConscript hierarchy | Yes | Local + shared CacheDir (CAS) | Graph edges + Export()/Import() | — | SCons |
| Waf | C/C++/native | Native build system | Single wscript; ctx.recurse('sub') | Yes | Local hash + wafcache (S3/GCS) | use='A B' task-generator name | — | Waf |
| Ninja | C/C++/native | Native build system | Machine-generated build.ninja; subninja/include | Yes | Local incremental only | Graph edges (output path as input) | — | Ninja |
| BuildBuddy | REAPI backend | Remote execution | None — server for a REAPI client | No (svc) | REAPI v2 (cache + execution) | N/A (--remote_instance_name) | — | BuildBuddy |
| Buildbarn | REAPI backend | Remote execution | None — server side of REAPI v2 | No (svc) | Full REAPI cache + execution | N/A (shared CAS digests) | — | Buildbarn |
| NativeLink | REAPI backend | Remote execution | None — REAPI v2 server, client-agnostic | No (svc) | Full REAPI CAS + ActionCache | N/A (content-addressed digests) | — | NativeLink |
| redo | Polyglot | Minimalist / research | None; tree of .do scripts + global .redo DB | Yes | Local incremental (.redo) | N/A; redo-ifchange ../lib/foo.o | — | redo |
| tup | Polyglot | Minimalist / research | One tree at .tup SQLite DB; per-dir Tupfiles | Yes | None (avoid-work, not reuse) | N/A; group/bin file-level edges | — | tup |
| Nix (flakes) | Nix / polyglot | Polyglot glue | Virtual graph of flakes; flake.lock pins the DAG | Yes | CAS store + binary caches | Relative path:./libs/core-cli | — | Nix (flakes) |
NOTE
"Task DAG? = No" does not mean "no graph at all": npm, uv, Poetry, Composer, and go.work all build a dependency DAG for resolution, but expose no task DAG — topological build/test is delegated to an external runner. "Yes (pkg)" marks package-level ordering (pnpm/Bun) without an intra-package dependsOn task graph. The REAPI backends own no client-side DAG at all; they schedule the leaf actions a client's DAG emits. See concepts for the task-DAG vs. dependency-DAG distinction.
By category
The same 44 rows, grouped by the scope matrix's Category column (the grouping carried into the VitePress sidebar).
| Category | Tools |
|---|---|
| JS/TS package managers | npm, Yarn Berry, pnpm, Bun |
| Python package managers | uv, Poetry, Hatch |
| Language build systems | Cargo, Go go.work, Gradle, Maven, sbt, Mill, Composer |
| JS/TS orchestrators | Nx, Turborepo, Lerna, Rush, Lage, Wireit |
| Polyglot orchestrators | Bazel, Buck2, Pants, Please, moon, GN + Ninja |
| Container / CI | Dagger, Earthly, Garden |
| Generic task runners | Task, Just, mise, Make |
| Native build systems | Meson, CMake, SCons, Waf, Ninja |
| Remote execution | BuildBuddy, Buildbarn, NativeLink |
| Minimalist / research | redo, tup |
| Polyglot glue | Nix (flakes) |
Taxonomy
Four re-cuts of the same set, one axis each. The full treatment with verbatim quotes lives in concepts and each deep-dive.
By workspace declaration
How are members discovered? The central split is whether the root manifest is itself a buildable package (root-package workspace) or a stateless grouping node (virtual workspace), and whether membership is globbed, enumerated, or inferred from the directory tree. See concepts § workspace topology.
| Declaration style | Mechanism | Tools |
|---|---|---|
| Root-package, glob | Root is a package; workspaces/members glob array | npm, Yarn Berry, Bun, Cargo (root-package mode), uv (root-package mode) |
| Virtual root, glob | Stateless root groups members by glob | pnpm, Cargo (virtual mode), uv (virtual mode), Nix flakes |
| Explicit enumeration | Members hand-listed (no glob) | Maven, Gradle, Rush, Go go.work, Task, Just, Meson |
| Value-reference tree | Members are language values wired by edges | sbt, Mill, SCons, Waf |
| Implicit (tree / inference) | Whole directory tree is the workspace; deps from imports or labels | Bazel, Buck2, Pants, Please, GN + Ninja, Ninja, tup, redo |
| Inherited / parasitic | Reads the host package manager's workspace | Nx, Turborepo, Lerna, Lage, Wireit, moon |
| None native | No workspace concept; assembled procedurally or by plugins | Poetry, Hatch, Composer, CMake, Make, mise |
By dependency isolation & local cross-references
How does a member depend on a sibling without publishing, and how is the dependency tree laid out on disk? The workspace:-protocol family symlinks to source; the label/coordinate family resolves through one global namespace; the path family is a filesystem link. See concepts § dependency isolation.
| Isolation / cross-ref model | Mechanism | Tools |
|---|---|---|
workspace: protocol | Explicit local-first selector, rewritten to a range at publish | Yarn Berry, pnpm, Bun, Rush (via pnpm) |
| Implicit local resolution | Sibling resolves locally with no selector | npm (symlink-if-satisfied), Go go.work (MVS), Maven (ReactorReader) |
| Central registry + inheritance | [workspace.dependencies] / catalog shared upstream pinning | Cargo, pnpm (catalog:), Bun (catalog:), uv (inherited [tool.uv.sources]) |
Relative path link | Filesystem symlink/copy into the dep tree | Composer, Poetry, Hatch, Dagger, Nix flakes |
| Value / module reference | Sibling referenced by a typed language value | sbt, Mill, Gradle, SCons, Waf, CMake |
| Global label namespace | One //path:target label space, no version/path | Bazel, Buck2, Please, GN + Ninja, Pants (inferred) |
| Task / file edge only | No package edge; cross-refs are task or file prerequisites | Task, Just, mise, Make, Ninja, redo, tup, Earthly, Garden |
By orchestration model
Does the tool build and schedule a task graph itself, or delegate it? See concepts § task DAG.
| Orchestration model | Behavior | Tools |
|---|---|---|
| Full task DAG | (package × task) graph, topologically scheduled, concurrent | Cargo, Gradle, Maven, sbt, Mill, Nx, Turborepo, Rush, Lage, Wireit, Bazel, Buck2, Pants, Please, moon |
| Package-level ordering only | Members ordered topologically; no intra-package task graph | pnpm, Bun, Yarn Berry (foreach -t) |
| File/recipe DAG (no package) | Real DAG over files or recipes, not packages | Make, Ninja, GN + Ninja, Task, Just, mise, Meson, SCons, Waf, redo, tup, Dagger, Earthly, Garden, Nix flakes |
| Delegated / none | No task DAG; defer to an external runner | npm, uv, Poetry, Hatch, Composer, Go go.work, CMake (backend), Lerna (via Nx) |
| Distributed scheduler (server) | Schedules leaf actions a client's DAG emits | BuildBuddy, Buildbarn, NativeLink |
By caching & remote execution
How deep does reuse go? The tiers run none → install/download only → local task-output cache → shared/remote cache → REAPI remote execution. The REAPI (Remote Execution API) line is the field's high-water mark; only a handful of language tools reach it natively. See concepts § caching and REAPI.
| Caching tier | What is reused | Tools |
|---|---|---|
None / mtime only | Nothing portable; incrementality dies on fresh CI checkout | Just, Make, CMake, Ninja (incremental only), GN + Ninja, Meson, tup |
| Install / download only | Package archives + lockfile reproducibility | npm, Yarn Berry, pnpm, Bun, Poetry, Hatch, Composer, Maven (core) |
| Local content-addressed | Build/test outputs keyed by input hash, single machine | uv, Cargo, Go go.work, Mill, Task, mise, redo |
| Local + shared/remote cache | Output reuse across machines/CI (HTTP/cloud) | Gradle, Nx, Turborepo, Rush, Lage, Wireit, SCons, Waf, Nix flakes, Garden, Earthly |
| REAPI (cache + remote exec) | Content-addressed actions cached and executed on a remote farm | Bazel, Buck2, Pants, Please, moon (cache only), sbt (2.x cache), BuildBuddy, Buildbarn, NativeLink |
NOTE
moon and sbt 2.x speak REAPI for caching but do not perform remote execution; they are listed in the REAPI row because they share the protocol and CAS format. The three REAPI backends are pure servers — they provide the cache and execution surface for the orchestrators above them.
Milestones
A high-confidence chronology of when each capability — native workspaces, topological foreach, content-addressed task caching, and REAPI remote execution — landed in each ecosystem. Dates are first stable/GA release unless noted; entries marked ~ are approximate.
| Date | Workspace / monorepo milestone | Caching / remote-execution milestone |
|---|---|---|
| 1976 | Make — file-mtime target/prerequisite DAG; the universal front door | — |
| ~2003 | Maven 2 — the multi-module reactor; aggregator pom.xml <modules> | ~/.m2 shared download repository |
| ~2006 | Bazel ancestor Blaze in production at Google (content-addressed action graph) | Internal content-addressed action cache |
| 2008 | SCons content-hash build signatures; shared CacheDir | Shared NFS derived-file cache (content-addressed) |
| ~2008 | Gradle 0.x multi-project builds (include()) | — |
| 2010 | Ninja released (Chromium); GN generator later pairs with it | Local incremental (.ninja_log) |
| 2011 | Cargo ships with Rust 1.0 lineage (single-crate first) | Local target/ build cache |
| 2015 | Bazel open-sourced (Mar 2015); sbt multi-project builds mature | Bazel local action cache |
| 2016 | Lerna 2.x popularizes JS monorepos; Bazel remote cache (gRPC) lands | Bazel remote cache over gRPC (the proto-REAPI) |
| 2017 | Yarn (classic) workspaces (workspaces field, Yarn 1.0, Sep 2017) | Bazel Remote Execution API (REAPI) v2 stabilizes; Buildbarn/BuildGrid emerge |
| 2018 | npm 7 workspaces in development; pnpm workspace + workspace: protocol | Gradle build cache GA (local + remote) |
| 2019 | Cargo [workspace] mature (virtual + root-package); Yarn Berry (v2) + PnP + foreach | Bazel RBE on Google Cloud; BuildBuddy founded |
| 2020 | Turborepo released (acquired by Vercel Dec 2021); Nx task graph + affected | Turborepo / Nx content-addressed task cache + remote cache |
| Mar 2021 | npm 7 ships workspaces GA (Node 15/16); Buck2 in development at Meta | Nx Cloud distributed cache; NativeLink (Rust REAPI) development |
| 2022 | Bun released (workspaces support); Rush subspaces; Wireit (Google) released | Wireit SHA-256 fingerprint cache; Lage remote backfill cache |
| Mar 2022 | Go 1.18 — go.work workspace mode (first-party multi-module) | $GOCACHE content-addressed (already present); GOCACHEPROG shim later |
| 2023 | Buck2 open-sourced (Meta, Apr 2023); moon + Pants 2.x dependency inference | Buck2 REAPI-first; Pants local LMDB + REAPI; moon REAPI cache |
| Feb 2024 | uv released (Astral); uv workspaces (Cargo-inspired) shortly after | uv local content-addressed cache; Go 1.24 stabilizes GOCACHEPROG (2025) |
| ~2025 | Hatch workspace.members (1.16.0); Earthly frozen/unmaintained (mid-2025) | Earthly Satellites + auto-skip cloud cache shut down (Jul 16, 2025) |
| Jun 2026 | sbt 2.x RC — automatic content-addressed ActionCache; dub workspace proposal authored | sbt 2.x Bazel-compatible REAPI remote cache (RC) |
WARNING
Several dates are approximate (~) where a capability shipped incrementally (Gradle multi-project builds, Cargo workspaces, npm workspaces across 7.x point releases) or where the exact public-release date is contested. The first-party sources for each are in the linked deep-dive; this table optimizes for "which ecosystem reached this capability first," not point-release precision.
Quick Navigation
Suggested reading paths
- "Give me the vocabulary first." concepts → comparison → one language-native deep-dive (Cargo or pnpm).
- "I'm designing
dubworkspaces."dubbaseline → comparison (the "dubdelta") →dubproposal. Cross-reference Cargo (virtual roots,[workspace.dependencies], fingerprint cache) and Yarn Berry (workspace:protocol,foreach -ttopological loop) — the two structural precedents the proposal builds on. - "I want the orchestrator landscape." Nx → Turborepo → Bazel → Buck2 → comparison.
- "I care about caching and remote execution." comparison (caching tiers) → Bazel → BuildBuddy / Buildbarn / NativeLink (the REAPI backends).
- "I want the minimal end of the spectrum." Make → Ninja → redo → tup.
Concepts & synthesis
- Concepts & vocabulary — workspace topology (root-package vs. virtual), dependency isolation (hoisting / symlink / virtual store), the task DAG and change detection, content-addressed caching + REAPI, the
workspace:-protocol family. dubbaseline — the system under improvement: howdubhandles sub-packages,path=overrides, anddub.selections.jsontoday, and where the gaps are.- Comparison — the consensus standard, the architectural trade-offs (explicit-graph vs. minimalist vs. language-lockfile), and the "
dubdelta" that bridges into the proposal. dubproposal — the milestoned enhancement plan: layout primitives → metadata inheritance → topological task routing → git-ref change detection.
Library deep-dives
One line per tool. Each links to its <slug>/ deep-dive.
| Tool | One-line |
|---|---|
| npm | Node.js's default package manager: a workspaces glob array symlinks members; no workspace: protocol, no task DAG, no caching. |
| Yarn Berry | TypeScript rewrite of Yarn: workspace: protocol, Plug'n'Play, and yarn workspaces foreach topological runner — most complete. |
| pnpm | Content-addressed store + strict symlinked node_modules; pnpm-workspace.yaml, workspace: protocol, catalogs, recursive runner. |
| Bun | Speed-first all-in-one toolkit: reads npm workspaces, hoisted-or-isolated node_modules, parallel dependency-ordered runner. |
| uv | Rust-built Python manager: Cargo-inspired workspaces, one shared uv.lock, one venv, local CAS — but no task orchestration. |
| Poetry | PubGrub-resolved pyproject.toml manager with no native workspace; monorepos improvised from path deps and plugins. |
| Hatch | PyPA project manager of isolated matrix environments; new per-env workspace.members editable-installs locals, no shared lock. |
| Cargo | Rust's [workspace]: one root manifest, one Cargo.lock, one target/, a fingerprint-cached build DAG — the canonical precedent. |
Go go.work | Go's first-party multi-module workspace: use-listed local modules cross-import via MVS; no member task DAG, no unified lockfile. |
| Gradle | JVM build engine: two-tier include + composite includeBuild, a cross-project task DAG, local + remote build cache. |
| Maven | The JVM reactor: aggregator pom.xml topologically sorts modules by GAV and builds them in one pass; no native lockfile or cache. |
| sbt | Scala's build tool: build.sbt with aggregate/dependsOn, a memoizing task graph, Zinc, and (2.x) a REAPI-compatible cache. |
| Mill | JVM build tool: a tree of Scala-object modules lowered into one graph of content-hash-cached tasks — Bazel's model in the host. |
| Composer | PHP's lockfile-driven single-package manager; its only monorepo primitive is the symlinking path repository. |
| Nx | JS/TS orchestrator atop the package manager: a project graph → hashed, cached, topologically-scheduled task DAG with affected. |
| Turborepo | Lean Rust JS/TS orchestrator: one turbo.json, content-hashed tasks, local + remote replayed outputs — "never do work twice." |
| Lerna | The original JS monorepo tool, now Nx-stewarded: delegates tasks/cache to Nx, keeps its version/publish release toolchain. |
| Rush | Microsoft's enterprise orchestrator: explicit project registry, deterministic install, native incremental engine, cobuild cache. |
| Lage | Microsoft's task runner overlaying a pipeline onto any npm/yarn/pnpm workspace; (package × task) DAG, local + remote cache. |
| Wireit | Google's no-new-binary upgrade to npm scripts: per-script cross-package DAG, SHA-256 fingerprinting, local + GitHub-Actions cache. |
| Bazel | Google's language-agnostic content-addressed engine: a monorepo becomes one action graph, Skyframe-incremental, REAPI-cacheable. |
| Buck2 | Meta's Rust rewrite of Buck: remote-execution-first, one phaseless DICE dependency graph, Starlark rules, REAPI caching. |
| Pants | Polyglot orchestrator betting on dependency inference: reads imports for a file-level DAG, memoizing Rust + Tokio engine over REAPI. |
| Please | Lightweight Go Bazel/Buck-family engine: restricted-Python BUILD files form one hash-keyed, sandboxed, REAPI-cacheable graph. |
| moon | Rust convention-first polyglot orchestrator: explicit project/action graph, content-hashed tasks, local + Bazel-REAPI cache. |
| GN + Ninja | A strict generator/executor split: GN writes build.ninja from BUILD.gn; Ninja executes it at maximum speed, mtime-incremental. |
| Dagger | Container-native CI engine: pipelines are real code calling a GraphQL API, run by BuildKit as an auto-caching content-addressed DAG. |
| Earthly | Container-native build tool ("Dockerfile + Makefile"): +target artifact references across files/repos; now frozen/unmaintained. |
| Garden | Kubernetes-native automation: repo-wide Build/Deploy/Test/Run actions compiled into a version-hashed, graph-aware Stack Graph. |
| Task | Single-binary YAML task runner (declarative Make): parallel deps DAG, file-fingerprinted up-to-date checks, includes namespaces. |
| Just | Single-binary make-inspired command runner (not a build system): names/orders commands via a justfile, no caching or resolution. |
| mise | Single-binary dev-tool manager + env loader + task runner: 2026 monorepo mode, //path:task namespacing, petgraph DAG. |
| Make | The 1976 mtime dependency engine and universal front door: a real parallel DAG, but no workspace, resolver, or content cache. |
| Meson | Fast generate-then-execute native build system; monorepo model is the in-tree subproject wired in by a .wrap manifest. |
| CMake | Cross-platform meta-build generator with no native workspace; multi-package trees aggregated via add_subdirectory. |
| SCons | Pure-Python construction tool: the build description IS a Python program; content-hash signatures, shared CacheDir. |
| Waf | Zero-dependency single-file Python build framework: recurse() assembles the tree, Waf schedules a hash-signature task DAG. |
| Ninja | Deliberately minimal, maximally-fast executor ("an assembler"): runs a generated build.ninja with near-instant incremental builds. |
| BuildBuddy | Open-core Go REAPI implementation: CAS + ActionCache + a Redis scheduler + autoscaling executors behind one --remote_executor URL. |
| Buildbarn | Modular Go REAPI: content-addressable cache + size-class-aware remote execution from small composable daemons wired by Jsonnet. |
| NativeLink | Nix-powered single-binary Rust REAPI: a composable JSON5 store stack and Nix-based Local Remote Execution for bit-identical toolchains. |
| redo | djb's minimalist design realized: per-target .do scripts declare prerequisites at runtime via redo-ifchange into .redo. |
| tup | File-based build system updating only the affected slice (the beta algorithm); the DAG is discovered by intercepting real I/O. |
| Nix (flakes) | Flakes turn any directory into a content-hash-locked node — the polyglot glue that wires multi-language monorepos no one tool sees. |
Sources
Each deep-dive carries its own primary-source citations (the tool's own source tree or official documentation, with verbatim quotes). The authoritative artifacts behind this index's classifications are:
- The five dimensions — workspace declaration, dependency isolation, task DAG, caching/remote execution, and CLI ergonomics — are defined in concepts and applied uniformly across all 44 deep-dives.
dubgrounding — thedubanddub-docssource trees under~/code/repos/dlang/, written up in thedubbaseline and the "dubdelta" of the comparison.- REAPI — the Remote Execution API v2 specification, as implemented by Bazel, Buck2, Pants, Please, and served by BuildBuddy, Buildbarn, and NativeLink.
- Per-tool sources — repository trees, official docs, and design write-ups cited in each linked deep-dive.
Cross-tree, the sibling async I/O survey and coroutines survey share this corpus's house style and feed the broader Sparkles research program.