@gametable.one/chess-analysis

Public GPLv3 TypeScript library for Stockfish position analysis and PGN game review in the browser. Independent of GameTable's rules library; no Lichess service, account, or network API is required. The browser downloads the engine only when the application creates its worker.

Build and test

Requires Node.js 22.14+ and pnpm 12.13.0. GitZone structure: ts/, test/, .smartconfig.json, dist_ts/, and dist_bundle/. The package is marked private to prevent accidental npm publication; the Git repository is public.

corepack pnpm install --frozen-lockfile
corepack pnpm check
corepack pnpm build
corepack pnpm test
python3 -m http.server 48889 --bind 127.0.0.1
# Open http://127.0.0.1:48889/examples/browser.html for the real browser smoke test.

The build copies Stockfish 19.0.1 lite-single worker/WASM, full license, corresponding-source links and a SHA-256 manifest to dist_bundle/stockfish/. This lightweight engine trades some playing strength for a smaller download and runs without cross-origin-isolation headers. Serve the matching JS/WASM files together from your application's origin, with JavaScript and application/wasm MIME types. No CDN dependency is built into the module. Configure CSP to allow your same-origin worker and WebAssembly compilation.

Position analysis

import { StockfishAnalysis } from '@gametable.one/chess-analysis';

const engine = new StockfishAnalysis({
  workerUrl: '/assets/stockfish/stockfish-19-lite-single.js',
});
try {
  const result = await engine.analyze({
    moves: ['e2e4', 'e7e5'], // UCI coordinate notation, from the initial position
    depth: 16,
    multiPv: 3,
    onInfo: line => console.log(line),
  });
  console.log(result.bestMove, result.lines);
} finally {
  engine.dispose();
}

Copy the entire generated dist_bundle/stockfish/ directory to that asset URL. Direct browser imports can use dist_bundle/index.js. fen can override the initial position, and moves replay from it so repetition history is retained. Invalid FEN/moves and unsafe numeric limits are rejected before commands reach the engine.

All returned scores use White's perspective, including mate distance and upper/lower bounds. Positive centipawns favor White; negative favor Black. mate is separate from cp; never display a mate distance as a pawn value. Lines contain depth, MultiPV index, score and the engine's coordinate-move continuation. Candidates can have differing depths when a timed search ends. bestMove: null represents no legal move.

Each instance accepts one search at a time; overlapping calls reject. Optional moveTimeMs bounds engine search time; timeoutMs on the constructor is a response watchdog (default 60 seconds). Increase it when requesting longer searches. Pass an AbortSignal to cancel. Cancellation, worker errors, watchdog expiry and dispose() terminate the worker and reject outstanding work; create a new instance afterward. UI callbacks should not throw: a thrown progress callback also terminates the current instance. The module never silently continues a stale search.

Game review

import { reviewPgn } from '@gametable.one/chess-analysis';
const moves = await reviewPgn(engine, '1. e4 e5 2. Nf3 Nc6 *', {
  depth: 14,
  onMove: move => console.log(move.san, move.centipawnLoss),
});

Reviews the mainline sequentially, including PGN initial-position headers. Each move contains its before/after analysis, SAN, coordinate move, player and estimated centipawn loss from that player's perspective. Loss is null when either evaluation is a mate, bound, or missing score. Shallow evaluations can fluctuate; losses are estimates, not authoritative mistake labels or an accuracy rating. Variations, prose coaching, puzzle generation and opponent difficulty controls are not implemented in this first version. The results provide inputs for a training interface and best-move computer opponent.

Do not enable analysis assistance in competitive human-versus-human play. The application decides when analysis/training is available.

License and redistribution

Original module code: GPL-3.0-only. See license.md. Stockfish.js is GPLv3; chess.js is BSD-2-Clause. See third-party-notices.md for exact upstream source and build links. Deploy the generated license, source notices and manifest with the engine; retain the bundler's chess.js notices. Preserve access to the matching corresponding source for distributed binaries. Separating repositories does not by itself remove GPL obligations for integrating applications.

Validation

Tests execute the real pinned Stockfish WASM engine, not just mocked responses: MultiPV, White/Black mate orientation, terminal positions, worker reuse, invalid moves, concurrency, abort, timeout, UCI parsing and PGN review/history. The included browser smoke test exercises a real Web Worker, multiple candidate lines, mate detection and PGN review. No private GameTable code or assets are copied into this repository.

S
Description
Browser chess analysis and game review powered by Stockfish. TypeScript, Web Workers, GPLv3.
Readme GPL-3.0
152 KiB
0 Stars 3 Watchers 0 Forks
Languages
TypeScript 92.9%
JavaScript 7.1%