Ninja’s home page describes it in a single phrase: “a small build system with a focus on speed.” Where most build systems try to be high-level languages, Ninja deliberately positions itself as an assembler. Its manual explains that “build systems get slow when they need to make decisions,” so Ninja omits that decision-making and instead expects an external program, such as CMake or gn, to do the high-level analysis up front and generate Ninja’s build files.
The design goals are explicit in the manual: “very fast (i.e., instant) incremental builds, even for very large projects,” minimal policy about build conventions, and correct dependency handling, particularly tracking C and C++ header dependencies. When these priorities conflict, Ninja chooses speed over convenience, and it deliberately rejects hand-written build files, built-in compilation rules, and runtime customization.
Ninja grew out of work on the Chromium browser project, which the manual notes contains over 30,000 source files. Previous build systems took roughly ten seconds to even start compiling after a single file changed; Ninja reduced that to under one second. Because build files are meant to be generated rather than written by hand, Ninja is almost always paired with a higher-level generator like CMake, which emits Ninja files as one of its output formats.