Drop-in packages that give the same answers, sooner.
Seven npm packages, including pako, acorn and esbuild, rebuilt to return byte-identical results in a fraction of the time, in Node and in the browser. They were made for Nodepod, a Node.js runtime that runs in the browser, and work anywhere the originals do. Every comparison here runs live in your browser.
Three rules every package follows
The same results
Byte-identical output, identical syntax trees, identical errors and callbacks. Each package is checked against the original on real code: 126,258 esbuild outputs, 93,841 acorn parses, 290,446 Brotli streams, and more, listed under how we check.
Faster on the benchmarks
A change only stays if the calls it touches still beat the original and none gets more than 10% slower than the previous version of the package. Size savings that broke this rule were rejected, even when they saved bytes.
No original inside
None of the packages ships the original as a fallback. What you install is the replacement alone, which is also why most of the npm downloads are smaller: pako's, for one, is 43.5 KB instead of 412.5 KB.
How much faster
Recorded on a Ryzen 7 7800X3D, in Node and Chromium, best of three rounds in fresh processes. Each row of every table is on its package's page.
Each bar spans a package's smallest to largest speedup across the rows of its results table. The dark tick is the median row.
The packages
Each page has a live comparison, an explanation of what made it faster, and where the limits are.
How they got faster
Five ideas account for nearly all of it. Each package uses a few of them.
Move the hot loop into WebAssembly
Used in pako, es-module-lexer, brotli and noble-hashes
A JavaScript engine has to guess types and guard those guesses. WebAssembly is typed and compiled ahead of time, has real 64-bit integers, and offers SIMD, which processes 16 bytes per instruction.
That is why SHA-512 gains about 5x, since JavaScript has to build 64-bit arithmetic from pairs of 32-bit numbers, while SHA-256, which a JIT already handles well, gains about 1.7x.
Engines run code fastest when objects have one consistent shape and values keep one type. fast-acorn gives every syntax-tree node type its own constructor and uses integers for token types, but keeps acorn's exact output.
esbuild-wasm is Go compiled to WebAssembly, which carries Go's runtime and a 14 MB download. Porting esbuild itself to JavaScript removes both.
Pay only for what you use
Used in every package
Tables are built the first time something needs them: pako's checksum and tree tables, Brotli's 518 KB of encoder lookup tables, each hash family's WebAssembly kernel. Modules that most callers never touch, such as acorn's generic parser for unusual plugins, load on demand.
The result is a smaller download and a start-up that costs close to what the original's did.
Copy the behaviour, then prove it
Used in every package
The ports follow the originals function by function, including their quirks, so decisions such as which match zlib emits next come out the same. Then differential tests feed the same inputs to both implementations and compare everything observable: outputs, errors, even the state of instances.
fast-noble-hashes is also mutation tested: deliberate bugs are planted in it, and the suite must catch all 41. See how we check.
Measure honestly, keep the failures
Used in every package
Benchmarks alternate the two implementations in fresh processes and keep the best of several rounds, so background load hits both alike. Ideas that did not work are written down instead of deleted: the dead ends explain, for example, why deflate cannot go much past 2x without changing its output.
Using them
Install each replacement under the name of the package it replaces, so every import, including those inside your other dependencies, gets the fast version. The major and minor versions match the originals, and the APIs and results are the originals', so this works the same in a bundler config, a Node project, a command-line tool or a browser app.
"dependencies": {
"pako": "npm:@r1ck404/fast-pako@2.1.2",
"acorn": "npm:@r1ck404/fast-acorn@8.18.2",
"acorn-jsx": "npm:@r1ck404/fast-acorn-jsx@5.3.4",
"esbuild-wasm": "npm:@r1ck404/fast-esbuild-wasm@0.28.5",
"es-module-lexer": "npm:@r1ck404/fast-es-module-lexer@1.7.2",
"brotli-wasm": "npm:@r1ck404/fast-brotli-wasm@3.0.3",
"@noble/hashes": "npm:@r1ck404/fast-noble-hashes@1.8.2"
}
pnpm can apply the same specs under pnpm.overrides to redirect transitive dependencies, and a bundler alias such as Vite's resolve.alias works too.
The packages were made for Nodepod, which does not use them yet. Versions follow the original's major and minor, so peer dependency ranges such as acorn-jsx's acorn ^8 keep working; the patch number is this project's own.