Skip to main content

moon.yml

The moon.yml configuration file is not required but can be used to define additional metadata for a project, override inherited tasks, and more at the project-level. When used, this file must exist in a project's root, as configured in projects.

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

dependsOn

Explicitly defines other projects that this project depends on, primarily when generating the project and task graphs. The most common use case for this is building those projects before building this one. When defined, this setting requires an array of project names, which are the keys found in the projects map.

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

A dependency object can also be defined, where a specific scope can be assigned, which accepts "production" (default), "development", "build", or "peer".

moon.yml
dependsOn:
- id: 'apiClients'
scope: 'production'
- id: 'designSystem'
scope: 'peer'

Learn more about implicit and explicit dependencies.

Metadata

idv1.18.0

Overrides the name (identifier) of the project, which was configured in or derived from the projects setting in .moon/workspace.yml. This setting is useful when using glob based project location, and want to avoid using the folder name as the project name.

moon.yml
id: 'custom-id'
info

All references to the project must use the new identifier, including project and task dependencies.

language

The primary programming language the project is written in. This setting is required for task inheritance, editor extensions, and more. Supports the following values:

  • bash - A Bash based project (Unix only).
  • batch - A Batch/PowerShell based project (Windows only).
  • go - A Go based project.
  • javascript - A JavaScript based project.
  • php - A PHP based project.
  • python - A Python based project.
  • ruby - A Ruby based project.
  • rust - A Rust based project.
  • typescript - A TypeScript based project.
  • unknown (default) - When not configured or inferred.
  • * - A custom language. Values will be converted to kebab-case.
moon.yml
language: 'javascript'

# Custom
language: 'kotlin'

For convenience, when this setting is not defined, moon will attempt to detect the language based on configuration files found in the project root. This only applies to non-custom languages!

ownersv1.8.0

Defines ownership of source code within the current project, by mapping file system paths to owners. An owner is either a user, team, or group.

Currently supports GitHub, GitLab, and Bitbucket (via app).

customGroupsBitbucket

When using the Code Owners for Bitbucket app, this setting provides a way to define custom groups that will be injected at the top of the CODEOWNERS file. These groups must be unique across all projects.

moon.yml
owners:
customGroups:
'@@@backend': ['@"user name"', '@@team']

defaultOwner

The default owner for all paths. This setting is optional in some cases but helps to avoid unnecessary repetition.

moon.yml
owners:
defaultOwner: '@frontend'

optionalGitLab

For GitLab, marks the project's code owners section as optional. Defaults to false.

moon.yml
owners:
optional: true

paths

The primary setting for defining ownership of source code within the current project. This setting supports 2 formats, the first being a list of file paths relative from the current project. This format requires defaultOwner to be defined, and only supports 1 owner for every path (the default owner).

moon.yml
owners:
defaultOwner: '@frontend'
paths:
- '**/*.ts'
- '**/*.tsx'
- '*.config.js'

The second format provides far more granularity, allowing for multiple owners per path. This format requires a map, where the key is a file path relative from the current project, and the value is a list of owners. Paths with an empty list of owners will fallback to defaultOwner.

moon.yml
owners:
defaultOwner: '@frontend'
paths:
'**/*.rs': ['@backend']
'**/*.js': []
'*.config.js': ['@frontend', '@frontend-infra']

The syntax for owners is dependent on the provider you are using for version control (GitHub, GitLab, Bitbucket). moon provides no validation or guarantees that these are correct.

requiredApprovalsBitbucket / GitLab

Requires a specific number of approvals for a pull/merge request to be satisfied. Defaults to 1.

moon.yml
owners:
requiredApprovals: 2

project

The project setting defines metadata about the project itself.

moon.yml
project:
name: 'moon'
description: 'A monorepo management tool.'
channel: '#moon'
owner: 'infra.platform'
maintainers: ['miles.johnson']

The information listed within project is purely informational and primarily displayed within the CLI. However, this setting exists for you, your team, and your company, as a means to identify and organize all projects. Feel free to build your own tooling around these settings!

channel

The Slack, Discord, Teams, IRC, etc channel name (with leading #) in which to discuss the project.

descriptionRequired

A description of what the project does and aims to achieve. Be as descriptive as possible, as this is the kind of information search engines would index on.

maintainers

A list of people/developers that maintain the project, review code changes, and can provide support. Can be a name, email, LDAP name, GitHub username, etc, the choice is yours.

name

A human readable name of the project. This is different from the unique project name configured in projects.

owner

The team or organization that owns the project. Can be a title, LDAP name, GitHub team, etc. We suggest not listing people/developers as the owner, use maintainers instead.

stackv1.22.0

The technology stack this project belongs to, primarily for categorization. Supports the following values:

  • frontend - Client-side user interfaces, etc.
  • backend - Server-side APIs, database layers, etc.
  • infrastructure - Cloud/server infrastructure, Docker, etc.
  • systems - Low-level systems programming.
  • unknown (default) - When not configured.
moon.yml
stack: 'frontend'
info

The project stack is also used in constraints and boundaries!

tags

Tags are a simple mechanism for categorizing projects. They can be used to group projects together for easier querying, enforcing of project boundaries and constraints, task inheritance, and more.

moon.yml
tags:
- 'react'
- 'prisma'

type

The type of project. Supports the following values:

  • application - An application of any kind.
  • automation - An automated testing suite, like E2E, integration, or visual tests. v1.16.0
  • configuration - Configuration files or infrastructure. v1.22.0
  • library - A self-contained, shareable, and publishable set of code.
  • scaffolding - Templates or generators for scaffolding. v1.22.0
  • tool - An internal tool, one-off script, etc.
  • unknown (default) - When not configured.
moon.yml
type: 'application'
info

The project type is used in task inheritance, constraints and boundaries, editor extensions, and more!

Tasks

env

The env field is map of strings that are passed as environment variables to all tasks within the current project. Project-level variables will not override task-level variables of the same name.

moon.yml
env:
NODE_ENV: 'production'

View the task env setting for more usage examples and information.

fileGroups

Defines file groups to be used by local tasks. By default, this setting is not required for the following reasons:

  • File groups are an optional feature, and are designed for advanced use cases.
  • File groups defined in .moon/tasks.yml will be inherited by all projects.

When defined this setting requires a map, where the key is the file group name, and the value is a list of globs or file paths, or environment variables. Globs and paths are relative to a project (even when defined globally).

moon.yml
# Example groups
fileGroups:
configs:
- '*.config.{js,cjs,mjs}'
- '*.json'
sources:
- 'src/**/*'
- 'types/**/*'
tests:
- 'tests/**/*'
- '**/__tests__/**/*'
assets:
- 'assets/**/*'
- 'images/**/*'
- 'static/**/*'
- '**/*.{scss,css}'

Once your groups have been defined, you can reference them within args, inputs, outputs, and more, using token functions and variables.

moon.yml
tasks:
build:
command: 'vite build'
inputs:
- '@group(configs)'
- '@group(sources)'

platform

The default platform for all task's within the current project. When a task's platform has not been explicitly configured, the platform will fallback to this configured value, otherwise the platform will be detected from the project's environment.

moon.yml
platform: 'node'

tasks

Tasks are actions that are ran within the context of a project, and commonly wrap an npm binary or system command. This setting requires a map, where the key is a unique name for the task, and the value is an object of task parameters.

moon.yml
tasks:
format:
command: 'prettier'
lint:
command: 'eslint'
test:
command: 'jest'
typecheck:
command: 'tsc'

extendsv1.12.0

The extends field can be used to extend the settings from a sibling task within the same project, or inherited from the global scope. This is useful for composing similar tasks with different arguments or options.

When extending another task, the same merge strategies used for inheritance are applied.

moon.yml
tasks:
lint:
command: 'eslint .'
inputs:
- 'src/**/*'

lint-fix:
extends: 'lint'
args: '--fix'
local: true

descriptionv1.22.0

A human-readable description of what the task does. This information is displayed within the moon project and moon task commands.

moon.yml
tasks:
build:
description: 'Builds the project using Vite'
command: 'vite build'

commandRequired

The command field is the command line to run for the task, including the command name (must be first) and any optional arguments. This field is required when not inheriting a global task of the same name.

moon.yml
tasks:
format:
# Using a string
command: 'prettier --check .'
# Using an array
command:
- 'prettier'
- '--check'
- '.'

By default a task assumes the command name is an npm binary, and if you'd like to reference a system command, you'll also need to set the platform to "system". We do our best to automatically detect this, but it's not accurate in all scenarios.

moon.yml
tasks:
clean:
command: 'rm -rf ./dist'
platform: 'system'

Special commands

For interoperability reasons, the following command names have special handling.

  • noop, no-op, nop - Marks the task as a "no operation". Will not execute a command in the action pipeline but can define dependencies.
  • When platform is "bun":
    • bun, bunx - Uses the binaries from the toolchain.
  • When platform is "deno":
    • Will execute with deno binary.
  • When platform is "node":
    • node, npm, pnpm, yarn - Uses the binaries from the toolchain.
  • When platform is "rust":
    • Will execute with cargo binary.

args

The args field is a collection of additional arguments to pass to the command line when executing the task. This field exists purely to provide arguments for inherited tasks.

This setting can be defined using a string, or an array of strings. We suggest using arrays when dealing with many args, or the args string cannot be parsed easily.

moon.yml
tasks:
test:
command: 'jest'
# Using a string
args: '--color --maxWorkers 3'
# Using an array
args:
- '--color'
- '--maxWorkers'
- '3'

However, for the array approach to work correctly, each argument must be its own distinct item, including argument values. For example:

moon.yml
tasks:
test:
command: 'jest'
args:
# Valid
- '--maxWorkers'
- '3'
# Also valid
- '--maxWorkers=3'
# Invalid
- '--maxWorkers 3'

deps

The deps field is a list of other tasks (known as targets), either within this project or found in another project, that will be executed before this task. It achieves this by generating a directed task graph based on the project graph.

moon.yml
tasks:
build:
command: 'webpack'
deps:
- 'apiClients:build'
- 'designSystem:build'
# A task within the current project
- 'codegen'

Args & env

Furthermore, for each dependency target, you can configure additional command line arguments and environment variables that'll be passed to the dependent task when it is ran. The args field supports a string or a list of strings, while env is an object of key-value pairs.

moon.yml
tasks:
build:
command: 'webpack'
deps:
- target: 'apiClients:build'
args: '--env production'
env:
NODE_ENV: 'production'

Dependencies of inherited tasks will be excluded and renamed according to the workspace.inheritedTasks setting. This process only uses filters from the current project, and not filters from dependent projects. Furthermore, args and env are not deeply merged.

Optional

By default, all dependencies are required to exist when tasks are being built and expanded, but this isn't always true when dealing with composition and inheritance. For dependencies that may not exist based on what's inherited, you can mark it as optional.

moon.yml
tasks:
build:
command: 'webpack'
deps:
- target: 'apiClients:build'
optional: true

env

The env field is map of strings that are passed as environment variables when running the command. Variables defined here will take precedence over those loaded with envFile.

moon.yml
tasks:
build:
command: 'webpack'
env:
NODE_ENV: 'production'

Variables also support substitution using the syntax ${VAR_NAME}. When using substitution, only variables in the current process can be referenced, and not those currently defined in env.

moon.yml
tasks:
build:
command: 'webpack'
env:
APP_TARGET: '${REGION}-${ENVIRONMENT}'

inputs

The inputs field is a list of sources that calculate whether to execute this task based on the environment and files that have been touched since the last time the task has been ran. If not defined or inherited, then all files within a project are considered an input (**/*).

Inputs support the following source types:

moon.yml
tasks:
lint:
command: 'eslint'
inputs:
# Config files anywhere within the project
- '**/.eslintignore'
- '**/.eslintrc.js'
# Config files at the workspace root
- '/.eslintignore'
- '/.eslintrc.js'
# Environment variables
- '$ESLINT_CACHE'
- '$ESLINT_*'
# Tokens
- '$projectRoot'
- '@group(sources)'
caution

When using an environment variable, we assume it's not defined by default, and will trigger an affected state when it is defined. If the environment variable always exists, then the task will always run and bypass the cache.

danger

When using globs, be aware that files that match the glob, but are ignored via .gitignore (or similar), will not be considered an input. To work around this, use explicit file inputs.

local

Marks the task as local only. This should primarily be enabled for long-running or never-ending tasks, like development servers and watch mode. Defaults to true if the task name is "dev", "start", or "serve", and false otherwise.

This is a convenience setting for local development that sets the following task options:

moon.yml
tasks:
dev:
command: 'webpack server'
local: true

outputs

The outputs field is a list of files and folders that are created as a result of executing this task, typically from a build or compilation related task. Outputs are necessary for incremental caching and hydration. If you'd prefer to avoid that functionality, omit this field.

moon.yml
tasks:
build:
command: 'webpack'
outputs:
# Relative from project root
- 'build/'

Globs can also be used if you'd like to restrict which files are cached. For example, when building a JavaScript project, you may want to include .js files, but exclude .map and other files.

moon.yml
tasks:
build:
command: 'webpack'
outputs:
- 'build/**/*.js'
- '!build/internal.js'
caution

When using globs and moon hydrates an output (a cache hit), all files not matching the glob will be deleted. Ensure that all files critical for the build to function correctly are included.

platform

The platform field defines the platform (language runtime) the command runs on, where to locate its executable, and which tool to execute it with. By default moon will set to a value based on the project's language or default platform.

  • bun - Command is a binary within node_modules and will be executed with Bun. v1.17.0
  • deno - Command is executed with Deno, or is a Deno binary located in ~/.deno/bin.
  • node - Command is a binary within node_modules and will be executed with Node.js.
  • rust - Command is executed with Cargo, or is a Cargo binary located in ~/.cargo/bin.
  • system - Command is expected to exist within the system's environment / user's shell.
  • unknown - When not configured or inferred.
moon.yml
tasks:
env:
command: 'printenv'
platform: 'system'

This field exists because of our toolchain, and moon ensuring the correct command is ran.

options

The options field is an object of configurable options that can be used to modify the task and its execution. The following fields can be provided, with merge related fields supporting all merge strategies.

moon.yml
tasks:
typecheck:
command: 'tsc --noEmit'
options:
mergeArgs: 'replace'
runFromWorkspaceRoot: true

affectedFiles

When enabled and the --affected option is provided, all affected files that match this task's inputs will be passed as relative file paths as command line arguments, and as a MOON_AFFECTED_FILES environment variable.

If there are no affected files, . (current directory) will be passed instead for arguments, and an empty value for the environment variable. This functionality can be changed with the affectedPassInputs setting.

moon.yml
tasks:
lint:
command: 'eslint'
options:
affectedFiles: true
# Only pass args
affectedFiles: 'args'
# Only set env var
affectedFiles: 'env'
caution

When using this option, ensure that explicit files or . are not present in the args list. Furthermore, this functionality will only work if the task's command supports an arbitrary list of files being passed as arguments.

affectedPassInputsv1.22.0

When affectedFiles is enabled, and no affected files are found, moon will pass . as an argument. For the most part, this works, but if you'd like to not pass the entire directory (and everything in it), and only pass the configured inputs instead, then you can enable this setting.

When enabled, moon will resolve all input globs to literal file paths, and pass them as relative arguments.

moon.yml
tasks:
lint:
command: 'eslint'
options:
affectedFiles: true
affectedPassInputs: true

allowFailurev1.13.0

Allows a task to fail without failing the entire pipeline. When enabled, the following changes occur:

  • Other tasks cannot depend on this task, as we can't ensure it's side-effect free.
  • For moon run, the process will not bail early and will run to completion.
  • For moon ci, the process will not exit with a non-zero exit code, if the only failing tasks are allowed to fail.
moon.yml
tasks:
lint:
command: 'eslint'
options:
allowFailure: true

cache

Whether to cache the task's execution result using our smart hashing system. If disabled, will not create a cache hash, and will not persist a task's outputs. Defaults to true.

We suggest disabling caching when defining cleanup tasks, one-off scripts, or file system heavy operations.

moon.yml
tasks:
clean:
command: 'rm -rf ./temp'
options:
cache: false

envFile

A boolean or path to a .env file (also know as dotenv file) that defines a collection of environment variables for the current task. Variables will be loaded on project creation, but will not override those defined in env.

Variables defined in the file support value substitution/expansion by wrapping the variable name in curly brackets, such as ${VAR_NAME}.

moon.yml
tasks:
build:
command: 'webpack'
options:
# Defaults to .env
envFile: true
# Or
envFile: '.env.production'
# Or from the workspace root
envFile: '/.env.shared'

Additionally, a list of file paths can also be provided. When using a list, the order of the files is important, as environment variables from all files will be aggregated into a single map, with subsequent files taking precedence over previous ones. Once aggregated, the variables will be passed to the task, but will not override those defined in env.

moon.yml
tasks:
build:
command: 'webpack'
options:
envFile:
- '.env'
- '.env.production'
caution

File parsing is done using the Rust dotenvy crate, which is different than the Node.js dotenv package. The biggest differences are around quote handling and variable substitution, so be aware of this!

internalv1.23.0

Marks the task as internal only. Internal tasks can not be explicitly ran on the command line, but can be depended on by other tasks.

moon.yml
tasks:
prepare:
# ...
options:
internal: true

interactivev1.12.0

Marks the task as interactive. Interactive tasks run in isolation so that they can interact with stdin.

This setting also disables caching, turns of CI, and other functionality, similar to the local setting.

moon.yml
tasks:
init:
# ...
options:
interactive: true

mergeArgs

The strategy to use when merging the args list with an inherited task. Defaults to "append".

mergeDeps

The strategy to use when merging the deps list with an inherited task. Defaults to "append".

mergeEnv

The strategy to use when merging the env map with an inherited task. Defaults to "append".

mergeInputs

The strategy to use when merging the inputs list with an inherited task. Defaults to "append".

mergeOutputs

The strategy to use when merging the outputs list with an inherited task. Defaults to "append".

outputStyle

Controls how stdout/stderr is displayed when the task is ran as a transitive target. By default, this setting is not defined and defers to the action pipeline, but can be overridden with one of the following values:

  • buffer - Buffers output and displays after the task has exited (either success or failure).
  • buffer-only-failure - Like buffer, but only displays on failures.
  • hash - Ignores output and only displays the generated hash.
  • none - Ignores output.
  • stream - Streams output directly to the terminal. Will prefix each line of output with the target.
moon.yml
tasks:
test:
# ...
options:
outputStyle: 'stream'

persistentv1.6.0

Marks the task as persistent (continuously running). Persistent tasks are handled differently than non-persistent tasks in the action graph. When running a target, all persistent tasks are ran last and in parallel, after all their dependencies have completed.

This is extremely useful for running a server (or a watcher) in the background while other tasks are running.

moon.yml
tasks:
dev:
# ...
options:
persistent: true

We suggest using the local setting instead, which enables this setting, amongst other useful settings.

retryCount

The number of attempts the task will retry execution before returning a failure. This is especially useful for flaky tasks. Defaults to 0.

moon.yml
tasks:
test:
# ...
options:
retryCount: 3

runDepsInParallel

Whether to run the task's direct deps in parallel or serial (in order). Defaults to true.

When disabled, this does not run dependencies of dependencies in serial, only direct dependencies.

moon.yml
tasks:
start:
# ...
deps:
- '~:clean'
- '~:build'
options:
runDepsInParallel: false

runInCI

Whether to run the task automatically in a CI (continuous integration) environment when affected by touched files, typically through the moon ci command. Defaults to true unless the local setting is disabled, but is always true when a task defines outputs.

moon.yml
tasks:
build:
# ...
options:
runInCI: false

runFromWorkspaceRoot

Whether to use the workspace root as the working directory when executing a task. Defaults to false and runs from the task's project root.

moon.yml
tasks:
typecheck:
# ...
options:
runFromWorkspaceRoot: true

shell

Whether to run the command within a shell or not. Defaults to true for system platform or Windows, and false otherwise. The shell to run is determined by the unixShell and windowsShell options respectively.

moon.yml
tasks:
native:
command: 'echo $SHELL'
options:
shell: true

However, if you'd like to use a different shell, or customize the shell's arguments, or have granular control, you can set shell to false and configure a fully qualified command.

moon.yml
tasks:
native:
command: '/bin/zsh -c "echo $SHELL"'
options:
shell: false

unixShellv1.21.0

Customize the shell to run with when on a Unix operating system. Accepts bash, elvish, fish, sh, or zsh. If not defined, will derive the shell from the SHELL environment variable, or defaults to sh.

moon.yml
tasks:
native:
command: 'echo $SHELL'
options:
unixShell: 'fish'

windowsShellv1.21.0

Customize the shell to run with when on a Windows operating system. Accepts bash (typically via Git) or pwsh. If not defined, defaults to pwsh.

moon.yml
tasks:
native:
command: 'echo $SHELL'
options:
windowsShell: 'bash'

Overrides

Dictates how a project interacts with settings defined at the top-level.

toolchain

bun

Configures Bun for this project and overrides the top-level bun setting.

version

Defines the explicit Bun version specification to use when running tasks for this project.

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

deno

Configures Deno for this project and overrides the top-level deno setting.

version

Defines the explicit Deno version specification to use when running tasks for this project.

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

node

Configures Node.js for this project and overrides the top-level node setting. Currently, only the Node.js version can be overridden per-project, not the package manager.

version

Defines the explicit Node.js version specification to use when running tasks for this project.

moon.yml
toolchain:
node:
version: '12.12.0'

rust

Configures Rust for this project and overrides the top-level rust setting.

version

Defines the explicit Rust version/channel specification to use when running tasks for this project.

moon.yml
toolchain:
rust:
version: '1.68.0'

typescript

disabled

Disables TypeScript support entirely for this project. Defaults to false.

moon.yml
toolchain:
typescript:
disabled: true

includeProjectReferenceSourcesv1.17.0

Overrides the workspace-level includeProjectReferenceSources setting. Defaults to undefined.

moon.yml
toolchain:
typescript:
includeProjectReferenceSources: false

includeSharedTypesv1.17.0

Overrides the workspace-level includeSharedTypes setting. Defaults to undefined.

moon.yml
toolchain:
typescript:
includeSharedTypes: false

routeOutDirToCache

Overrides the workspace-level routeOutDirToCache setting. Defaults to undefined.

moon.yml
toolchain:
typescript:
routeOutDirToCache: false

syncProjectReferences

Overrides the workspace-level syncProjectReferences setting. Defaults to undefined.

moon.yml
toolchain:
typescript:
syncProjectReferences: false

syncProjectReferencesToPaths

Overrides the workspace-level syncProjectReferencesToPaths setting. Defaults to undefined.

moon.yml
toolchain:
typescript:
syncProjectReferencesToPaths: false

workspace

inheritedTasks

Provides a layer of control when inheriting tasks from .moon/tasks.yml.

exclude

The optional exclude setting permits a project to exclude specific tasks from being inherited. It accepts a list of strings, where each string is the name of a global task to exclude.

moon.yml
workspace:
inheritedTasks:
# Exclude the inherited `test` task for this project
exclude: ['test']

Exclusion is applied after inclusion and before renaming.

include

The optional include setting permits a project to only include specific inherited tasks (works like an allow/white list). It accepts a list of strings, where each string is the name of a global task to include.

When this field is not defined, the project will inherit all tasks from the global project config.

moon.yml
workspace:
inheritedTasks:
# Include *no* tasks (works like a full exclude)
include: []

# Only include the `lint` and `test` tasks for this project
include:
- 'lint'
- 'test'

Inclusion is applied before exclusion and renaming.

rename

The optional rename setting permits a project to rename the inherited task within the current project. It accepts a map of strings, where the key is the original name (found in the global project config), and the value is the new name to use.

For example, say we have 2 tasks in the global project config called buildPackage and buildApplication, but we only need 1, and since we're an application, we should omit and rename.

moon.yml
workspace:
inheritedTasks:
exclude: ['buildPackage']
rename:
buildApplication: 'build'

Renaming occurs after inclusion and exclusion.