One script, three features, three sites (chess.com, lichess.org, and endgame.ai):
- Analyzer — draws the top 3 engine move suggestions (plus a dashed ponder arrow) directly on the board, with a live score badge.
- Full-strength engine — Stockfish 19 with the full NNUE network (~95MB, downloaded once and cached by the browser), the same engine the Chess Analyzer web app uses.
- Relay — mirrors the game you are playing to the web app's Live tab on any other device via a session ID.
- Install a userscript manager extension in your browser (e.g., Violentmonkey, Tampermonkey, or similar).
- Open your userscript manager and select Create a new script.
- Copy all the code from the
userscript.jsfile in this repository. - Paste the code into the script editor and click Save.
- Refresh your chess game page, and the analyzer is ready to use!
- A — Show or hide the move suggestions (starts/stops the analyzer).
- Insert — Hide or show the Analyze button. Useful for keeping the interface clean; the 'A' hotkey still works while the button is hidden.
- Ctrl+Shift+C or Ctrl+Shift+X — Copy your Relay ID to the clipboard (a small toast confirms and shows the ID). There is no persistent relay UI.
- On chess.com the script fetches the full Stockfish 19 NNUE build from chess.0xpnj.dev and runs it in a worker. First start shows "Loading engine… (one-time ~95MB)"; after that it starts instantly from the browser cache. If the download fails it falls back to chess.com's built-in engine.
- On lichess the script runs the same engine: it downloads it through
Tampermonkey's
GM_xmlhttpRequest(declared in the header — approve thechess.0xpnj.devpermission if your userscript manager asks) and caches the ~95MB in IndexedDB, so it downloads once ever, not once per page. - lichess variants (King of the Hill, Three-Check, Antichess, Atomic,
Horde, Racing Kings, Crazyhouse) run on Fairy-Stockfish 14 with the
variant's NNUE network, the engine lichess's own analysis uses
(lichess-org/stockfish-web,
fetched from jsDelivr at a pinned version and checked against its
SHA-256). Each network comes once from lichess's asset host (about 1MB for
antichess and horde, 48-59MB for the others), is checked against the hash
in its name and cached. Approve the
cdn.jsdelivr.netandlichess.orgpermissions if asked. Where threads are not available, or it fails, the script falls back to multi-variant Stockfish 10 (lichess-org/stockfish.js, GPLv3, ~0.6MB). Crazyhouse pockets and three-check counters are read from the page; a suggested drop shows as a ringed square with the piece letter. lichess variant games are not relayed: the web app follows them straight from lichess by username. - chess.com variants (the 4 Player & Variants server): Crazyhouse, 3 Check, King of the Hill, Atomic, Giveaway, Horde and Racing Kings run on multi-variant Stockfish 10, since chess.com pages cannot run the threaded Fairy-Stockfish. The extension version runs Fairy-Stockfish with the variant's NNUE network there too, from its own offscreen page, which a userscript cannot have. No Castling, and Setup Chess once both sides have set up, are standard chess for Stockfish 19. Torpedo, Sideways Pawns, Petrified, Paradigm Chess30, Seirawan Chess, Chaturanga and Duck Chess need Fairy-Stockfish, so in the userscript they show "Variant needs the extension". Banked pieces, the side to move and the checks given are read from the board and its move list. Any other variant there (Fog of War, Spell Chess, Blindfold, 4 Player, custom rules) shows "Variant not supported" instead of arrows. Games of the supported variants, the Fairy-Stockfish ones included, are relayed with their variant, start position and moves, so the web app follows, analyzes and reviews them.
- Chess960 (all three sites): the engine runs in Chess960 mode, with castling rights taken from the game's start position (looked up once per game from the site's own game API; on chess.com's variants server, read from the page). A suggested castle is drawn to the king's landing square, or as the rook's move when the king already stands there. A Chess960 game on the variants server is relayed with its start position and moves, so the web app follows it like any other game.
- endgame.ai: the script runs the same Stockfish 19 NNUE build as on chess.com (cached in IndexedDB) without site-engine fallback. In Secret Queen games, hidden queens (own square + revealed pieces from API/DOM badges) are analyzed as queens. Includes Secret Queen Threat Overlay (red dashed danger lines and target beacons from all living opponent pawns) and auto-detection toast alerts when opponent pawns or their Secret Queen are captured. Both appear only once endgame.ai's API confirms the game is Secret Queen.
- On the game page press Ctrl+Shift+C or Ctrl+Shift+X — your Relay ID is copied to the clipboard (a small toast shows it). The ID stays the same on this browser.
- In the Chess Analyzer web app: Live tab → Session ID → paste the ID → Connect Session.
- Every move appears on the web app's board within ~2 seconds with engine suggestions; when the game ends, a full Game Review starts automatically.
Positions are sent as small JSON messages through the public
ntfy.sh pub/sub relay under the topic chessweb-<id>.
Messages contain only the position (FEN) and the player usernames shown on the
page. Anyone who knows the random ID could read them, so treat the ID like a
private link.
Relay on lichess: lichess's page security policy blocks plain fetches, so
the script sends through Tampermonkey's GM_xmlhttpRequest (approve the
ntfy.sh permission if asked). The extension version works out of the box
(its isolated world is exempt). If neither channel is available the relay goes
quiet — you can always use the web app's Live → lichess username watch,
which needs no relay at all.
- Analyzer is stuck or arrows don't appear: press 'A' twice (off and on again). This resets the engine and resyncs it with the current board.
- "Engine unavailable": the engine failed to load or crashed more than three times in a row (it restarts by itself before that — usually an interrupted ~95MB download). Press 'A' twice to retry from scratch.
- "Engine unavailable" on lichess: the engine could not be loaded,
usually because the userscript manager denied the
chess.0xpnj.devpermission. Grant it (or use the extension version), then press 'A' twice.
The same script ships as a Chrome extension in the sibling
chess-analyzer folder (scripts/main.js is generated from userscript.js).