.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).
$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!
extends: 'https://raw.githubusercontent.com/organization/repository/master/.moon/toolchain.yml'
Settings will be merged recursively for blocks, with values defined in the local configuration taking precedence over those defined in the extended configuration.
moon
v1.29.0
Configures how moon will receive information about latest releases and download locations.
manifestUrl
Defines an HTTPS URL in which to fetch the current version information from.
moon:
manifestUrl: 'https://proxy.corp.net/moon/version'
downloadUrl
Defines an HTTPS URL in which the moon binary can be downloaded from. The download file name is hard-coded and will be appended to the provided URL.
Defaults to downloading from GitHub: https://github.com/moonrepo/moon/releases
moon:
downloadUrl: 'https://github.com/moonrepo/moon/releases/latest/download'
JavaScript
bun
v1.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.
bun:
version: '1.0.0'
Version can also be defined with
.prototools
.
installArgs
v1.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.
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
:
bun:
dependencyVersionFormat: 'workspace'
inferTasksFromScripts: true
rootPackageOnly: true
syncProjectWorkspaceDependencies: true
deno
Enables and configures Deno.
version
v1.21.0
Defines the explicit Deno toolchain
version specification to use. If this field is not
defined, the global deno
binary will be used.
deno:
version: '1.40.0'
bins
v1.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.
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
.
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
.
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.
node:
version: '16.13'
Version can also be defined with
.prototools
or with theMOON_NODE_VERSION
environment variable.
packageManager
Defines which package manager to utilize. Supports npm
(default), pnpm
, yarn
, or bun
.
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.
node:
packageManager: 'yarn'
yarn:
version: '3.1.0'
Version can also be defined with
.prototools
or with theMOON_NPM_VERSION
,MOON_PNPM_VERSION
,MOON_YARN_VERSION
, orMOON_BUN_VERSION
environment variables.
installArgs
v1.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.
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.
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.
{
// ...
"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.
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
.
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) - Usesfile:../relative/path
and copies package contents.link
- Useslink:../relative/path
and symlinks package contents.star
- Uses an explicit*
.version
- Uses the explicit version from the dependent project'spackage.json
, e.g., "1.2.3".version-caret
- Uses the version from the dependent project'spackage.json
as a caret range, e.g., "^1.2.3".version-tilde
- Uses the version from the dependent project'spackage.json
as a tilde range, e.g., "~1.2.3".workspace
(bun/pnpm/yarn default) - Usesworkspace:*
, which resolves to "1.2.3". Requires package workspaces.workspace-caret
- Usesworkspace:^
, which resolves to "^1.2.3". Requires package workspaces.workspace-tilde
- Usesworkspace:~
, which resolves to "~1.2.3". Requires package workspaces.
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
ormoon.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.
node:
inferTasksFromScripts: true
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
.
node:
rootPackageOnly: true
This setting does not verify that other package.json
s do not have dependencies, it merely runs
"install dependency" commands in the root. It's up to you to ensure that other package.json
s do
not have dependencies.
syncPackageManagerField
v1.27.0
Will sync the currently configured package manager and its version to the
packageManager
field in the root package.json
. This setting does nothing if the package manager
or version is not defined. Defaults to true
.
node:
syncPackageManagerField: true
packageManager: pnpm
pnpm:
version: '9.0.0'
A quick example on how this works. Given the above, the following field will be injected:
{
// ...
"packageManager": "pnpm@9.0.0"
}
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
.
node:
syncProjectWorkspaceDependencies: true
A quick example on how this works. Given the following dependsOn
:
dependsOn:
- 'designSystem'
- 'reactHooks'
Would result in the following dependencies
within a project's package.json
. The version format
can be customized with node.dependencyVersionFormat
.
{
// ...
"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).
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
.
typescript:
createMissingConfig: true
includeProjectReferenceSources
v1.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.
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.
{
// ...
"include": ["../../design-system/**/*", "../../react-hooks/**/*"],
"references": [
// ...
{ "path": "../../design-system" },
{ "path": "../../react-hooks" }
]
}
includeSharedTypes
v1.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
.
typescript:
includeSharedTypes: true
As a demonstration, if we had a package located at "packages/components", the include
setting will
be appended with:
{
// ...
"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
.
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 .
.
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
.
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:
- When creating a
tsconfig.json
for a project, sets theextends
field to this value.
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
.
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.
{
// ...
"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
.
typescript:
syncProjectReferences: true
A quick example on how this works. Given the following dependencies:
dependsOn:
- 'designSystem'
- 'reactHooks'
Would result in the following references
within both tsconfig.json
s.
{
// ...
"references": [
// ...
{ "path": "../../design-system" },
{ "path": "../../react-hooks" }
]
}
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
.
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.
{
// ...
"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.
Pythonv1.30.0
python
Enables and configures Python.
version
Defines the explicit Python toolchain
version specification to use. If this field is not
defined, the global python
binary will be used.
python:
version: '3.11.10'
Python installation's are based on pre-built binaries provided by indygreg/python-build-standalone.
Version can also be defined with
.prototools
.
rootRequirementsOnly
Supports the "single version policy" or "one version rule" patterns by only allowing dependencies in
the root requirements.txt
, and only installing dependencies in the workspace root, and not within
individual projects. It also bypasses all workspaces
checks to determine package locations.
python:
rootRequirementsOnly: true
venvName
Defines the virtual environment name, which will be created in the workspace or project root when a
requirements.txt
exists, and where dependencies will be installed into. Defaults to .venv
python:
venvName: '.my-custom-venv'
pip
Optional fields for defining pip specific configuration.
installArgs
Customize the arguments that will be passed to the pip install command, when the InstallDeps
action is triggered in the pipeline. These arguments are used both locally and in CI.
python:
pip:
installArgs: ['--trusted-host company.repo.com', '-i https://company.repo.com/simple']
Rust
rust
v1.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.
rust:
version: '1.69.0'
Version can also be defined with
.prototools
.
bins
v1.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.
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:
tasks:
test:
command: 'nextest run --workspace'
binstallVersion
v1.30.0
The version of cargo-binstall
to install if it does not
already exist. Defaults to "latest" if not configured.
rust:
binstallVersion: '1.10.12'
components
v1.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.
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.
rust:
version: '1.69.0'
syncToolchainConfig: true
To demonstrate this, the settings above would sync the following file:
[toolchain]
channel = "1.69.0"
targets
v1.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.
rust:
targets:
- 'aarch64-unknown-linux-gnu'
- 'wasm32-wasi'
Targets are currently not scoped based on operating system, and will be installed for all machines.