Skip to main content


Tasks are commands that are ran in the context of a project. Underneath the hood, a task is simply a binary or system command that is ran as a child process.


A task name (or identifier) is a unique resource for locating a task within a project. The name is explicitly configured as a key within the tasks setting, and can be written in camel/kebab/snake case. Names support a-z, A-Z, 0-9, _, -, /, ., and must start with a character.

A task name can be paired with a scope to create a target.


Tasks are grouped into 1 of the following types based on their configured parameters.

  • Build - Task generates one or many artifacts, and is derived from the outputs setting.
  • Run - Task runs a one-off, long-running, or never-ending process, and is derived from the local setting.
  • Test - Task asserts code is correct and behaves as expected. This includes linting, typechecking, unit tests, and any other form of testing. Is the default.


Alongside types, tasks can also grouped into a special mode that provides unique handling within the dependency graph and pipelines.

Local only

Tasks either run locally, in CI (continuous integration pipelines), or both. For tasks that should only be ran locally, for example, development servers and watchers, we provide a mechanism for marking a task as local only. When enabled, caching is turned off, the task will not run in CI, terminal output is not captured, and the task is marked as persistent.

To mark a task as local only, enable the local setting.

command: 'start-dev-server'
local: true


Tasks that need to interact with the user via terminal prompts are known as interactive tasks. Because interactive tasks require stdin, and it's not possible to have multiple parallel running tasks interact with stdin, we isolate interactive tasks from other tasks in the dependency graph. This ensures that only 1 interactive task is ran at a time.

To mark a task as interactive, enable the options.interactive setting.

command: 'init-app'
interactive: true


Tasks that never complete, like servers and watchers, are known as persistent tasks. Persistent tasks are typically problematic when it comes to dependency graphs, because if they run in the middle of the graph, subsequent tasks will never run because the persistent task never completes!

However in moon, this is a non-issue, as we collect all persistent tasks within the dependency graph and run them last as a batch. This is perfect for a few reasons:

  • All persistent tasks are ran in parallel, so they don't block each other.
  • Running both the backend API and frontend webapp in parallel is a breeze.
  • Dependencies of persistent tasks are guaranteed to have ran and completed.

To mark a task as persistent, enable the local or options.persistent settings.

command: 'start-dev-server'
local: true
# OR
persistent: true


Tasks can be configured per project through moon.yml, or for many projects through .moon/tasks.yml.


View the official documentation on task inheritance.