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

bunv1.17.0

Enables and configures Bun.

version

Defines the explicit Bun toolchain version specification to use. If this field is not defined, the global bun binary will be used.

.moon/toolchain.yml
bun:
version: '1.0.0'

Version can also be defined with .prototools.

installArgsv1.22.0

Customize the arguments that will be passed to the bun install command, when the InstallDeps action is triggered in the pipeline. These arguments are used both locally and in CI.

.moon/toolchain.yml
bun:
installArgs: ['--frozen-lockfile']

Inherited from node

Since Bun and Node.js have a lot of overlap in functionality, the following node settings can also be configured within bun:

.moon/toolchain.yml
bun:
dependencyVersionFormat: 'workspace'
inferTasksFromScripts: true
rootPackageOnly: true
syncProjectWorkspaceDependencies: true

deno

Enables and configures Deno.

versionv1.21.0

Defines the explicit Deno toolchain version specification to use. If this field is not defined, the global deno binary will be used.

.moon/toolchain.yml
deno:
version: '1.40.0'

binsv1.10.0

A list of binaries to install globally into Deno (~/.deno/bin). This setting requires a list of URLs or binary configuration objects with the following fields:

  • bin (required) - URL of the binary.
  • name - Provide a custom name for the binary.
  • local - Only install the binary locally, and not in CI.
  • force - Force install the binary. This should be toggled for one-offs.
.moon/toolchain.yml
deno:
bins:
- 'https://deno.land/std@0.192.0/http/file_server.ts'
- bin: 'https://deno.land/std@0.192.0/http/file_server.ts'
name: 'fs'

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 specification to use. If this field is not defined, the global node binary will be used.

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

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

packageManager

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

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

npm, pnpm, yarn, bun

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 specification to use. If this field is not defined, the global npm, pnpm, yarn, and bun binaries will be used.

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

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

installArgsv1.22.0

Customize the arguments that will be passed to the package manager's install command, when the InstallDeps action is triggered in the pipeline. These arguments are used both locally and in CI.

.moon/toolchain.yml
node:
packageManager: 'yarn'
yarn:
installArgs: ['--immutable']

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 (npm default) - 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 (bun/pnpm/yarn 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. Furthermore, if a package manager does not support a chosen format, it will fallback to another format!

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 run through the configured package manager.

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

rootPackageOnly

Supports the "single version policy" or "one version rule" patterns by only allowing dependencies in the root package.json, and only installing dependencies in the workspace root, and not within individual projects. It also bypasses all workspaces checks to determine package locations. Defaults to false.

.moon/toolchain.yml
node:
rootPackageOnly: true
info

This setting does not verify that other package.jsons do not have dependencies, it merely runs "install dependency" commands in the root. It's up to you to ensure that other package.jsons do not have dependencies.

syncProjectWorkspaceDependencies

Will sync a project's dependencies 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

includeProjectReferenceSourcesv1.17.0

When enabled and syncing project references, will inject each project reference as an entry in the include field of the respective project's tsconfig.json. These includes are sometimes required by editors for auto-completion, intellisense, and automatic imports.

.moon/toolchain.yml
typescript:
includeProjectReferenceSources: true

To demonstrate this, we'll use the example from syncProjectReferences. When this setting is enabled, the include field will also be populated.

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

includeSharedTypesv1.17.0

When enabled, will automatically inject shared types (types/**/*) into the include field of each project's tsconfig.json. The shared types folder must be named types and must exist relative to the root setting. Defaults to false.

.moon/toolchain.yml
typescript:
includeSharedTypes: true

As a demonstration, if we had a package located at "packages/components", the include setting will be appended with:

<project>/tsconfig.json
{
// ...
"include": ["../../types/**/*"]
}

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'

root

Defines the TypeScript root (relative from moon's workspace root), where project reference composition, common compiler options, and shared types will be located. Defaults to ..

.moon/toolchain.yml
typescript:
root: './types'

rootConfigFileName

Defines the file name of the tsconfig.json found in the root of all projects. 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 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 a 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 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 dependencies:

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 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 package with the name @brand/components, the paths compiler option would be updated to the following when syncing.

If an index file exists, we'll map a default import. Otherwise, we'll always map a wildcard import. Both imports can optionally be nested within a src directory.

<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 specification to use. 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.

binsv1.10.0

A list of 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.

This setting requires a list of package names or binary configuration objects with the following fields:

  • bin (required) - Name of the binary.
  • local - Only install the binary locally, and not in CI.
  • force - Force install the binary. This should be toggled for one-offs.
.moon/toolchain.yml
rust:
bins:
- 'cargo-nextest@0.9.52'
- bin: 'cargo-nextest'
local: true

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

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

componentsv1.16.0

A list of additional components to automatically install with rustup for the current toolchain. Will be installed when the pipeline is first ran, and subsequently when configuration changes.

.moon/toolchain.yml
rust:
components:
- 'rust-docs'
- 'rust-analyzer'

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"

targetsv1.16.0

A list of additional targets to automatically install with rustup for the current toolchain. Will be installed when the pipeline is first ran, and subsequently when configuration changes.

.moon/toolchain.yml
rust:
targets:
- 'aarch64-unknown-linux-gnu'
- 'wasm32-wasi'

Targets are currently not scoped based on operating system, and will be installed for all machines.