Stockfish.js
Stockfish.js is a WASM implementation by Nathan Rugg of the Stockfish chess engine. It is written for Chess.com's in-browser engine and is maintained as a general purpose project.
Stockfish.js is currently updated to Stockfish 19.
Prebuilt engines are published to npm and to the releases page. Please file bugs on the issue tracker.
The Engines
This edition of Stockfish.js comes in five flavors:
| Engine | Size (js + wasm) | Threads | Needs cross-origin isolation | Files |
|---|---|---|---|---|
| Full | ≈94MB | Yes | Yes | stockfish-19.js and stockfish-19.wasm |
| Full, single-threaded | ≈94MB | No | No | stockfish-19-single.js and stockfish-19-single.wasm |
| Lite | ≈1.6MB | Yes | Yes | stockfish-19-lite.js and stockfish-19-lite.wasm |
| Lite, single-threaded | ≈1.7MB | No | No | stockfish-19-lite-single.js and stockfish-19-lite-single.wasm |
| ASM-JS | ≈3MB | No | No | stockfish-19-asm.js |
A few notes on the table:
- The multi-threaded engines need the page to be cross-origin isolated so that
SharedArrayBufferis available. The server must send bothCross-Origin-Opener-Policy: same-originandCross-Origin-Embedder-Policy: require-corp. You can check the current page withcrossOriginIsolatedin the browser console. The demo server inexamples/sends these headers automatically. - The single-threaded engines run without those headers, but the UCI command
setoption name Threadshas no effect on them. - The lite engines use a much smaller neural network, so they are far smaller and quite a bit weaker.
- The ASM-JS engine is compiled to JavaScript, not WASM. It runs in essentially any browser or runtime that supports JavaScript. It is very slow and weak, and it is larger than the lite WASM engines. Use it only as a last resort.
Which engine should I use?
It depends on your project, but most likely, you should use the lite single-threaded engine because it is fast and does not require any complicated setup. Although the full engine is objectively stronger, the lite engine is still far stronger than any human will ever be, and the full engine is so large that it can be very slow to load, which would cause a poor user experience.
The WASM Stockfish engines will run on all modern browsers (e.g., Chrome/Edge/Firefox/Opera/Safari) on supported systems (Windows 10+/macOS 11+/iOS 16+/Linux/Android), as well as currently supported versions of Node.js. Node.js 14 through 18 need --experimental-wasm-threads --experimental-wasm-simd for the multi-threaded engines. For slightly older browsers, see the Stockfish.js 16 branch. The ASM-JS engine will run in essentially any browser/runtime that supports JavaScript. For an engine that supports chess variants (like three-check and crazyhouse), see the Stockfish.js 11 branch.
How do I use stockfish.js?
Stockfish.js is a raw engine. It speaks the UCI chess engine protocol over stdin and stdout in Node.js, and over postMessage in the browser. You need to bring the rest of the parts to make it into a working vehicle.
Node.js (npm)
The engines are published to npm as stockfish, and the package contains all five flavors.
npm install stockfish
The package also provides a stockfish command, so you can install it globally and use the engine interactively:
npm install -g stockfish
stockfish
To use the engine from a script, require() it as a CommonJS module:
var stockfish = require("stockfish")("lite-single", function onMessage(line) {
console.log("STDOUT:", line);
if (/bestmove \S+/.test(line)) {
console.log("The best move is " + line.match(/bestmove (\S+)/)[1] + ".");
stockfish.terminate();
}
});
stockfish.processCommand("uci");
stockfish.processCommand("go depth 10");
The first argument selects which engine to load. It can be a keyword ("full", "lite", "single", "lite-single", "asm") or a path to any stockfish.js engine file. If you leave it out, the full engine is used. Call terminate() when you are done so the process exits.
If you would rather spawn the engine yourself, findEngine() gives you the path to the engine file:
var enginePath = require("stockfish").findEngine("lite-single");
var child = require("child_process").spawn(process.execPath, [enginePath], {stdio: "pipe"});
Browser
var worker = new Worker("stockfish-19-lite-single.js");
worker.onmessage = function (ev) {
console.log(ev.data);
};
worker.postMessage("uci");
worker.postMessage("position startpos");
worker.postMessage("go depth 10");
The .js file expects the matching .wasm file to sit next to it, and both files must be served with the correct MIME types (text/javascript and application/wasm). The lite single-threaded engine works on any static host with no special configuration.
The loadEngine abstraction
examples/loadEngine.js is a small abstraction layer that works in both Node.js and the browser. It queues commands, matches output back to the command that produced it, streams info lines, reports engine download progress, and works with any UCI compatible engine, including native binaries.
The examples folder and examples/README.md show it in use.
How do I compile the engine?
You only need to compile the engine if you want to make changes to the engine itself.
In order to compile the engine, you need to have emscripten 6.0.9 installed and in your path. build.js checks your version and warns if it does not match. Add --skip-em-check to bypass the check, or --strict-em-check to turn a mismatch (or an unconfirmed version) into an error.
Then you can compile Stockfish.js with the build script:
./build.js --help # every option, with examples
./build.js # the multi-threaded WASM engine
./build.js --all # all five flavors
./build.js --bin # a native (non-WASM) Stockfish binary
Built files are written to src/, which you can change with --output-dir=dir. The npm scripts mirror the most common flavors: npm run build, npm run build-lite, npm run build-single, npm run build-single-lite.
A few things worth knowing:
- Syzygy tablebase probing is stripped from the WASM builds by default. Add
--keep-syzygyto include it. --split=6splits the WASM file into several parts, which can help browsers and CDNs that are slow with very large files.--no-splitdisables splitting.--hashappends a content hash to the generated file names, and--version=changes the version number used in them.
Repository layout
| Path | Description |
|---|---|
src/ |
The Stockfish C++ source, the emscripten glue code in src/emscripten/, and everything build.js produces |
build.js |
The build script (see ./build.js --help) |
index.js |
The Node.js interface that the npm package exposes, require("stockfish") |
scripts/findEngine.js |
Resolves an engine keyword or path to an engine file |
scripts/cli.js |
Implements the stockfish command |
scripts/prepack.js |
Builds all flavors and copies them into bin/ before packaging (bin/ is not in git) |
examples/ |
Web and Node.js examples, plus the demo server |
tests/, tester.js |
Simple engine tests |
Thanks
- exoticorn for the original Stockfish to JS conversion
- ddugovic for his Stockfish with many variants
- niklasf for his stockfish.js & stockfish.wasm
- hi-ogawa for his optimizations
- linrock for older lite nets
- sscg13 for Stockfish 19 lite nets
- Lichess WASM Builds for their patches
- The Stockfish team for everything
See AUTHORS for more credits.
License
Stockfish.js engine code is GPL v3 (see Copying.txt). The published npm package is licensed under GPL-3.0 because it contains the engine.
The non-engine code is MIT licensed.