# moon: a Rust build system and monorepo tool for the web ecosystem

> moon manages projects, tasks, tool versions and build caching across a polyglot web monorepo from a single Rust binary. It is a good fit for teams outgrowing per-package package.json scripts, and a poor fit for single-package repositories.

**moonrepo/moon** — A build system and monorepo management tool for the web ecosystem, written in Rust.

- Repository: https://github.com/moonrepo/moon
- Website: https://moonrepo.dev/moon
- Stars: 4,124 · Forks: 253
- Language: Rust
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/moonrepo-moon

## What moon solves in a multi-project repository

The README frames the problem in terms of questions every repository eventually faces: which package manager to use, which language version to use, how to import packages, how to build code. In a monorepo those questions get answered separately in every package, and the answers drift. moon's stated goal is to manage that whole process from one place.

The target user is a team working in the web ecosystem with more than one project in a repository. The README is explicit that the tool is for the web ecosystem and that its concepts are heavily inspired by Bazel. That heritage shows in the vocabulary: projects, tasks, a project graph, a dependency graph, hashing, remote caching.

Two claims in the README are worth separating from the marketing. The first is incremental adoption: moon is described as designed to be adopted project-by-project or task-by-task rather than all at once. That matters because build system migrations usually fail when they require a big-bang rewrite. The second is the script argument: package.json scripts get duplicated into every package, and contributors have to reverse-engineer which root scripts apply. moon replaces that with a project name plus a task name. If your repository does not have duplicated scripts and drifting tool versions, moon is solving a problem you do not have.

## How the task pipeline and hashing actually work

The README describes four cooperating pieces. A project graph captures dependency and dependent relationships between projects. A dependency graph captures the same for tasks. An action pipeline executes actions in parallel and in order using a thread pool and that dependency graph. Smart hashing collects inputs from multiple sources so that builds are deterministic and reproducible, and incremental builds use those hashes to rebuild only projects that changed since the last build.

The data flow implied by that description is: moon reads project and task configuration, resolves the graph, hashes each task's inputs, compares against a stored hash, skips tasks whose inputs are unchanged, and schedules the rest through the thread pool in dependency order. Remote caching extends the same hashes beyond one machine, persisting builds and caches between teammates and CI/CD environments.

The Cargo workspace confirms the shape of the implementation rather than just the pitch. The workspace depends on petgraph and daggy for graph work, blake3 with the mmap feature for hashing, and bazel-remote-apis, which points at the Bazel remote execution and caching protocol rather than a proprietary cache format. That is a real interoperability decision: a cache backend speaking the Bazel remote APIs is reachable from moon. The README does not document the exact hash inputs or how cache keys are composed, so treat remote cache hit rates as something you measure in your own repository, not something the documentation promises.

## Installing moon and running your first task

The README points to https://moonrepo.dev for documentation, and the repository's own toolchain metadata lives in a .prototools file at the root, which is the Proto version manager's configuration format. The README does not include installation commands, so check the documentation site for the current install path for your platform before anything else.

The repository's own package.json shows how the maintainers invoke a locally built binary, including a log level flag:

```bash
target/debug/moon --log trace
```

That flag combination is what the project uses for its own development runs, not a recommended production setting. The README describes the task model as a project name plus a task name, and the repository's own justfile shows the maintainers running the workspace test suite through cargo nextest with a config file:

```bash
cargo nextest run --workspace --no-fail-fast --config-file ./.cargo/nextest.toml
```

The justfile also defines a filter argument for that command, so a single package can be tested in isolation:

```bash
cargo nextest run --package {{name}} --no-fail-fast -j 4 --config-file ./.cargo/nextest.toml
```

What you should see from moon's own task execution is the task's output plus moon's reporting about which tasks ran and which were skipped because their hashes matched. The README does not give the exact output format, so do not expect a specific layout.

Tool version pinning is configured in .prototools, the same file the repository uses at its root. moon will download and install the explicit versions it finds there, per workspace or per project, according to the README's description of the integrated toolchain. The README does not show the file's syntax, so copy the format from the documentation rather than guessing keys.

## Where moon is the wrong tool

The README carries a warning that is easy to skim past: not all features are currently supported, and readers should view the documentation for an accurate list. That is an admission that the feature list in the README is aspirational in places. Action distribution across multiple machines, flakiness detection, webhook events and terminal notifications are all listed, but the README itself will not tell you which of them are live. Verify each one you depend on against the documentation before designing a workflow around it.

The second limitation is scope. moon is built for the web ecosystem. The topics list includes Go, Python and Ruby alongside JavaScript and TypeScript, but the framing throughout the README is web tooling: node_modules installation, package dependency syncing, TypeScript project references. A repository whose primary build is a C++ or JVM toolchain is outside the stated audience, and the automatic behaviors described in the README will not apply.

The third is the cost of the model itself. Smart hashing only pays off if moon can see every input that affects a task's output. A task that reads a file moon does not know about, or that depends on network state, will produce a hash that does not change when the real inputs do. The README describes collecting inputs from multiple sources but does not document the full set, so incorrect incremental builds are a failure mode you have to reason about yourself. When in doubt, the safe move is to make the task's inputs explicit in configuration rather than trusting inference.

## moon compared with Nx

Nx is the closest well-known alternative, and the difference is in what each tool assumes about your repository. Nx grew out of the JavaScript and TypeScript ecosystem and its configuration lives in the JS toolchain. moon is a Rust binary that treats JavaScript as one of several ecosystems it manages, and its concepts are drawn from Bazel, which is a general build system rather than a JS one.

That shows up in concrete places. moon's integrated toolchain downloads and installs explicit tool versions, so Node.js and other runtimes are pinned by moon rather than by whatever is on the developer's machine. Its remote caching speaks the Bazel remote APIs, per the bazel-remote-apis dependency in the Cargo workspace. Its dependency workspaces are described as working alongside package manager workspaces so projects keep distinct dependency trees, rather than replacing the package manager.

The trade-off is familiarity. A team already fluent in Nx loses that fluency and has to learn moon's project and task model, its configuration files, and its hashing behavior. A team with a polyglot repository, or one that wants build caching semantics closer to Bazel's, gets more from moon's approach. Neither is a drop-in for the other; the configuration formats and the caching backends are different.

## Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-09-23. Releases are frequent and versioned: v2.5.5 on 2026-09-15, v2.5.4 on 2026-09-03, v2.5.3 on 2026-08-24. Patch releases at roughly weekly to fortnightly intervals indicate a project that is being maintained, and the version numbering says the project is on a 2.x line, so expect incremental upgrades rather than a rewrite.

Upgrade cost is bounded by the versioning scheme but not zero. A build tool sits underneath every task in the repository, and a patch release can change hashing behavior, task scheduling or configuration parsing. The repository's own justfile shows how the maintainers gate changes: cargo check, cargo clippy with -D warnings, and cargo nextest for the test suite. Those are the project's checks on itself, not a promise about your upgrade. Pin the moon version in CI and read the changelog between versions.

The licence is MIT, which permits commercial and private use and modification with the licence and copyright notice retained. That is a permissive licence with no copyleft obligation on your own code. It says nothing about the hosted or remote caching services you might connect moon to; those are separate arrangements, and the README does not describe them.

## Conclusion

Adopt moon if you run a multi-project repository where package.json scripts have started to duplicate across packages and tool versions drift between machines; the incremental adoption model means you can migrate one project or one task at a time. Do not adopt it for a single-package repository, where the configuration overhead buys you nothing. Before committing, verify two things in the documentation: which features are actually supported today (the README states that not all listed features are currently supported), and how remote caching is configured if you want cache sharing between CI and developer machines.

## FAQ

### What is moonrepo/moon?

moon is a repository management, organization, orchestration and notification tool for the web ecosystem, written in Rust. Its concepts are heavily inspired by Bazel and other popular build systems, and it handles projects, tasks, tool versions and build caching for a monorepo.

### How do I install moon?

The README does not include installation commands. It directs readers to the documentation at https://moonrepo.dev, which is where the current install instructions for Linux, macOS and Windows live.

### How do I run a task with moon?

Tasks are addressed by project name and task name, for example moon run app:build. The README's stated goal is that knowing the project name and a task name is all you need, instead of duplicating scripts into every package.

### How does moon decide which tasks to rebuild?

The README describes smart hashing, which collects inputs from multiple sources to make builds deterministic, and incremental builds that rebuild only projects changed since the last build. The exact set of inputs is not documented in the README.

### Does moon work with remote caching?

Yes, the README lists remote caching as a feature that persists builds, hashes and caches between teammates and CI/CD environments. The Cargo workspace depends on bazel-remote-apis, which is the Bazel remote execution and caching protocol.

### What platform does moon run on?

The README states that moon runs on common development platforms: Linux, macOS and Windows. The repository's justfile sets a Windows shell of pwsh.exe for its own development commands.

## Sources

- [License: MIT](https://github.com/moonrepo/moon/blob/master/LICENSE)
- [moonrepo/moon on GitHub](https://github.com/moonrepo/moon)
- [Project website](https://moonrepo.dev/moon)
- [README](https://github.com/moonrepo/moon/blob/master/README.md)
- [Releases](https://github.com/moonrepo/moon/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/moonrepo-moon
