Reference · print-friendly

Decision playbook

Four gates for monorepo + tool choice. Run in order. Earlier gates reject more options than later ones.

Gate A · Job (topology)

Gate B · Tool layer

Gate C · Tool family (decision depth)

Choose When
Turborepo JS/TS only; orchestrate existing package.json scripts; thin caching layer; Vercel remote cache OK
moon Want built-in toolchain pins, task inheritance, polyglot commands, ownership/constraints; config-first; not only npm scripts
Nx Full platform: plugins, generators, distributed CI / Nx Cloud depth, large JS ecosystem investment
Bazel Hermetic builds + transparent remote execution at extreme scale; accept steep model (BUILD files, sandbox)

moon’s own comparison is a starting point (may be incomplete/outdated): moonrepo.dev/docs/comparison. Landscape: monorepo.tools/compare.

Gate D · Ship risks (if monorepo + moon)

  1. Map projects (folders alone invisible)
  2. Shared tasks under .moon/tasks + inheritance
  3. Pin toolchain full semver (or own force-globals in CI)
  4. moon run … --affected — never full CI forever
  5. Constraints + CODEOWNERS — fight coupling/ownership vacuum
  6. Honest inputs/outputs — cache must not lie
  7. Incremental migration — not big-bang Friday

Review sentence

“We use mono | poly because job; tool is moon | turbo | nx | bazel because need; loop is init → map → inherit → pin → run affected; we own risk.”