(This game is Fuentealba Cartes, Rodrigo vs Lück, Gerard - ICCF Aspirers, Group 364. I won with a tactical shot a couple years ago.)
If you’ve ever wanted to analyze a chess game, verify a tactics puzzle, or evaluate a position on the fly without loading a heavy platform or triggering third-party pop-ups, you know the feeling: most web-based chess engines are either locked behind paywalls or buried inside complex web apps.
Instead of relying on external services, I decided to build a lightweight, fully functional chess analyzer embedded directly into my website. It's powered by Stockfish and chess.js, built for fast, client-side position evaluation and simple chess database, right in your browser.
To be brutally honest, I didn't build this as a revolutionary SaaS or a productivity product. I mostly built it to drive a bit of organic traffic to my website and, let’s be real, to have a fun tech trick to show off when talking shop.
Still, it works like a charm for anyone who wants to evaluate FEN strings and game positions instantly. Here is how it works under the hood, the key web architecture challenges I ran into, and how you can try it out today.
The Architecture: Engine in the Browser
The flow is built to be fast, responsive, and 100% client-side:
-
State & Validation:
chess.jshandles game logic, move validation, legal move generation, and FEN parsing. It's the gold standard for managing chess state, move tree, and board representation in JavaScript. - UI & Board Display: An interactive board interface renders the current state and listens for user interactions or FEN input. It's also powered by chess.js, and managed via React.
- Async Evaluation: Stockfish runs as a Web Worker in the background, receiving UCI (Universal Chess Interface) commands and streaming back real-time evaluation scores and principal variations (PV). Stockfish is the world's strongest open-source chess engine.
Two Technical Challenges I Solved
1. Handling PGNs with and without Engine Analysis
The Portable Game Notation (PGN) format has existed since 1994 as a plain-text standard for chess games, containing headers, moves, and free-form comments inside braces. Over the years, conventions like [%eval] for engine evaluations, [%clk] for clocks, and [%cal]/[%csl] for arrows and highlighted squares were added. But PGN has no dedicated space for analysis.
The core architectural issue is that a single game file has two authors: the human studying or annotating it, and the machine (Stockfish) calculating evaluations and move qualities. In the file, both write to the exact same place: the move comment. An analyzed move looks like this:
14. Nxe5 { [%eval -1.20] Me pareció que ganaba un peón. +0.3 → -1.2 ?. Error. Mejor jugada: d4. Profundidad: 18 }
Exporting is easy by appending the engine text, but importing is complex. When a file is re-uploaded, the system must separate human notes from machine data across eight different languages (where "Best move" might arrive as Beste Zug or Millor jugada). Instead of searching for translated keywords, the system recognizes the engine's structure by its strict formatting contract at the end of the comment.
Furthermore, within the app, analysis is decoupled from plain text: it is stored separately and associated with each move using a key formed by the position before the move plus the move itself, rather than a static move number. This ensures that opening trees, promoted variations, or transposed move orders never misalign the analysis.
Because standard libraries like chess.js drop variations and comments when parsing PGNs, the project implements its own dedicated PGN reader and writer—ensuring that a file read and written back out remains structurally identical.
2. Preventing Stale Engine Calculations on Quick Position Changes
When a user rapidly clicks through moves or jumps across a game, Stockfish doesn’t automatically drop its current deep calculation. If left unchecked, stale evaluation messages from an old position continue to stream in asynchronously and can temporarily "flicker" or overwrite the metrics of the new position on the UI.
To keep the interface snappy and accurate, the application manages a strict cancellation flow before any new evaluation begins:
// Whenever the user changes position or moves a piece:
engine.postMessage('stop'); // Tell Stockfish to halt the current search immediately
// Send the new position state and restart calculation cleanly
engine.postMessage(`position fen ${newFEN}`);
engine.postMessage('go depth 18');
Issuing the stop command guarantees that obsolete background threads clear out instantly, ensuring the UI only reacts to the exact position the user is currently looking at.
Try It Out
The analyzer is live and accessible to everyone. You can test any FEN or set up custom board positions directly:
👉 https://www.devrfc83.com/es/ajedrez/analisis
If you don't speak Spanish (my native language), you can use the Website's language selector to redirect to the English, German, Italian, French, Dutch, Catalan, or Portuguese version of the analysis board.
EDIT: I wanted to give you this FEN so you could setup the board and start analyzing right away.
1r2k1r1/pbppnp1p/1b3P2/8/Q7/B1PB1q2/P4PPP/3R2K1 w - - 0 21
While writing this article, I learned that this tool breaks when one tries to paste a FEN. Here is a workaround though, paste this into the PGN:
[Variant "From Position"]
[FEN "1r2k1r1/pbppnp1p/1b3P2/8/Q7/B1PB1q2/P4PPP/3R2K1 w - - 0 21"]
Or, if you prefer, you can use the whole PGN from what's called "The Evergreen Game" between Adolf Anderssen and Jean Dufresne, circa 1852, which remains one of the most impressive games played.
[Event "Casual game"]
[Site "Berlin"]
[Date "1852.??.??"]
[White "Adolf Anderssen"]
[Black "Jean Dufresne"]
[Result "1-0"]
[Opening "Evans Gambit"]
1. e4 e5 2. Nf3 Nc6 3. Bc4 Bc5 4. b4 Bxb4 5. c3 Ba5 6. d4 exd4 7. O-O d3 8. Qb3 Qf6 9. e5 Qg6 10. Re1 Nge7 11. Ba3 b5 12. Qxb5 Rb8 13. Qa4 Bb6 14. Nbd2 Bb7 15. Ne4 Qf5 16. Bxd3 Qh5 17. Nf6+ gxf6 18. exf6 Rg8 19. Rad1 Qxf3 20. Rxe7+ Nxe7 21. Qxd7+ Kxd7 22. Bf5+ Ke8 23. Bd7+ Kf8 24. Bxe7# 1-0
Here is the position of the puzzle I showed, right from my analysis engine (yes, it can take pictures from certain positions too! I thought about exporting entire games as GIF, but I think that's too much for something that lives in your browser).
What's Next?
This hidden tool is open for anyone to use. Future updates might include PGN import/export, interactive arrow overlays for best engine lines, and customizable search depths. Consider that it still requires some UI work, as I kept throwing features without pondering much about organizing the features it has.
If you test it out and have feedback, feature ideas, or spot an edge case in evaluation rendering, feel free to reach out! Also, consider visiting other sections of my website, although these might not be as fun as a good old chess game.
About the Author
Hi! I'm Rodrigo Fuentealba Cartes, an entrepreneur, Bachelor of Engineering Sciences and Computer and Informatics Engineer. For more than two decades I've combined data analysis with software engineering to take projects from idea to production. Now I offer my services through a small company named Sea Dragon.
I'm also a chess player, musician, motorcyclist, amateur radio operator (license CA5NFS), and a low performance athlete.
You can find me around the web:
- Website: https://www.devrfc83.com/
- GitHub: @devrfc83
- Instagram: @devrfc83


Top comments (0)