
moonrepo quickstart: what are the exact steps to get it running in an existing monorepo?
Most teams discover Moonrepo after they already have a working monorepo and just want the exact steps to plug it in without breaking anything. This guide walks through a practical, copy‑pasteable quickstart for getting Moonrepo running in an existing monorepo, including configuration, task migration, and basic verification.
1. Prerequisites and assumptions
Before you start, make sure:
- You already have an existing monorepo (e.g. with JavaScript/TypeScript, Rust, Go, etc.)
- You have:
- Node.js (for most setups)
- Git (Moon uses Git metadata)
- A terminal and permission to install binaries
Optional but recommended:
- A package manager set up (pnpm, npm, yarn, bun)
- CI access (GitHub Actions, GitLab CI, CircleCI, etc.) for later integration
Note: These steps are written to be minimal and safe to try. You can add Moonrepo alongside your current workflow and gradually migrate tasks.
2. Install Moonrepo CLI in your repo
The easiest and most portable way is via the official installer script. From the root of your monorepo:
curl -fsSL https://moonrepo.dev/install.sh | bash
This will:
- Download the Moon binary into
./.moon/binby default - Create a small shell wrapper so you can run
moondirectly
If you want it in node_modules/.bin instead (for JS-centric repos):
curl -fsSL https://moonrepo.dev/install.sh | bash -s -- --node
Verify installation:
moon --version
You should see a version output; if not, ensure ./.moon/bin (or the correct path) is on your PATH, or call it directly:
./.moon/bin/moon --version
3. Initialize Moonrepo in an existing monorepo
From the root of your repo:
moon init
You’ll be prompted for a few options (these may evolve, but in general):
- Language / ecosystem (e.g.
node,typescript,rust, etc.) - Project layout (e.g.
packages/*,apps/*,services/*) - Whether to create example configs
If you want a non-interactive quickstart, you can pass flags, for example:
moon init --language node --preset node --yes
After running, you should see something like:
moon.yml– workspace-level config.moon/– Moon’s internal cache and binaries (do not commit the whole directory; only what docs suggest)- Possibly some starter task files like
.moon/tasks.yml(depending on options)
4. Understand Moonrepo’s basic concepts (in 2 minutes)
You can get productive without knowing everything, but these fundamentals are key:
-
Workspace (
moon.yml)
Defines:- Project conventions (how Moon detects packages/apps)
- Global tasks
- Tools configuration
-
Projects
Each app/package is a “project” (e.g.packages/api,apps/web). Moon can auto-detect them from package manifests or config files. -
Tasks
Named commands likelint,test,build,typecheck. They can:- Run in multiple projects at once
- Be cached and only re-run when inputs change
- Be wired into dependency graphs
You’ll mainly touch:
moon.yml- Per-project task config (for JS this is often
package.jsonplus Moon conventions, or amoon.ymlper project)
5. Configure project detection for your existing layout
Open the generated moon.yml at your repo root. For a typical JavaScript/TypeScript monorepo, a common structure is:
apps/
web/
admin/
packages/
ui/
api/
Configure Moon to recognize these projects. A simple moon.yml might look like:
# moon.yml
projects:
# Automatically detect Node/JS projects by package.json
- id: "apps"
source: "apps/*"
language: "javascript"
- id: "packages"
source: "packages/*"
language: "javascript"
# Optional: set Node-specific settings
node:
packageManager: "pnpm" # or "npm" | "yarn" | "bun"
version: "22.0.0" # or whatever your team uses
For other ecosystems:
- Rust: use
Cargo.toml-based detection - Go: use Go module layout
- Polyglot: you can mix multiple
projectsentries with differentlanguagevalues
Run a quick detection check:
moon query projects
You should see a list of detected projects. If some are missing:
- Confirm
sourceglobs inmoon.ymlmatch your folder layout. - Ensure each project has a recognizable manifest (
package.json,Cargo.toml, etc.) or define a per-projectmoon.ymlinside those directories.
6. Mirror your existing scripts as Moon tasks
To get value quickly, start by mapping the scripts you already use (NPM scripts, Make targets, etc.) into Moon tasks.
6.1 Identify your common commands
Look at package.json files (for JS) or your CI configuration and list:
linttestbuilddev/starttypecheck
Example package.json:
{
"scripts": {
"lint": "eslint .",
"test": "vitest",
"build": "tsc -p tsconfig.build.json",
"dev": "next dev"
}
}
6.2 Create workspace-level tasks (optional but handy)
You can define tasks once and reuse them across projects. In moon.yml, add:
tasks:
lint:
command: "lint"
platform: "node"
options:
runFromProject: true
test:
command: "test"
platform: "node"
options:
runFromProject: true
build:
command: "build"
platform: "node"
options:
runFromProject: true
This configuration tells Moon:
- Run the
linttask by invoking the project’s script namedlint(usuallynpm run lint/pnpm lint). - Do it from within each project directory (
runFromProject: true).
Alternatively, you can declare per-project moon.yml files if you need different commands per project.
7. Verify basic tasks across all projects
From the repo root, run:
moon lint
Moon will:
- Detect all projects that have the
linttask available - Run them, respecting the dependency graph and parallelism
Similarly:
moon test
moon build
If a task fails:
- Check the output for the failing project path
- Confirm that project actually has the underlying script/command you referenced
- Adjust
moon.ymlor the project’spackage.jsonas needed
8. Hook into your dependency graph
Moonrepo is powerful when it knows project dependencies (e.g. web depends on ui, api depends on shared).
For Node/TS monorepos using a package manager workspace (pnpm, yarn, npm workspaces), Moon can often infer the graph from package.json dependencies/devDependencies. If that’s your case, you may not need manual configuration.
If you want to be explicit (or are in a different ecosystem), you can add per-project config. Example apps/web/moon.yml:
type: "application"
dependsOn:
- "packages/ui"
- "packages/api"
Now running:
moon build apps/web
Will:
- Build
packages/ui - Build
packages/api - Then build
apps/web
…in the correct order, using caching when possible.
9. Enable caching so tasks don’t re-run unnecessarily
Moon’s incremental task cache is a core feature. To leverage it, you need good inputs and outputs configuration so Moon knows when a task is “the same” and can be restored.
In moon.yml:
tasks:
test:
command: "test"
platform: "node"
inputs:
- "src/**"
- "tests/**"
- "package.json"
- "vitest.config.*"
outputs:
- "coverage/**"
Now:
- Run
moon testonce. - Make no changes and run
moon testagain.
You should see logs indicating a cache hit and near-instant completion.
Customize inputs/outputs per task (workspace-level or per-project) for best results.
10. Add Moonrepo to CI without breaking your current pipeline
You don’t have to rewrite your CI all at once. Start by adding a Moon job in parallel or as an experiment.
Example GitHub Actions snippet:
name: CI
on:
push:
branches: [ main ]
pull_request:
jobs:
moon:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install Moon
run: |
curl -fsSL https://moonrepo.dev/install.sh | bash
- name: Install dependencies
run: pnpm install # or yarn install / npm ci / bun install
- name: Run Moon tasks
run: |
moon lint
moon test
moon build
Once you’re comfortable, you can replace older ad‑hoc scripts with moon commands, benefitting from caching and consistent task orchestration.
11. Gradually migrate legacy scripts to Moon tasks
To integrate Moonrepo cleanly into an existing monorepo:
- Keep existing
package.jsonscripts / Makefiles for now. - Wrap them in Moon tasks so every common operation has a
moon <task>equivalent. - Start using Moon locally:
moon lintmoon testmoon build
- Update CI to use Moon for those steps.
- Once stable, you can:
- Simplify or remove redundant scripts
- Introduce more advanced Moon features (pipelines, target inheritance, more granular caching)
This incremental approach avoids big-bang refactors and allows the team to get comfortable with Moonrepo.
12. Quick checklist: exact steps in order
If you just want a short, actionable checklist for “moonrepo quickstart: what are the exact steps to get it running in an existing monorepo?”:
-
From repo root, install Moon:
curl -fsSL https://moonrepo.dev/install.sh | bash -
Initialize Moon workspace:
moon init -
Edit
moon.ymlto:- Configure
projectsto match yourapps/*,packages/*, etc. - (Optional) Set
node.packageManagerandnode.versionif using Node.
- Configure
-
Verify project detection:
moon query projects -
Define core tasks in
moon.yml(or per project), mapping to existing commands:tasks: lint: command: "lint" platform: "node" options: runFromProject: true test: command: "test" platform: "node" options: runFromProject: true build: command: "build" platform: "node" options: runFromProject: true -
Optionally set inputs/outputs to enable caching for tasks (e.g. for
testandbuild). -
Run tasks across the monorepo:
moon lint moon test moon build -
Configure dependency graph (if not auto-detected) via per-project
moon.ymlwithdependsOnentries. -
Add Moon to CI, using
moon lint,moon test, andmoon buildin your pipeline. -
Iterate: refine tasks, caching, and project configuration as your team adopts Moonrepo.
Follow these steps and you’ll have Moonrepo running smoothly in your existing monorepo with minimal disruption, ready to evolve into a more powerful, cache‑aware, graph‑driven workflow.