Comparison

Where mmz sits among build systems, task runners and compiler caches — and which of them you should reach for instead.

mmz is not a build system, and most of what follows is about which tool you should be using instead of — or alongside — it.

mmzmake / ninjaBazel / BuckTurborepo / Nxsccache / ccache
Unit of worka command you namea file targeta declared actiona package taska compiler invocation
Declares depsyou do, as globsyou do, per targetyou do, exhaustivelyinferred from the graphthe compiler does
Orderingnonegraphgraphgraphnone
Replays outputexit code only—full artifactslogs + artifactsobject files
Remote cachenever—first-classfirst-classoptional
Language-awarenonenonerulesetsJS-centricC/C++/Rust
Setup costone YAML filea Makefilea build system migrationa workspace configa wrapper binary
Wrong-answer riskan under-declared scopea missing prerequisitesandboxedan inferred edgehash of the real inputs

When to use something else

You need ordering

If the answer to “what runs first?” is anything but “my task runner already knows”, mmz is the wrong tool. It has no graph and will not grow one — that is make, ninja, just, or your CI’s own dependency syntax. mmz goes on one of those, one line at a time.

You need the artifacts back

mmz caches an exit code, never output. A hit on cargo build means the build was not re-run — it does not conjure target/ back into existence. If you want a cache that restores artifacts across machines, that is Bazel, Turborepo, or a language-specific cache, and it costs the modelling those tools require.

Declared outputs are the deliberate half-measure here: mmz checks that an artifact still exists, so a cargo clean voids the record instead of leaving it fresh. It never stores or restores one.

You want compilation caching

sccache and ccache operate one compiler invocation below where mmz sits, and they know how to hash a compiler’s real inputs because they are language-aware. The two compose fine: mmz skips the whole cargo test, and sccache speeds up the runs it does not skip.

What mmz is actually for

The gap those tools leave: a project-level check that is expensive, that you run constantly, and whose real dependency is a set of files you can name.

In every case the value comes from the same trade: you declare the inputs by hand, in one readable file, and get memoization without adopting a build system.

The trade cuts both ways, and it is the whole risk surface. mmz cannot see a dependency you did not declare, and a wrongly-fresh rule is silent. A tool that sandboxes or traces its inputs makes that impossible instead — at a setup cost mmz exists precisely to avoid. Choose accordingly, and read the correctness contract before you do.