Skip to main content

.moon/toolchain.yml

The .moon/toolchain.yml file configures the toolchain and the workspace development environment. This file is optional.

Managing tool version's within the toolchain ensures a deterministic environment across any machine (whether a developer, CI, or production machine).

.moon/toolchain.yml
$schema: 'https://moonrepo.dev/schemas/toolchain.json'

extends

Defines an external .moon/toolchain.yml to extend and inherit settings from. Perfect for reusability and sharing configuration across repositories and projects. When defined, this setting must be an HTTPS URL or relative file system path that points to a valid YAML document!

.moon/toolchain.yml
extends: 'https://raw.githubusercontent.com/organization/repository/master/.moon/toolchain.yml'
caution

Settings will be merged recursively for blocks, with values defined in the local configuration taking precedence over those defined in the extended configuration.

JavaScript

deno

Enables and configures Deno.

depsFile

Path to the dependencies file that's used for re-exporting external libraries. This file is heavily used in hashing and caching related scenarios. Defaults to deps.ts.

.moon/toolchain.yml
deno:
depsFile: 'src/deps.ts'

lockfile

Enables lockfile (deno.lock) support for Deno dependencies. When enabled, will run deno cache as part of the dependency installation action. Defaults to false.

.moon/toolchain.yml
deno:
lockfile: true

node

Enables and configures Node.js.

version

Defines the explicit Node.js version to use. We require an explicit and semantic major, minor, and patch version, to ensure the same environment is used across every machine. Ranges are not supported.

If this field is not defined, the global node binary will be used.

.moon/toolchain.yml
node:
version: '16.13.0'

Version can also be defined with .prototools or be overridden with the MOON_NODE_VERSION environment variable.

packageManager

Defines which package manager to utilize. Supports npm (default), pnpm, or yarn.

.moon/toolchain.yml
node:
packageManager: 'yarn'

npm, pnpm, yarn

Optional fields for defining package manager specific configuration. The chosen setting is dependent on the value of node.packageManager. If these settings are not defined, the latest version of the active package manager will be used (when applicable).

version

The version setting defines the explicit package manager version to use. We require an explicit major, minor, and patch version, to ensure the same environment is used across every machine.

If this field is not defined, the global npm, pnpm, and yarn binaries will be used.

.moon/toolchain.yml
node:
packageManager: 'yarn'
yarn:
version: '3.1.0'

Version can also be defined with .prototools or be overridden with the MOON_NPM_VERSION, MOON_PNPM_VERSION, or MOON_YARN_VERSION environment variables.

yarn

plugins

A list of plugins that will automatically be imported using yarn plugin import (Yarn 2+ only). For performance reasons, plugins will only be imported when the Yarn version changes.

.moon/toolchain.yml
node:
packageManager: 'yarn'
yarn:
version: '3.1.0'
plugins:
- 'interactive-tools'
- 'workspace-tools'

addEnginesConstraint

Injects the currently configured Node.js version as an engines constraint to the root package.json field. Defaults to true.

node:
addEnginesConstraint: true

For example, say our Node.js version is "16.15.0", and when we execute a run process through the moon binary, it will update the root package.json with the below. We pin a fixed version to ensure other Node.js processes outside of our toolchain are utilizing the same version.

package.json
{
// ...
"engines": {
"node": "16.15.0"
}
}

binExecArgs

Additional command line arguments to pass to the node binary when it's being executed by running a target. This will apply arguments to all Node.js based targets, and cannot be changed on a per target basis.

.moon/toolchain.yml
node:
binExecArgs:
- '--preserve-symlinks'
- '--loader'
- '@boost/module/loader'

dedupeOnLockfileChange

Will dedupe dependencies after they have been installed, added, removing, or changed in any way, in an effort to keep the workspace tree as clean and lean as possible. Defaults to true.

.moon/toolchain.yml
node:
dedupeOnLockfileChange: true

dependencyVersionFormat

When syncing project dependencies, customize the format that will be used for the dependency version range. The following formats are supported (but use the one most applicable to your chosen package manager):

  • file - Uses file:../relative/path and copies package contents.
  • link - Uses link:../relative/path and symlinks package contents.
  • star - Uses an explicit *.
  • version - Uses the explicit version from the dependent project's package.json, e.g., "1.2.3".
  • version-caret - Uses the version from the dependent project's package.json as a caret range, e.g., "^1.2.3".
  • version-tilde - Uses the version from the dependent project's package.json as a tilde range, e.g., "~1.2.3".
  • workspace (default) - Uses workspace:*, which resolves to "1.2.3". Requires package workspaces.
  • workspace-caret - Uses workspace:^, which resolves to "^1.2.3". Requires package workspaces.
  • workspace-tilde - Uses workspace:~, which resolves to "~1.2.3". Requires package workspaces.
.moon/toolchain.yml
node:
dependencyVersionFormat: 'link'

This setting does not apply to peer dependencies, as they will always use a format of ^<major>.0.0.

inferTasksFromScripts

Will infer and automatically create tasks from package.json scripts. Defaults to false.

This requires the project's language to be "javascript" or "typescript", a package.json to exist in the project, and will take the following into account:

  • Script names will be converted to kebab-case, and will become the task ID.
  • Pre, post, and life cycle hooks are ignored.
  • Tasks defined in .moon/tasks.yml or moon.yml take precedence over scripts of the same name.

To verify inferred tasks, run moon project <id> (pass --json to view raw config and options). Tasks that are inferred will have their command and args set to moon node run-script.

.moon/toolchain.yml
node:
inferTasksFromScripts: true
caution

This implementation shares functionality with moon migrate from-package-json, and will attempt to determine environment variables, outputs, CI options, and more! Be aware of these when utilizing this feature, especially in regards to runInCI, as it may be inaccurate!

syncProjectWorkspaceDependencies

Will sync a project's dependsOn setting as normal dependencies within the project's package.json. If a dependent project does not have a package.json, or if a dependency of the same name has an explicit version already defined, the sync will be skipped. Defaults to true.

.moon/toolchain.yml
node:
syncProjectWorkspaceDependencies: true

A quick example on how this works. Given the following dependsOn:

moon.yml
dependsOn:
- 'designSystem'
- 'reactHooks'

Would result in the following dependencies within a project's package.json. The version format can be customized with node.dependencyVersionFormat.

package.json
{
// ...
"dependencies": {
"@company/design-system": "workspace:*",
"@company/react-hooks": "workspace:*"
// ...
}
}

syncVersionManagerConfig

Will sync the currently configured Node.js version to a 3rd-party version manager's config/rc file. Supports "nodenv" (syncs to .node-version), "nvm" (syncs to .nvmrc), or none (default).

.moon/toolchain.yml
node:
syncVersionManagerConfig: 'nvm'

This is a special setting that ensure other Node.js processes outside of our toolchain are utilizing the same version, which is a very common practice when managing dependencies.

typescript

Dictates how moon interacts with and utilizes TypeScript within the workspace. This field is optional and is undefined by default. Define it to enable TypeScript support.

createMissingConfig

When syncing project references and a depended on project does not have a tsconfig.json, automatically create one. Defaults to true.

.moon/toolchain.yml
typescript:
createMissingConfig: true

projectConfigFileName

Defines the file name of the tsconfig.json found in the project root. We utilize this setting when syncing project references between projects. Defaults to tsconfig.json.

.moon/toolchain.yml
typescript:
projectConfigFileName: 'tsconfig.build.json'

rootConfigFileName

Defines the file name of the tsconfig.json found in the workspace root. We utilize this setting when syncing projects as references. Defaults to tsconfig.json.

.moon/toolchain.yml
typescript:
rootConfigFileName: 'tsconfig.projects.json'

rootOptionsConfigFileName

Defines the file name of the config file found in the workspace root that houses shared compiler options. Defaults to tsconfig.options.json. This setting is used in the following scenarios:

.moon/toolchain.yml
typescript:
rootOptionsConfigFileName: 'tsconfig.base.json'

routeOutDirToCache

Updates the outDir compiler option in each project's tsconfig.json to route to moon's cache folder. This is useful when using project references and wanting to keep all the compiled .d.ts files out of the project folder. Defaults to false.

.moon/toolchain.yml
typescript:
routeOutDirToCache: true

As a demonstration, if we had an npm package located at "packages/components", the outDir compiler option will be re-routed to the following when syncing.

<project>/tsconfig.json
{
// ...
"compilerOptions": {
// ...
"outDir": "../../.moon/cache/types/packages/components"
}
}

syncProjectReferences

Will sync a project's dependencies (when applicable) as project references within that project's tsconfig.json, and the workspace root tsconfig.json. Defaults to true when the parent typescript setting is defined, otherwise false.

.moon/toolchain.yml
typescript:
syncProjectReferences: true

A quick example on how this works. Given the following dependsOn:

moon.yml
dependsOn:
- 'designSystem'
- 'reactHooks'

Would result in the following references within both tsconfig.jsons.

tsconfig.json
{
// ...
"references": [
// ...
{ "path": "../../design-system" },
{ "path": "../../react-hooks" }
]
}
info

This setting assumes you're using the file organization as defined in our official TypeScript project references in-depth guide.

syncProjectReferencesToPaths

Will sync a project's tsconfig.json project references to the paths compiler option, using the referenced project's package.json name. This is useful for mapping import aliases to their source code. Defaults to false.

.moon/toolchain.yml
typescript:
syncProjectReferencesToPaths: true

As a demonstration, if we had a reference to a shared npm package with the name @brand/components, the paths compiler option would be updated to the following when syncing. The index file may exist in a src folder, or the root of the package.

<project>/tsconfig.json
{
// ...
"compilerOptions": {
// ...
"paths": {
"@brand/components": ["../shared/components/src/index.ts"],
"@brand/components/*": ["../shared/components/src/*"]
}
},
"references": [
{
"path": "../shared/components"
}
]
}

This setting runs after syncProjectReferences and will inherit any synced references from that setting.

Rust

rustv1.5.0

Enables and configures Rust.

version

Defines the explicit Rust toolchain version/channel to use. We require an explicit and semantic major, minor, and patch version, to ensure the same environment is used across every machine.

If this field is not defined, the global cargo, rustc, and other binaries will be used.

.moon/toolchain.yml
rust:
version: '1.69.0'

Version can also be defined with .prototools.

bins

A list of crates/binaries (with optional versions) to install into Cargo (~/.cargo/bin), and make them available to the cargo command. Binaries will be installed with cargo-binstall in an effort to reduce build and compilation times.

.moon/toolchain.yml
rust:
bins:
- 'cargo-make@0.35.0'
- 'cargo-nextest'

Binaries that have been installed into Cargo can be referenced from task commands:

<project>/moon.yml
tasks:
test:
command: 'nextest run --workspace'

syncToolchainConfig

Will automatically sync the currently configured Rust version to the toolchain.channel field in rust-toolchain.toml, relative to the root Cargo.lock. If the file does not exist, it will be created.

This is a special setting that ensures other Rust/Cargo processes outside of our toolchain are utilizing the same version, which is a very common practice.

.moon/toolchain.yml
rust:
version: '1.69.0'
syncToolchainConfig: true

To demonstrate this, the settings above would sync the following file:

rust-toolchain.toml
[toolchain]
channel = "1.69.0"