moon

A Rust-based build system and monorepo orchestrator that manages toolchains, tasks, caching, and CI pipelines across the JavaScript, TypeScript, and polyglot ecosystem.

Tool
npm
v2.5.5
4,115 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
90 /100 Excellent
Development Activity 100
Maintenance 100
Community 64
Maturity 56
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
83 /100 Excellent
Architecture 88
Code Quality 85
Innovation 82
Learning Curve 75

moon is a repository management and build orchestration tool, written in Rust, that brings Bazel-style concepts to everyday JavaScript and TypeScript monorepos (and beyond). It replaces ad-hoc package.json scripts with a project graph and task graph: every workspace project declares its tasks, dependencies, and inputs/outputs in moon.yml, and moon computes what needs to run, in what order, and whether it can be skipped entirely because nothing relevant changed.

The @moonrepo/cli package published to npm is the JavaScript-facing installer for the moon binary — it pulls in a platform-specific @moonrepo/core-* optional dependency (prebuilt Rust binaries for Linux/macOS/Windows across musl/gnu/msvc targets) and exposes thin moon/moonx wrapper scripts that shell out to the native executable. The actual logic — smart hashing, remote/local caching, an integrated toolchain manager that downloads pinned versions of Node, Rust, Go, Python and other runtimes, and a WASM-based extension/plugin system (via extism and moon’s own warpgate/proto plugin protocol) — lives entirely in the Rust workspace under crates/.

What You Get

  • A project graph and task graph computed from moon.yml and workspace config, so moon knows exactly what depends on what
  • Smart hashing and incremental builds — only tasks whose inputs actually changed are re-run, locally or in CI
  • An integrated toolchain manager that downloads and pins exact versions of Node.js, Rust, Go, Python, and other runtimes per-project or workspace-wide
  • A WASM plugin system (extensions and toolchain plugins) for adding custom languages, tools, and sync behavior without forking moon itself
  • Code generation templates for scaffolding new applications, libraries, and boilerplate consistently across the repo
  • Built-in CODEOWNERS generation, git hook management, and Docker pruning helpers for polyglot monorepos

Common Use Cases

  • Replacing sprawling root-level package.json scripts with per-project moon.yml task definitions that are composable and cacheable
  • Standardizing Node/Rust/Go/Python toolchain versions across every contributor and CI runner without separate version-manager configs
  • Speeding up CI by skipping tasks whose declared inputs haven’t changed since the last successful run
  • Migrating a Yarn/npm/pnpm workspace to a real build graph incrementally, project-by-project, instead of an all-at-once rewrite
  • Generating and enforcing CODEOWNERS, git hooks, and TypeScript project references automatically as the workspace grows

Under The Hood

Architecture Execution starts in the thin crates/cli binary (main.rs/main_exec.rs), which immediately hands off to crates/app, where app.rs and session.rs build a long-lived Session object shared across a systems/ pipeline (bootstrap.rs → startup.rs → analyze.rs → execute.rs) that stages workspace discovery, project/task graph construction, and action execution as distinct phases. Individual subcommands live under commands/ (run, ci, sync, generate, docker, query, toolchain, migrate, extension, mcp, and more), each operating against graph crates built separately — project-builder, action-graph, task-expander, and task-hasher — so the graph-construction logic is decoupled from any single command. A background daemon (daemon-client/daemon-server/daemon-proto, communicating over a defined protocol) persists state between invocations, and a dedicated plugin/toolchain-plugin/extension-plugin layer loads WASM modules through extism so third-party toolchains and extensions run in a sandboxed host without touching the core binary.

Tech Stack The workspace is a 70+ crate Cargo workspace (resolver “3”) built around clap for argument parsing, tokio for async execution, starbase/starbase_console/miette for the application framework and diagnostics-rich error reporting, schematic for typed, schema-validated configuration, petgraph/daggy for the dependency graphs, blake3/sha2 for content hashing, and reqwest (rustls-backed) for network access. The WASM plugin runtime is built on extism/extism-pdk together with moon’s own proto_core/warpgate/warpgate_api crates, which also power the separate proto toolchain-version-manager project. The npm-facing @moonrepo/cli package is a minimal CommonJS wrapper (moon.js, moonx.js, utils.js) that resolves the correct @moonrepo/core-<platform>-<arch>-<libc> optional dependency via detect-libc and spawnSyncs the bundled native binary — no JavaScript build logic lives in the npm package itself.

Code Quality Tests are distributed per-crate under tests/ directories (process, cas, task-hasher, action-graph, config, docker, extension-plugin, and more all carry dedicated integration tests) alongside inline unit tests, and CI (.github/workflows/rust.yml, pr.yml, nix.yml) runs the suite across platforms plus a dedicated benchmark workflow (benchmark.yml via codspeed). clippy.toml disallows raw std::collections::HashMap/HashSet in favor of the crate’s hashing utilities, thiserror and miette give typed, diagnostic-rendered errors throughout rather than stringly-typed failures, and schematic enforces config schema validation at the type level. A justfile and Nix flake standardize local dev commands and reproducible toolchains for contributors.

What Makes It Unique Where most JavaScript monorepo tools (Turborepo, Nx) are themselves Node.js/TypeScript programs, moon’s entire task graph, hashing, and execution engine is a native Rust binary distributed as prebuilt platform binaries through npm optionalDependencies — the JS package is only a launcher. Combined with its own toolchain manager (pinning Node, Rust, Go, Python, and other runtime versions per-project) and a WASM plugin protocol shared with its sibling proto project, moon positions itself as a single orchestration layer for genuinely polyglot repositories rather than a JavaScript-first build tool with other languages bolted on.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers