A chess cognitive training platform with three exercises targeting board visualization, notation recall, and coordinate recognition. Features animated move playback, progressive difficulty scaling, timed challenges, and a scoring engine with streak bonuses.
Train Now -- chessbenchmark.netlify.app
Watch an opening play out move-by-move on an animated chessboard, study the resulting position, then recreate the moves from memory by dragging pieces.
SELECTION --> SHOWING (animated playback) --> STUDYING (memorize position) --> RECALL (drag pieces) --> RESULTS
Visual Feedback:
| Element | Color | Behavior |
|---|---|---|
| Piece trail (FROM squares) | #F1C40F yellow |
Persists for 4 moves, then fades |
| Destination flash (TO squares) | Yellow pulse | Flashes 1000ms on arrival |
| Square activity heat | Accumulated opacity | Repeated touches glow brighter |
Difficulty Tiers:
| Tier | Study Time | Animation Speed |
|---|---|---|
| Beginner | 10s | 1200ms/move |
| Club | 8s | 1000ms/move |
| Expert | 6s | 800ms/move |
| Master | 4s | 600ms/move |
Both study time and animation speed are independently adjustable via custom sliders.
Memorize the SAN (Standard Algebraic Notation) for an opening sequence, then type it back after the timer expires. Correct answers advance the level by +2 moves (up to 20). Incorrect answers hold the current level.
SELECTION --> STUDY (view notation) --> RECALL (type it back) --> RESULTS
| Tier | Study Time |
|---|---|
| Beginner | 10s |
| Club | 7s |
| Expert | 5s |
| Master | 3s |
A square is highlighted on the board -- type its algebraic coordinate (e.g., e4) before time runs out. Ten rounds per session.
SELECTION --> PLAYING (identify square) --> FEEDBACK --> ... --> RESULTS
| Tier | Time Per Square |
|---|---|
| Beginner | 5.0s |
| Club | 3.0s |
| Expert | 2.0s |
| Master | 1.0s |
Three classical openings with 20-move mainlines used across exercises:
- Ruy Lopez --
1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 ... - King's Indian Defense --
1. d4 Nf6 2. c4 g6 3. Nc3 Bg7 ... - Queen's Gambit Declined --
1. d4 d5 2. c4 e6 3. Nc3 Nf6 ...
Spatial Memory uses the first 5-6 moves for board animation. Verbal Memory uses all 20 moves for progressive recall.
points = 100 (base) + timeBonus + streakBonus
timeBonus = floor((timeLimit - responseTime) / 100)
streakBonus = currentStreak * 10
Faster responses yield higher time bonuses. Consecutive correct answers build a streak multiplier. Any miss resets the streak to zero.
Score accumulates per correct move recalled, with streak tracking across rounds. Points scale with move count and difficulty tier.
Score and streak persist across levels. Each correct full-sequence recall awards points and advances to the next level (+2 moves). Best score tracked per session.
All exercises share a GamePhase enum that drives UI rendering:
SELECTION --> active gameplay phases --> RESULTS
Each phase controls which panels render, which timers are active, and which inputs are enabled. Transitions are managed via useCallback with timer cleanup to prevent memory leaks.
| Hook | Purpose |
|---|---|
useTimer |
Countdown timer with useRef-based interval management and automatic cleanup on unmount |
useGameScoring |
Score accumulation, streak tracking, round management, and best-score persistence |
useMobile |
Responsive breakpoint detection (900px threshold) for layout switching |
Each exercise follows an orchestrator pattern:
page.tsx (orchestrator)
--> SelectionPanel.tsx # Opening + difficulty selection
--> GameBoard.tsx # Interactive chessboard with phase-aware behavior
--> StudyPanel.tsx # Notation display (Verbal Memory only)
--> RecallPanel.tsx # User input capture
--> ResultsPanel.tsx # Score breakdown + replay option
The orchestrator page owns all state and passes props downward. Components are pure renderers with no internal state management.
react-chessboard receives:
position-- FEN string fromchess.jsgame statecustomSquareStyles-- dynamic highlighting computed per framearePiecesDraggable-- toggled per phase (locked during study, enabled during recall)animationDuration-- 0 for instant feedback, configurable during playback
- Desktop: Side panel + center board + right controls (flex row)
- Mobile: Stacked vertical layout with compact score card, smaller board (360px vs 480px), and full-width controls
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) |
| Language | TypeScript 5 |
| Chess Engine | chess.js |
| Board Renderer | react-chessboard |
| Styling | Tailwind CSS 3.4 + inline styles |
| Icons | react-icons |
| Font | Geist Sans + Geist Mono (local woff) |
| Testing | Vitest 4 + React Testing Library + jsdom |
| CI | GitHub Actions (lint, build, test) |
| Build | Static export (next export) |
| Hosting | Netlify (static CDN) |
src/
├── app/
│ ├── exercises/
│ │ ├── layout.tsx # Error boundary wrapper
│ │ ├── coordinate-vision/
│ │ │ ├── page.tsx # Orchestrator
│ │ │ └── components/
│ │ │ ├── SelectionPanel.tsx
│ │ │ ├── GameBoard.tsx
│ │ │ └── ResultsPanel.tsx
│ │ ├── game-memory/
│ │ │ ├── page.tsx # Orchestrator
│ │ │ └── components/
│ │ │ ├── SelectionPanel.tsx
│ │ │ ├── GameBoard.tsx
│ │ │ └── ResultsPanel.tsx
│ │ └── san-memory/
│ │ ├── page.tsx # Orchestrator
│ │ └── components/
│ │ ├── SelectionPanel.tsx
│ │ ├── StudyPanel.tsx
│ │ ├── RecallPanel.tsx
│ │ └── ResultsPanel.tsx
│ ├── globals.css
│ ├── layout.tsx # Root layout
│ ├── page.tsx # Landing page
│ └── project.ts # App metadata
├── components/
│ ├── Card.tsx # Exercise card with Next.js Link
│ ├── ErrorBoundary.tsx # React error boundary
│ ├── ExerciseList.tsx # Exercise card grid
│ └── Header/Header.tsx # Navigation bar with logo
├── config/
│ ├── difficulty.ts # Centralized difficulty presets
│ └── openings.ts # Chess opening definitions
├── hooks/
│ ├── useMobile.ts # Responsive breakpoint hook
│ ├── useGameScoring.ts # Score/streak/round management
│ └── useTimer.ts # Countdown timer with cleanup
└── utils/
├── chessUtils.ts # Square generation, formatting
└── styles.ts # Shared slider styles, colors
- Node.js 20+
- npm or Bun
git clone https://github.com/claygeo/chess-benchmark.git
cd chess-benchmark
npm install
npm run devOpen http://localhost:3000.
| Command | Description |
|---|---|
npm run dev |
Start dev server with hot reload |
npm run build |
Static export to out/ directory |
npm run start |
Serve production build locally |
npm run lint |
ESLint with auto-fix |
npm test |
Run unit & component tests (Vitest) |
npm run test:watch |
Run tests in watch mode |
63 tests across 10 test files covering utilities, hooks, and components.
| Layer | Framework | Files |
|---|---|---|
| Unit tests | Vitest + jsdom | src/utils/__tests__/, src/hooks/__tests__/ |
| Component tests | Vitest + React Testing Library | src/components/__tests__/, src/app/exercises/*/__tests__/ |
npm test # run all tests
npm run test:watch # watch modeCI pipeline runs on every push and PR via GitHub Actions: lint, build, and test.
Benchmarked on Netlify CDN (April 2026). Grade: A (8/8 budget checks passing).
| Page | Full Load | First Load JS |
|---|---|---|
| Homepage | 287ms | 97.6 KB |
| Spatial Memory | 749ms | 126 KB |
| Verbal Memory | 147ms | 92.9 KB |
| Coordinate Vision | 150ms | 118 KB |
Shared JS across all routes: 87.3 KB (React runtime + shared components). All pages statically exported to CDN with zero server-side rendering overhead.
| Check | Result |
|---|---|
| ESLint | 0 warnings, 0 errors |
| TypeScript | Strict mode, no errors |
| Unit & Component Tests | 63/63 passing |
| Build | All 5 routes export successfully |
| QA (browser testing) | Health score: 97/100 |
| Security Audit | 0 findings (static site, no backend/auth/secrets) |
Configured for static export on Netlify. next.config.mjs sets output: 'export' to generate a fully static site -- no server-side rendering, no API routes, no Node.js runtime required.
# netlify.toml
[build]
command = "npm run build"
publish = "out"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
force = falseDeploy to any static hosting provider by pointing to the out/ directory.
This repository represents the frontend implementation of a collaborative client project. The development responsibilities were divided as follows:
- Frontend Development: Complete implementation of all UI components, training exercises, responsive design, and client-side functionality (this repository)
- Backend Development: Server architecture, APIs, database design, and backend logic (implemented by separate developer, not included in this repository)
All frontend code -- including the training algorithms, UI/UX design, responsive layouts, and interactive features -- represents original implementation work.
Special thanks to @danmandel for the client work opportunity.
Proprietary -- All rights reserved.



