Skip to main content
A project is a library, application, package, binary, tool, etc, that contains source files, test files, assets, resources, and more. A project must exist and be configured within a workspace.

Overview

Projects in moon represent discrete units of code that can be built, tested, and deployed. Each project:
  • Has a unique identifier (ID) or alias
  • Can depend on other projects
  • Inherits or defines tasks
  • Has its own configuration
  • Belongs to a specific language/toolchain

Project IDs

A project identifier (or name) is a unique resource for locating a project. The ID is explicitly configured within .moon/workspace.yml, as a key within the projects setting, and can be written in camel/kebab/snake case.

ID Requirements

IDs support:
  • Alphabetic unicode characters
  • Numbers 0-9
  • Underscores _, hyphens -, forward slashes /, dots .
  • Must start with a character
.moon/workspace.yml
projects:
  sources:
    api-clients: 'packages/api-clients'
    design_system: 'packages/design-system'
    tools/build: 'tools/build'
  globs:
    - 'apps/*'
IDs are used throughout moon for configuration and CLI commands. They’re typically easier to remember and type than full file paths.

Usage Examples

# Run tasks by project ID
moon run api-clients:build
moon run design_system:test

# Query projects
moon query projects api-clients

# Check project status
moon project api-clients
Lastly, a project ID can be paired with a task ID to create a target.

Project Aliases

Aliases are a secondary approach for naming projects, and can be used as a drop-in replacement for standard IDs. An alias can be used when configuring dependencies or defining targets.

How Aliases Work

The difference between aliases and IDs is that aliases cannot be explicitly configured in moon. Instead, they are derived from the toolchain that has been detected for the project. Examples:
  • A JavaScript project uses the name field from package.json as the alias
  • A Rust project uses the package name from Cargo.toml
  • A Python project uses the package name from pyproject.toml
packages/ui/package.json
{
  "name": "@company/ui",
  "version": "1.0.0"
}
.moon/workspace.yml
projects:
  sources:
    # ID is 'ui', alias is '@company/ui'
    ui: 'packages/ui'
Now you can reference the project by either its ID or alias:
# Using ID
moon run ui:build

# Using alias
moon run '@company/ui:build'
Because of this, a project can be referenced by its name or alias, or both. Choose the pattern that makes the most sense for your company or team!

Project Dependencies

Projects can depend on other projects within the workspace to build a project graph, and in turn, an action graph for executing tasks. Project dependencies are divided into 2 categories:

Explicit Dependencies

These are dependencies that are explicitly defined in a project’s moon.yml config file, using the dependsOn setting.
apps/web/moon.yml
language: typescript

dependsOn:
  - 'design-system'
  - 'api-clients'
  - 'shared-utils'

tasks:
  build:
    command: 'vite build'
    deps:
      - '^:build'  # Build all dependencies first

Implicit Dependencies

These are dependencies that are implicitly discovered by moon when scanning the repository. How an implicit dependency is discovered is based on the project’s language setting, and how that language’s ecosystem functions. For JavaScript/TypeScript projects: Moon automatically detects dependencies from package.json:
packages/api/package.json
{
  "name": "@company/api",
  "dependencies": {
    "@company/shared": "workspace:*"
  }
}
The @company/shared dependency is automatically discovered as an implicit project dependency.

Dependency Resolution

When you run moon run web:build, moon automatically:
  1. Analyzes the dependency graph
  2. Determines the correct build order
  3. Runs dependency tasks first
  4. Executes the web build task

Project Configuration

Projects can be configured with an optional moon.yml in the project root, or through the workspace-level .moon/tasks/**/* for inherited tasks.

Basic Configuration

packages/api/moon.yml
language: typescript
layer: application

project:
  title: 'API Server'
  description: 'REST API for the application'
  maintainers:
    - 'backend-team'

tags:
  - 'backend'
  - 'api'

dependsOn:
  - 'database-client'
  - 'shared-types'

tasks:
  dev:
    command: 'node'
    args:
      - '--watch'
      - 'src/index.ts'
    preset: 'server'
  
  build:
    command: 'tsc'
    outputs:
      - 'dist'

Project Metadata

The project field allows you to add rich metadata:
moon.yml
project:
  title: 'Design System'
  description: 'Reusable UI components and design tokens'
  maintainers:
    - '[email protected]'
  channel: '#design-system'

Language and Toolchain

Specify the language and platform for the project:
moon.yml
language: typescript
layer: library
stack: frontend

toolchain:
  node: '20.0.0'  # Override workspace node version
The language setting determines which toolchain is used and how implicit dependencies are detected.

Project Types

Applications

Deployable applications that produce runnable artifacts:
apps/web/moon.yml
language: typescript
layer: application
stack: frontend

tasks:
  build:
    command: 'vite build'
    outputs:
      - 'dist'
  
  start:
    command: 'vite'
    preset: 'server'

Libraries

Reusable packages consumed by other projects:
packages/ui/moon.yml
language: typescript
layer: library
stack: frontend

tasks:
  build:
    command: 'tsup'
    outputs:
      - 'dist'

Tools

Internal tooling and scripts:
tools/codegen/moon.yml
language: typescript
layer: tooling

tasks:
  generate:
    command: 'node'
    args:
      - 'src/generate.ts'

Task Inheritance

Projects automatically inherit tasks from workspace-level configurations in .moon/tasks/. You can control this inheritance:
moon.yml
workspace:
  inheritedTasks:
    # Include only specific tasks
    include:
      - 'lint'
      - 'test'
    
    # Exclude specific tasks
    exclude:
      - 'build'
    
    # Rename inherited tasks
    rename:
      typecheck: 'type-check'
See Task Inheritance for more details.

File Groups

Define reusable file groups for use in task inputs:
moon.yml
fileGroups:
  sources:
    - 'src/**/*.ts'
    - 'src/**/*.tsx'
  tests:
    - 'tests/**/*.test.ts'
  configs:
    - '*.config.js'
    - 'tsconfig.json'

tasks:
  lint:
    command: 'eslint'
    inputs:
      - '@globs(sources)'  # Reference file group

Tags

Tags allow you to group and target multiple projects:
moon.yml
tags:
  - 'frontend'
  - 'react'
  - 'public-api'
Run tasks across all projects with a tag:
# Run tests in all frontend projects
moon run '#frontend:test'

Best Practices

Each project should have a single, well-defined purpose. Avoid creating monolithic projects that do too much.
While implicit dependencies are convenient, explicit dependencies in moon.yml make the dependency graph clearer and more maintainable.
Use tags to group related projects (e.g., by team, stack, or deployment target). This makes it easier to run tasks across multiple projects.
Use the project metadata fields to document the purpose, maintainers, and communication channels for each project.
  • Workspace - The root container for all projects
  • Tasks - Commands that run in project context
  • Targets - Project:task identifiers
  • Dependencies - Task and project dependencies

Configuration Reference

For detailed configuration options, see:

Build docs developers (and LLMs) love