A full-stack TypeScript application for exploring Chess.com player data, comparing players, reviewing opening trends, and analyzing saved games with a Stockfish-powered board.
This project combines a Node.js/Express backend with a React + Vite frontend to provide a complete Chess analytics workflow:
- Search and view Chess.com player profiles
- Compare two players side by side
- Review insights such as activity heatmaps, win rates, and opening stats
- Browse recent games and archive data for a username
- Authenticate users and save analysis sessions
- Analyze a game with a chess engine and review evaluated moves
- Player profile and stats dashboard
- Two-player comparison views
- Insights dashboard with activity heatmaps and win-rate summaries
- Opening explorer and repertoire analysis
- Game archive retrieval for recent Chess.com activity
- Authenticated user workflows with Google OAuth and JWT
- Saved game analysis and notes
- Stockfish browser engine analysis board
- Play with Engine gameplay with minimax difficulty levels
- Legal move indicators, evaluation bar, move sounds, focus mode, and local game persistence
- Move-by-move classifications, clickable evaluation graph, hints, best-move arrows, and accuracy summaries
- Feedback and contact form
- Node.js
- Express 5
- TypeScript
- MongoDB + Mongoose
- Passport + Google OAuth
- JWT access and refresh tokens
- Node-cache in-memory caching
- Chess.com public API integration via chess-web-api and direct archive requests
- React 19
- Vite
- TypeScript
- Tailwind CSS
- Radix UI
- Recharts
- Chess.js
- react-chessboard
- Framer Motion / Motion
- Sonner for notifications
- The
/playexperience uses material evaluation, piece-square tables, and alpha-beta minimax search. - Saved-game review uses Stockfish in a browser Web Worker and reports depth, centipawn, mate, and best-move results.
- Batch analysis and interactive evaluation use separate worker instances so hints do not interrupt batch analysis.
.
├── index.ts # Express entry point
├── package.json # Backend scripts and dependencies
├── tsconfig.json # Backend TypeScript config
├── test-db.ts # MongoDB connectivity smoke check
├── get_avatars.js # Standalone avatar utility
├── README.md
├── client/ # React frontend
│ ├── package.json
│ ├── src/
│ ├── public/
│ └── vite.config.ts
├── src/
│ ├── config/ # DB and Passport config
│ ├── controllers/ # HTTP handlers
│ ├── middleware/ # auth, rate limiting, DB readiness
│ ├── models/ # Mongoose schemas
│ ├── routes/ # Express routes
│ ├── services/ # Chess.com / auth / cache logic
│ └── utils/ # helpers, JWT, chess utilities
└── Chess_Stats_API.postman_collection.json
- Node.js 18 or newer
- MongoDB instance or MongoDB Atlas cluster
- A Chess.com username to query
- Google OAuth credentials for login
- Clone the repository:
git clone <repo-url>
cd Chess-Analytics-Engine-- Install backend dependencies:
npm install- Install frontend dependencies:
cd client
npm installCreate a .env file in the project root with the following values:
PORT=3000
MONGODB_URI=mongodb+srv://<user>:<password>@<cluster>/<database>
GOOGLE_CLIENT_ID=<google-client-id>
GOOGLE_CLIENT_SECRET=<google-client-secret>
GOOGLE_CALLBACK_URL=http://localhost:3000/auth/google/callback
JWT_ACCESS_SECRET=<long-access-secret>
JWT_REFRESH_SECRET=<long-refresh-secret>
JWT_ACCESS_EXPIRY=15m
JWT_REFRESH_EXPIRY=7d
CLIENT_URL=http://localhost:5173
NODE_ENV=developmentThe frontend also uses a client/.env file:
VITE_API_URL=http://localhost:3000If the MongoDB URI is not set, the server will still start, but database-backed routes such as auth and comments will fail until MongoDB is available.
From the project root:
npm run devThis starts the Express API on http://localhost:3000.
In a second terminal:
cd client
npm run devVite typically serves the app at http://localhost:5173.
npm run buildcd client
npm run buildcd client
npm run lintThe backend exposes route groups including:
/authfor registration, login, Google OAuth, refresh, logout, and profile updates/playerfor chess profile, stats, archives, comparisons, insights, and activity data/analysisfor authenticated saved-game analyses and evaluated moves/healthfor server health checks
Protected routes require Authorization: Bearer <access-token>.
| Route | Description |
|---|---|
/ |
Search players and access profile, statistics, comparison, and insights views |
/play |
Play against the built-in minimax engine |
/analysis |
Browse authenticated saved-game analyses |
/analysis/:gameId |
Review a game with Stockfish evaluation and move navigation |
The /play page is a self-contained practice board for playing against the built-in engine. The board is locked until the player selects Play, which prevents accidental moves while the game settings are being configured.
- Choose whether to play as White or Black.
- Select Easy, Medium, or Hard difficulty and configure the bot move delay.
- Select Play to unlock the board and start the session.
- If Black is selected, the engine automatically makes the opening move as White.
- Make legal moves by selecting a piece and then selecting a highlighted destination square.
- Continue until checkmate, a draw, resignation, or a new game is started.
- White or Black play, including an automatic engine opening move when playing Black
- Easy, Medium, and Hard minimax difficulty levels
- Click-to-select legal move indicators, capture outlines, selected-square highlighting, and move validation
- Chess.com-inspired green and cream board styling with responsive square proportions
- Evaluation bar with animated numerical evaluation after player and engine moves
- Move history with review navigation, first/previous/next/latest controls, and automatic scrolling
- Undo/takeback, board flipping, resign, reset, and play-again actions
- Move, capture, check, and checkmate audio feedback with a sound toggle
- Focus mode that hides the navbar and page heading to maximize board space
- Authenticated player profile and StockBot opponent banners
- Local game-state persistence for the board position, settings, orientation, move history, and status
Selecting Analyze from the game list opens /analysis/:gameId and hides the navbar so the review board can use the full viewport. The review page provides:
- Board styling consistent with
/play, last-move highlighting, and orientation controls - First/previous/next/latest navigation, keyboard controls, clickable move rows, and hints
- Stockfish depth, centipawn/mate evaluation, evaluation bar, graph navigation, and best-move arrows
- Inaccuracy, mistake, and blunder classifications with symbols and explanations
- Accuracy and average-loss summaries for both players
- Persistent personal notes and visible evaluation-save errors
The analysis experience is powered by a browser-based Stockfish 16 NNUE engine running inside a Web Worker. This keeps heavy engine computation off the main UI thread while allowing the app to evaluate positions, moves, and game states in real time.
- The frontend creates a dedicated worker from
client/src/engine/stockfish.worker.ts. - The worker initializes Stockfish, loads the NNUE weights, and sends a
readysignal once it is prepared to receive commands. - Each position is analyzed by sending a FEN string and a target search depth. The worker returns engine lines such as
info depth ... pv ...and the finalbestmove. - The app uses those outputs to compute a centipawn evaluation, identify the best move, and compare it against the actual move played.
- Each move is scored in terms of how much it deviates from the engine’s best continuation.
The engine flow is intentionally layered:
- Parse the PGN with Chess.js
- Reconstruct the position for each move using FEN states
- Ask Stockfish for the best move and evaluation at the current position
- Compare the played move against the engine’s recommendation
- Classify the move as a blunder, mistake, inaccuracy, good move, or best move
- Surface a human-friendly explanation and visual signal in the analysis UI
This is handled in the client engine pipeline under client/src/engine/, where the worker emits live evaluation data and the teaching layer converts raw engine output into player-friendly coaching feedback.
Instead of simply showing a raw numeric score, the app turns engine analysis into a learning tool. It can answer questions like:
- Was this move objectively best?
- Did the player miss a tactical shot?
- How much worse was the move compared to the engine line?
- Which moves were critical turning points in the game?
This makes the engine not just a calculator, but a move-review assistant that helps users understand the tactical and strategic quality of their play.
- External Chess.com requests are wrapped in backend services and cached in memory for performance.
- All public chess-data service methods use cache keys based on username or comparison request.
- Google OAuth redirects through Passport and issues JWT access and refresh tokens.
- The analysis workflow parses PGN data using Chess.js and runs engine evaluation via a dedicated Stockfish worker.
- MongoDB is optional at startup, but required for auth and other database-backed features.
- If MongoDB times out, verify the Atlas network settings and connection string.
- If Google OAuth fails, ensure the callback URL matches your Google console configuration.
- If the frontend cannot reach the API, check
VITE_API_URLand the backend port. - If the analysis board shows no engine depth, inspect the browser console and ensure the worker has started correctly.
- There is no automated test suite in this repository; manual verification is done via local development servers and the Postman collection.
- The app is designed for local development and experimentation, with
.envvalues kept out of source control.