Modern chess application built with React + TypeScript + Vite, powered by the custom engine @rumenx/chess.
Supports multiple backend engines — play offline in the browser or connect to rust-chess, go-chess, or npm-chess REST APIs.
- Legal move generation & game state via
@rumenx/chess - Multi-backend support — switch between Local (in-browser), Rust, Go, and JS engines
- Backend picker with live connection status & health checking
- Move history with time-travel (jump to any ply)
- AI opponent with multiple difficulty tiers (random → depth 5 minimax w/ alpha-beta & capture ordering)
- Hint system (on-demand best move preview)
- Under-promotion support (choose promotion piece)
- Board orientation flip & side selection
- Time controls (e.g. 3+2, 5+0, 10+5, unlimited) with increments & flag detection
- Player naming (persistent) and configurable vs AI / local 2-player mode
- Persistent UI preferences (orientation, difficulty, coordinates, debug flags)
- Debug overlays (piece color & mapping diagnostics) via collapsible Developer panel
- Copy FEN / PGN export
- Responsive board sizing with CSS `clamp()`
- Modular SCSS design system
| Label | Strategy | Nominal Depth |
|---|---|---|
| Harmless | random legal move | 0 |
| Easy | minimax | 1 |
| Medium | minimax + ordering | 2 |
| Hard | minimax + ordering | 3 |
| Expert | alpha-beta + capture ordering | 4 |
| Godlike | optimized alpha-beta (throttled) | 5 |
The engine dynamically reduces depth in pathological or large branching scenarios to keep UI responsive.
Time format is `M+I` (minutes base + seconds increment). Unlimited mode disables the clocks. When a side reaches 0 the opponent wins on time; result string (`1-0` / `0-1`) reflects the flag event.
```bash git clone https://github.com/RumenDamyanov/react-chess.git cd react-chess npm install npm run dev ```
Then open: http://localhost:5173
React Chess supports four chess engines — you can switch between them at any time without losing your current game position.
| Backend | Engine | Runs In | Default URL |
|---|---|---|---|
| Local | @rumenx/chess |
Browser (no server) | — |
| Rust | rumenx-chess |
REST API | http://localhost:8082 |
| Go | go-chess |
REST API | http://localhost:8080 |
| JS | npm-chess |
REST API | http://localhost:8081 |
- Open the app at http://localhost:5173
- In the left sidebar, find the Backend Engine section
- Select an engine from the Engine dropdown (Local, Rust, Go, or JS)
- For remote backends, a URL field appears — edit it if your server runs on a different host/port
- A connection indicator shows the status:
- ⏳ Checking… — health check in progress
- ✅ Connected — backend is reachable
- ❌ Disconnected — server unreachable; click 🔄 Retry
- Start playing — the game resets with the new engine
Your selection is persisted in localStorage, so it survives page reloads.
Set the default backend before starting the dev server:
cp .env.example .envEdit .env:
# Options: local | rust | go | js
VITE_CHESS_BACKEND=rust
# Override default URLs (optional)
VITE_CHESS_RUST_URL=http://localhost:8082
VITE_CHESS_GO_URL=http://localhost:8080
VITE_CHESS_JS_URL=http://localhost:8081Then run npm run dev — the app opens with the chosen backend pre-selected.
Start the frontend and all three remote backends together:
docker compose up| Service | URL |
|---|---|
| Frontend | http://localhost:3001 |
| Rust API | http://localhost:8082 |
| Go API | http://localhost:8080 |
| JS API | http://localhost:8081 |
Once running, switch freely between all four engines in the Settings panel.
Not every backend supports every feature:
| Capability | Local | Rust | Go | JS |
|---|---|---|---|---|
| AI opponent | ✅ | ✅ | ✅ | ✅ |
| Hint | ✅ | ✅ | ✅ | ✅ |
| Undo | ✅ | ✅ | ❌ | ✅ |
| FEN load | ✅ | ✅ | ✅ | ✅ |
| PGN export | ✅ | ✅ | ✅ | ✅ |
| Analysis | ❌ | ✅ | ✅ | ✅ |
| LLM Chat | ❌ | ✅ | ✅ | ❌ |
| WebSocket | ❌ | ✅ | ✅ | ❌ |
The UI automatically warns when a feature is unavailable (e.g. "
src/
App.tsx # Composition + settings + backend picker
hooks/
useChessGame.ts # Core game + clocks + history logic
useChessBackendGame.ts # Backend-aware game hook (delegates to provider)
providers/
types.ts # BackendId, presets, normalised game types
LocalProvider.ts # In-browser provider via @rumenx/chess
RemoteProvider.ts # HTTP provider for Rust/Go/JS APIs
adapters.ts # Response normalisers per backend
BackendContext.tsx # React context (selection, health, persistence)
index.ts # Barrel export
services/
ChessAI.ts # AI difficulty + minimax search
ChessEngine.ts # Engine wrapper for local play
components/
ChessBoard/ # Board + Square rendering
MoveHistory/ # Move list & navigation
utils/ # PGN, persistence, notation helpers
styles/ # SCSS tokens & theming
tests/
providers/ # Provider & adapter tests
services/ # ChessAI & ChessEngine tests
utils/ # Notation utility tests
| Script | Purpose |
|---|---|
| `npm run dev` | Start Vite dev server (HMR) |
| `npm run build` | Production build |
| `npm run preview` | Preview production build |
| `npm run format` | Format code with Prettier |
| `npm run format:check` | Check code formatting |
| `npm run lint` | ESLint checks |
| `npm run type-check` | Run TypeScript in isolated mode |
| `npm test` | Run Jest test suite |
| `npm run test:watch` | Run tests in watch mode |
| `npm run test:coverage` | Generate coverage report |
Comprehensive test coverage for core functionality:
- 151 passing tests covering providers, services, and utilities
- 85%+ coverage on ChessAI service (difficulty levels, move selection, minimax)
- 77%+ coverage on ChessEngine wrapper (initialization, moves, game state)
- 50%+ coverage on chess notation utilities (SAN formatting, move chunking)
Run tests locally:
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:coverage # Generate coverage report| Module | Statements | Branches | Functions | Lines |
|---|---|---|---|---|
| ChessAI | 93% | 73% | 90% | 93% |
| ChessEngine | 77% | 77% | 68% | 77% |
| chessNotation | 51% | 51% | 33% | 57% |
PRs welcome! Before submitting:
- Run
npm run format:check- ensure code is properly formatted - Run
npm run lint- pass all linting checks - Run
npm run type-check- no TypeScript errors - Run
npm test- all tests must pass with coverage - Keep UI changes accessible (labels, aria-live where needed)
See the full Contributing Guide for detailed guidelines.
- WebSocket real-time game sync (rust-chess, go-chess)
- AI chat panel (LLM integration via rust-chess, go-chess)
- Opening explorer / book weighting
- Engine benchmarking panel
- Dark theme toggle
- Save slots (3 game slots)
- PGN import
- Cloud sync (optional)
- React 19 + TypeScript 5 + Vite 7
- Custom chess engine:
@rumenx/chess - Multi-backend provider layer (Local / Rust / Go / JS)
- SCSS modules (design tokens & utilities)
- Docker + Docker Compose (optional)
Explore other libraries and tools from the same developer:
- @rumenx/chess - TypeScript chess engine with legal move generation (npm)
- rust-chess - Rust chess engine + REST API (crates.io)
- go-chess - Go chess engine + REST API
- @rumenx/chatbot - AI chatbot integration library (npm)
- @rumenx/seo - SEO analysis and optimization toolkit (npm)
- @rumenx/sitemap - Dynamic sitemap generator (npm)
- @rumenx/feed - RSS/Atom feed generator (npm)
- php-chatbot - PHP chatbot framework (Packagist)
- php-geolocation - Geolocation services library (Packagist)
- php-seo - PHP SEO toolkit (Packagist)
- php-sitemap - Sitemap generation (Packagist)
- php-feed - Feed generation (Packagist)
- go.rumenx.com/chess - Go chess engine (go.rumenx.com/chess)
- go.rumenx.com/chatbot - Go chatbot framework (go.rumenx.com/chatbot)
- Code of Conduct - Community guidelines and expectations
- Contributing Guide - How to contribute to the project
- Security Policy - Responsible disclosure and security practices
- License - Open source license details
MIT © Rumen Damyanov
- Documentation: This README and linked governance docs
- Issues: GitHub Issues
- Email: contact@rumenx.com
Have an idea or spot a bug? Open an issue or propose a PR!