Lesson 0005 · ~12 minutes
One skill: stop version drift with
.moon/toolchains.* — enable tools, pin versions, know when
to force PATH globals in CI/Docker.
You can defend a pin set (e.g. Node 20 + yarn 4) in a design review:
where it lives, what version buys you, and when
MOON_TOOLCHAIN_FORCE_GLOBALS is the right escape hatch.
Lesson 1 named version drift as a polyrepo pain. Shared tasks (lesson 4) don’t help if Alice runs Node 18 and CI runs Node 22. moon’s toolchain layer downloads, installs, and manages tools so environments match (toolchain concept):
Built on
proto under
~/.proto — moon reuses or installs tools there.
.moon/toolchains.* is
optional. Without it, tasks use the
system toolchain — binaries already on
PATH, no special install
(setup toolchain).
Enabling a block turns on platform features (dependency hashing, package manager awareness, etc.). Empty object still counts as enable:
# .moon/toolchains.yml
javascript:
packageManager: 'yarn'
node: {}
yarn: {}
Or inject with
moon toolchain add <toolchain> (not every language).
version (auto-install)
The win for multi-machine monorepos: set
version so moon downloads/installs on first related task and
sets PATH/env for you
(auto install).
node:
version: '20.0.0'
yarn:
version: '4.0.0'
Pains this kills (from moon’s own list):
| Shape | Example | Note |
|---|---|---|
| Full | 20.0.0 |
Preferred — least subtle drift |
| Partial | 20.0, ^20 |
May reuse a local match (e.g. 20.0.10) or fetch latest matching |
| Alias | latest, stable |
Discouraged — can change daily |
Share one pin across tools with
.prototools +
versionFromPrototools (default inherits; good with Renovate).
Pre-baked CI/Docker images sometimes already have Node/yarn. Then:
MOON_TOOLCHAIN_FORCE_GLOBALS=true
# or only some tools:
MOON_TOOLCHAIN_FORCE_GLOBALS=node,yarn
moon uses PATH binaries instead of downloading
(force disabling). Tradeoff: you own keeping that image in sync with
toolchains.yml intent.
Shared tasks (lesson 4) standardize commands. Shared toolchain standardizes which binary runs them. Both are required for “easier maintenance.”
Equal-length options. Defend the pin, not the whole proto manual.
Where do you pin Node so moon can auto-install it for the workspace?
You never create .moon/toolchains.*. How do tasks find
Node?
Best default version shape for a team monorepo pin?
When is MOON_TOOLCHAIN_FORCE_GLOBALS=true appropriate?
Recommended: Setup toolchain (~5 min). Then skim toolchain concept (version shapes + force globals) and keep the toolchain sheet open.