Lesson 0005 · ~12 minutes

Toolchain pins: same versions everywhere

One skill: stop version drift with .moon/toolchains.* — enable tools, pin versions, know when to force PATH globals in CI/Docker.

Win for this lesson

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.

1. The problem pins solve

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.

2. Optional, but high leverage

.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).

3. Pin with 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):

4. Version shapes (pick full when you can)

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).

5. Escape hatch: force globals

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.

Mental model

Shared tasks (lesson 4) standardize commands. Shared toolchain standardizes which binary runs them. Both are required for “easier maintenance.”

6. Practice

Equal-length options. Defend the pin, not the whole proto manual.

Question 1

Where do you pin Node so moon can auto-install it for the workspace?

Question 2

You never create .moon/toolchains.*. How do tasks find Node?

Question 3

Best default version shape for a team monorepo pin?

Question 4

When is MOON_TOOLCHAIN_FORCE_GLOBALS=true appropriate?

7. Primary source

Recommended: Setup toolchain (~5 min). Then skim toolchain concept (version shapes + force globals) and keep the toolchain sheet open.

Ask your teacher Map your real Node/pnpm/yarn pins, or whether CI should use force-globals vs managed install. Chat is part of the course.