moosebench · Node benchmark
Results from npm run moosebench — the same templating jobs, plus the
drop-in compatibility API (Writer, Context, Scanner, the config argument, function partials, cache control),
each rendered by both engines to confirm identical output, then timed on Node. Green past the 1× line means moose-stash is faster.
Throughput
faster on 16 of 17 comparable jobs
Peak speed
on the deepest job
Lines of code — packaged script, excluding comments (moose-stash.js vs mustache.js)
646 vs 463 lines of code, measured excluding comments — moose-stash does more (inheritance, dynamic partial names, render-callback lambdas), zero deps.
* All render timings — the workload jobs above and the test suite below — were measured on Node.js v22.22.2 (V8) on a 4-vCPU cloud container (Intel Xeon @ 2.10 GHz), each figure the fastest of 8 timed windows. Absolute microseconds are hardware-specific (≈1.5–2× slower than desktop Apple Silicon); the ratios are the signal. Run-to-run swing is ≈10–15% on shared-tenant vCPUs, so anything within ~0.1× of parity is a tie — big-list-2000 (≈1.0×) is such a tie.
† Drop-in means byte-for-byte parity on the 17 common, hard, and compat-surface jobs above — real templates (an HTML table, a page layout, a transactional email, deeply-nested sections, …) each rendered by both engines and compared character-for-character, plus the same public API (render, parse, escape, tags, clearCache, templateCache, Writer, Context, Scanner). Their templates and data are moose-stash's own moosebench workload.
‡ The two moose-only jobs are template inheritance ({{<parent}} / {{$block}}) and section lambdas that use the spec's render callback — neither is implemented by mustache.js 4.2.
Interpreter, not a compiler. moose-stash and mustache.js both parse a template to a token tree and walk it per render — no eval, no new Function. Compiled engines (hogan.js, wontache, mote, …) emit JavaScript and eval it, which V8 then JITs, so they render faster than either interpreter. moose-stash is the faster interpreter, and — unlike the compilers — it runs under a strict Content-Security-Policy (script-src without 'unsafe-eval') that forbids new Function.
Correctness
Two example corpora: the official Mustache spec, and mustache.js's own test suite. moose-stash reproduces every mustache.js fixture "byte-for-byte", and passes spec modules mustache.js doesn't implement.
Spec conformance
mustache.js: 142 / 194
* The 4 declined are the spec's lambda re-render cases (lambdas row above).
moose-stash never re-parses a lambda's return value as a template — doing so would let user text returned from a lambda become live
tags like {{secret}} or {{> admin}}, a server-side template-injection surface — so it emits the safe literal
output by design instead of expanding the returned tags. They are declines, not failures: the engine still produces correct, safe text.
(mustache.js 4.2 doesn't implement these either — it passes 2 of the 10 lambda cases.)