A high-performance, modular chess engine and rules library written in pure Rust, designed to run natively and compile to WebAssembly for client-side browser execution.
Developed by Jeremy L.D. Ryan (AxolDad).
This is not Stockfish. There's no NNUE, no multi-threaded search, no endgame tablebases. This is a classical chess engine — every technique in it was state of the art before neural networks took over — and it's built to run entirely in your browser with zero backend.
The architecture is split into independent crates so the rules engine, search engine, and WebAssembly bindings never bleed into each other. The search runs in a Web Worker. The board runs on the main thread. Nothing blocks the UI.
Two engines ship in the box:
- Core-0 — A fixed-depth negamax baseline. Deliberately simple. Exists so Core-1 has something to prove itself against.
- Core-1 — The real engine. Iterative deepening, PVS, transposition tables, null-move pruning, LMR, killer/history heuristics, quiescence search. Everything you'd find in a textbook on classical search, implemented and tested.
Core-1 wins 100 out of 100 games against Core-0 in automated gauntlet testing.
| Crate | Target | Description |
|---|---|---|
chess-core |
Native / WASM | Pure rules engine: legal move generation, FEN/SAN parsing, draw conditions, perft validation, evaluation, and the Core-0 baseline engine. |
chess-search |
Native / WASM | The Core-1 classical engine: iterative-deepening PVS, transposition table, search heuristics, time management, and gauntlet testing. |
chess-wasm |
wasm32 |
wasm-bindgen boundary exposing Game and Engine to JavaScript runtimes. |
tools/replay-gen |
Native CLI | Offline build tool for converting PGN games into per-ply replay snapshots with precomputed FENs. |
- Algorithm: Fixed-depth Negamax with Alpha-Beta pruning.
- Move Ordering: Captures-first ordering via MVV-LVA.
- Evaluation: Material counting + Piece-Square Tables (PST).
- Role: Serves as a transparent, reproducible benchmark to measure search enhancements.
- Search Algorithm: Iterative Deepening with Principal Variation Search (PVS) and Aspiration Windows.
- Transposition Table: Lockless Zobrist hashing storing exact scores, lower bounds, upper bounds, and best moves.
-
Selectivity & Pruning:
- Null-Move Pruning (
$R=2$ ) with zugzwang guard. - Late Move Reductions (LMR) based on move index and depth.
- Quiescence Search with delta pruning to resolve tactical captures and promotions without Horizon effect.
- Check Extensions to ensure critical evasions are never truncated.
- Null-Move Pruning (
-
Move Ordering:
- Hash move from transposition table (highest priority).
- MVV-LVA (Most Valuable Victim – Least Valuable Aggressor) for captures.
- Killer Move heuristic (two plies).
- History heuristic table for quiet moves.
-
Game Management:
- Full game history tracking for threefold repetition detection.
- Contempt evaluation: scores neutral draws slightly negative to fight for wins against equal/inferior opponents.
- Time allocation management per move.
Engine heuristics and non-classical extensions are governed by a central hybrid configuration:
- Central Source of Truth:
chess-search/src/config.rs(EngineConfig). - Compile-Time Features: Cargo flags (
default = ["classical"], optionalnnue,experimental) keep default WASM binaries lean (~100 KB) and free of heavy dependencies. - Runtime Toggles: Search heuristics (TT, null-move pruning, LMR, aspiration windows) can be toggled via
engine.set_config(json)in the browser or viaCHESS_*environment variables on native targets. - Classical Fallback: Automatically falls back to Core-1 if an uncompiled or disabled engine tier is requested.
Core-1 is continuously verified using an automated gauntlet against Core-0:
- Test Format: 100-game match seeded with distinct two-ply openings, alternating colors.
-
Acceptance Criterion: Core-1 must win
$\ge 95%$ of games. - Result: Core-1 scores 100 wins / 0 losses / 0 draws against Core-0.
If you don't have Rust installed, grab it from rustup.rs:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shRequires Rust 1.75+ (stable recommended). Verify with:
rustc --versiongit clone https://github.com/AxolDad/Chess_Engine_in_Rust.git
cd Chess_Engine_in_RustBuild the entire workspace in release mode:
cargo build --releaseRun the full test suite — unit tests, perft validation, mate finders, and an 8-game gauntlet smoke test:
cargo testRun the full 100-game gauntlet tournament (release mode recommended for speed):
cargo test -p chess-search --release --test gauntlet -- --ignoredLint with strict compiler warnings:
cargo clippy --workspace --all-targets -- -D warningsOnly needed if you want to compile the engine for browser use.
Install the WASM target and wasm-pack:
rustup target add wasm32-unknown-unknown
cargo install wasm-packBuild the WebAssembly module:
wasm-pack build chess-wasm --target web --releaseThis produces a pkg/ directory inside chess-wasm/ containing chess_core.js and chess_core_bg.wasm, ready to import as an ES module in any web project.
Note:
wasm-optis intentionally disabled inchess-wasm/Cargo.tomldue to an upstreambinaryenissue withexternreftable growth. The unoptimized.wasmbinary is still compact (~100 KB gzipped).
The replay-gen CLI tool converts classic PGN games into per-ply JSON snapshots with precomputed FENs. It ships with four famous games (Immortal, Evergreen, Opera, Game of the Century):
cd tools/replay-gen
cargo run --release -- games/immortal-game.pgnchess-core: Perft accuracy against standard test suites, FEN/SAN roundtrips, castling legality, en-passant, pawn promotion, threefold repetition, and 50-move rule enforcement.chess-search: Mate-in-1 and mate-in-2 tactical verification, quiescence correctness, depth streaming, repetition avoidance, and gauntlet dominance.
| Board & Opponent Modes | Live Game & Checkmate |
|---|---|
![]() |
![]() |
When deployed in the browser:
chess_core_bg.wasmis loaded once as an ES module.- The UI thread instantiates
Gamefor instantaneous move validation, legal move querying, and board animations. - A background Web Worker runs the search engine via
Engine, communicating over structured JSON messages (start,go,stop,search_info,best_move). - Live search telemetry (depth, nodes evaluated, NPS, principal variation) streams back to the UI in real-time without causing frame drops.
Contributions are welcome! Please read CONTRIBUTING.md and our AI Policy for architectural guidelines, testing requirements, and code standards before opening a pull request.
Dual-licensed under either of:
- MIT License (
LICENSE-MIT) - Apache License, Version 2.0 (
LICENSE-APACHE)
at your option.
Copyright © 2026 Jeremy L.D. Ryan (AxolDad).


