Hey HN, Miles and James here from Moonrepo (
https://moonrepo.dev). Are you struggling with large codebases? Well look no further! We built Moonrepo to simplify repository management, project ownership, task running, and everyday developer and productivity workflows.
If you’ve used Bazel (or another “enterprise” build system) in the past, you’re probably aware of how complex they can be to setup, configure, and use. Let alone the cognitive overhead required by developers on a day to day basis. After more than a decade in the industry, with many of those years working on infrastructure and developer tooling related products, we set out to build Moon, a language agnostic build system.
Existing systems focused solely on runtime logistics (faster builds, concurrency), while we want to also focus on the developer experience. We do this by automating workflows as much as possible, in an effort to reduce manual work. We constantly sync and verify configuration, so that the repository stays in a healthy state. We also infer/detect as much as we can from the environment/repository/codebase, so pieces "just work".
We wanted our system to be enjoyable to use and easy to understand, but also solve the same problems as existing systems. For example, configuration is in YAML, not a proprietary syntax. Tasks are defined and run as if you were running them in the terminal; no more abstractions like BUILD files. Unlike Bazel, we don’t hide or heavily rewrite terminal output, so the feedback loop is what you expect. We manage a toolchain, ensuring the correct version of languages is used (no more “works on my machine”). And lastly, our foundation is built on Rust and Tokio, so performance is first-class, the runtime is reliable, and memory safety is guaranteed.
We follow the open core model. Moon is open source, but we’re also working on a few subscription-based services for monitoring and improving your continuous integration pipelines, a registry of project and code ownership, a continuous deployment/delivery board, auxiliary application systems, and more. We haven't finalized the subscription model yet, so there's no pricing information on the website. However, we do have a starter/free tier that everyone can use by registering on https://moonrepo.app. In the future, we will offer on-prem as well.
Although Moonrepo is relatively new, we’re already feature-packed, stable, and used in production. We’re big fans of honest feedback, and look forward to your comments!
But abstractions are a good thing! They let you separate a system into layers, so that things programmed at a higher layer don't need to know all the details of the lower layers. It's the way we separate interface from implementation.
Let me give an example from Bazel. Suppose you are compiling some C or C++, and you need to define a preprocessor symbol. There are two ways of doing this, "defines" and "local_defines":
You can use "defines" when you have #ifdef statements in headers and "local_defines" when you only test the symbols in your .cc files.I did not have to think about how defines will propagate to the libraries that depend on me, I just specified what I need and the build system handles the rest. I did not have to define my own CXXFLAGS variable and handle concatenating all of the right things together. The lower layer takes care of that.
What Bazel lets you do is create abstraction boundaries within the build system. People can write rules that define a self-contained set of build logic, then other people can use those abstractions without knowing all the details of how they are implemented.
Bazel is not perfect, and I have found myself banging my head against the wall many times. But overall the ability to define abstractions in a build system is, I think, one of the biggest things it gets right.
Disclosure: I work for Google, but not on Bazel.