A full-stack chess application demonstrating RESTful architecture, chess rule enforcement, and modern web development practices. This is a reference implementation of chess game logic with a Spring Boot backend and Next.js frontend—designed for two human players on the same machine.
This project is a portfolio-grade demonstration of:
- Chess Engine Logic: Complete implementation of chess rules including move validation, check/checkmate detection, stalemate, draw conditions, castling (with full validation), en passant, pawn promotion, and move history tracking
- PGN Export: Export games in standard Portable Game Notation format
- RESTful API Design: Clean separation of concerns with a Spring Boot backend exposing chess operations via HTTP
- Modern Frontend: React-based TypeScript UI using Next.js 13 with server and client components
- Full-Stack Integration: Real-world example of frontend-backend communication with CORS handling
This is NOT:
- A chess AI or computer opponent
- An online multiplayer service
- A production-ready deployment platform
- A database-backed application
This repository was created to:
- Demonstrate chess rule implementation - A working example of complex game logic including special moves and win condition detection
- Showcase full-stack patterns - Clean architecture with REST API, DTOs, and state management
- Serve as a learning resource - Well-documented code for developers learning chess engines or full-stack development
- Provide a reference implementation - Reusable patterns for turn-based game development
Intended Audience: Developers learning chess engine logic, full-stack development patterns, or seeking a reference implementation of chess rules validation.
- Java 17+ - Backend runtime
- Node.js 18+ - Frontend runtime
- Docker (optional) - For containerized deployment
Start Backend:
cd backend
./gradlew bootRunBackend runs on http://localhost:8080
Start Frontend (in a new terminal):
cd frontend
npm install
npm run devFrontend runs on http://localhost:3000
Open your browser: Navigate to http://localhost:3000 and start playing!
make docker-upOr manually:
docker-compose upAccess at http://localhost:3000
make dev # Run both services locally
make test # Run all tests
make docker-up # Start with DockerRun end-to-end tests to verify everything works:
cd e2e-tests
npm install
npx playwright install chromium
npm testThis will start both services, run comprehensive tests, and generate a report.
graph TB
subgraph Frontend["Frontend (Next.js, TypeScript)"]
UI["React Components<br/>(Chessboard, RightSidePanel)"]
Service["ChessService<br/>(API Client)"]
Models["TypeScript Models"]
end
subgraph Backend["Backend (Spring Boot, Java 17)"]
Controller["ChessController<br/>(REST Endpoints)"]
Game["ChessGame<br/>(Game State Manager)"]
Board["Chessboard<br/>(Move Logic & Validation)"]
DomainModels["Domain Models<br/>(ChessPiece, Position, etc.)"]
end
UI -->|User clicks| Service
Service -->|HTTP GET/POST| Controller
Controller --> Game
Game --> Board
Board --> DomainModels
Controller -->|JSON Response| Service
Service --> Models
Models -->|Props| UI
Data Flow:
- User interacts with the chessboard UI in the browser
- Frontend
ChessServicesends HTTP requests to Spring Boot backend ChessControllerdelegates toChessGamefor game state managementChessGameusesChessboardto validate moves and detect check/checkmateChessboardapplies chess rules and returns results- Backend responds with JSON containing updated board state
- Frontend updates React state and re-renders the UI
| Component | Variable | Default | Description |
|---|---|---|---|
| Frontend | NEXT_PUBLIC_API_URL |
http://localhost:8080/ |
Backend API URL |
| Backend | CORS_ALLOWED_ORIGIN |
http://localhost:3000 |
Allowed CORS origin |
| Backend | SERVER_PORT |
8080 |
Server port (Spring Boot default) |
Frontend (frontend/.env.local - optional):
NEXT_PUBLIC_API_URL=http://localhost:8080/Backend (backend/src/main/resources/application.properties):
# CORS Configuration
cors.allowed-origin=http://localhost:3000
# Springdoc OpenAPI
springdoc.api-docs.path=/api-docs
springdoc.swagger-ui.path=/swagger-ui.htmlDocker (docker-compose.yml):
- Backend exposed on port
8080 - Frontend exposed on port
3000 - Services communicate via Docker network
Interactive API documentation is available at:
http://localhost:8080/swagger-ui.html
Start the backend and navigate to Swagger UI to explore endpoints, request/response schemas, and try API calls interactively.
| Method | Endpoint | Description |
|---|---|---|
GET |
/startGame |
Initialize a new chess game |
GET |
/endGame |
End current game and clear state |
GET |
/chessGame |
Get current game state |
POST |
/move |
Make a chess move |
POST |
/getValidMoves |
Get valid moves for a piece |
GET |
/moveHistory |
Get all moves made in current game |
GET |
/exportPGN |
Export current game in PGN format |
Start a game:
curl http://localhost:8080/startGameGet current game state:
curl http://localhost:8080/chessGameMake a move (e2 to e4):
curl -X POST http://localhost:8080/move \
-H "Content-Type: application/json" \
-d '{
"source": {"row": 2, "col": 5},
"target": {"row": 4, "col": 5},
"promotionType": "Queen"
}'Get valid moves for a piece at e2:
curl -X POST http://localhost:8080/getValidMoves \
-H "Content-Type: application/json" \
-d '{"row": 2, "col": 5}'Get move history:
curl http://localhost:8080/moveHistoryExport game to PGN:
curl http://localhost:8080/exportPGNThis project intentionally does NOT include:
❌ AI Opponent - No computer player or move engine
❌ Online Multiplayer - No WebSocket or network play between different machines
❌ Persistence - No database; game state is in-memory only
❌ Authentication - No user accounts or login system
❌ Production Hardening - No load balancing, caching, or cloud deployment
These are design choices, not oversights. The project focuses on core chess logic and full-stack patterns.
- In-Memory Game State: Game is lost on server restart (no database)
- Single Game Instance: Only one game can run per server
- Two Local Players: Designed for hotseat play on the same machine
- No Time Controls: No chess clocks or time limits
The following features have been recently added:
- Stalemate Detection - Detects draw by stalemate
- Castling Through Check - Fully validated (kingside and queenside)
- Pinned Piece Validation - All edge cases handled
- Move History - Tracks all moves in a game
- PGN Export - Export games in standard chess notation
- Draw Detection - Stalemate, threefold repetition, 50-move rule
See tests in backend/src/test/java/com/backend/domain/ for implementation details.
- Simplicity: RESTful architecture is easier to understand and debug
- Stateless: Each request is independent (game state is managed server-side)
- Use Case: Two players on the same machine don't need real-time push updates
- Learning: Better for demonstrating REST API patterns
- Scope: Project focuses on chess logic, not multi-tenancy
- Simplicity: Avoids session management and game ID complexity
- Use Case: Designed for local demonstration, not production scale
- Alternative: Multi-game support would require database and session management (out of scope)
- Security: Client-side validation can be bypassed
- Single Source of Truth: Rules enforced in one place
- Testability: Easier to test game logic in Java than in UI tests
- Separation of Concerns: Frontend handles UI, backend handles business logic
- Focus: Project demonstrates chess logic and full-stack patterns, not data persistence
- Simplicity: In-memory state is easier to reason about and debug
- Fast Iteration: No migrations or schema management during development
- Portability: Runs anywhere without external dependencies
Location: backend/src/test/java/
Coverage:
- ✅ Game State Tests (
GameStateTest.java) - Check and checkmate scenarios - ✅ Chessboard Tests (
ChessBoardTest.java) - Move validation, en passant, promotion, castling - ✅ Chess Rules Tests (
ChessRulesTest.java) - En passant timing, edge cases (some disabled for future work) - ✅ Integration Tests (
ChessControllerIntegrationTest.java) - Full API flow testing
Run Tests:
cd backend
./gradlew testPhilosophy: Focus on chess rule correctness and API contract validation. Edge cases are documented with TODO comments.
Location: frontend/src/app/_client_components/*.test.tsx
Coverage:
- ✅ Component Rendering - Chessboard and RightSidePanel render correctly
- ✅ Game State Display - Check/checkmate states displayed properly
- ✅ Smoke Tests - Components don't crash with various props
Run Tests:
cd frontend
npm testPhilosophy: Focus on component behavior and rendering. API calls are tested in integration tests.
Location: e2e-tests/
Coverage:
- ✅ Application Boot - Backend and frontend startup validation
- ✅ Game Initialization - Board setup and initial state
- ✅ Legal Moves - Basic move validation (e2-e4, e7-e5)
- ✅ Illegal Move Rejection - Move validation and error handling
- ✅ Special Rules - Valid moves API, pawn promotion, castling, en passant
- ✅ Check and Checkmate - Fool's Mate detection
- ✅ Complete Game - Scholar's Mate end-to-end scenario
- ✅ UI Interactions - Chessboard loading, move highlighting, invalid move rejection
- ✅ Non-Goals Validation - Documented limitations verification
- ✅ API Validation - All REST endpoints
- ✅ Security Posture - Authentication, secrets, CORS
Run Tests:
cd e2e-tests
npm install
npx playwright install chromium
npm test # Run UI browser tests
npm run test:legacy # Run legacy API-focused testsPhilosophy: Black box testing from a real user's perspective. Uses only public interfaces (HTTP API and browser UI). Tests behavior, not implementation.
UI Browser Tests (tests/chess-ui.test.ts):
- Browser-based tests using Playwright
- Test complete game scenarios (e.g., Scholar's Mate)
- Validate UI rendering and interactions
- Run with
npm test(starts services automatically via webServer config)
Legacy API-Focused Tests (tests/chess-api.test.ts):
- API-centric tests for core functionality
- Validate request/response schemas and status codes
- Run with
npm run test:legacy
What's Implemented:
- ✅ CORS: Restricts cross-origin requests to configured frontend URL
- ✅ No Secrets: No API keys, passwords, or tokens required
What's NOT Implemented:
- ❌ HTTPS/TLS: All communication is plain HTTP
- ❌ Authentication: No login or user verification
- ❌ Authorization: No access control
- ❌ Input Sanitization: Minimal validation beyond chess rules
- ❌ Rate Limiting: No protection against spam requests
- ❌ CSRF Protection: Not applicable (no session management)
If you want to deploy this publicly:
- Use HTTPS - Add a reverse proxy (nginx, Caddy) with TLS certificates
- Add Authentication - Implement OAuth2 or JWT if tracking users
- Input Validation - Add bean validation annotations to DTOs
- Rate Limiting - Use Spring rate limiting or API gateway
- Dependency Scanning - Enable Dependabot (already configured)
- Secret Management - Use environment variables, never commit secrets
Recommendation: Keep this as a localhost-only demo. For production chess, use established platforms.
TODO: Add screenshots of:
- Chessboard in initial state
- Valid move highlighting
- Checkmate state
- Pawn promotion modal
No live demo is hosted. Run locally with make dev or make docker-up.
- FEN Import/Export - Import and export positions using standard FEN notation
- Undo/Redo - Full undo/redo support with game state snapshots
- AI Opponent - Basic minimax AI with alpha-beta pruning (depth-3 search)
- Chess Engine Documentation - Comprehensive extraction guide for reusable core
See CHESS_ENGINE_EXTRACTION_GUIDE.md for details on how to extract the chess engine as a standalone library.
See CHESS_ENGINE_API.md for complete API documentation.
The following new endpoints have been added:
| Method | Endpoint | Description |
|---|---|---|
POST |
/importFEN |
Import game position from FEN notation |
GET |
/exportFEN |
Export current position to FEN notation |
GET |
/undo |
Undo the last move |
GET |
/redo |
Redo a previously undone move |
GET |
/undoRedoStatus |
Check if undo/redo are available |
GET |
/aiMove |
Get AI suggested move using minimax |
- Frontend UI for FEN - UI controls for FEN import/export
- Frontend UI for Undo/Redo - Undo/redo buttons in the UI
- Frontend AI Toggle - Enable/disable AI opponent in UI
- Extract Chess Engine - Create separate Gradle module (see extraction guide)
- ❌ Online Multiplayer - Out of scope (use dedicated platforms)
- ❌ Database - Intentionally in-memory
- ❌ User Accounts - Not applicable for local hotseat play
- ❌ Production Deployment - Demo project, not a service
Contributions are welcome! Please read CONTRIBUTING.md for:
- Development setup
- Code style guidelines
- Testing requirements
- Pull request process
- What contributions are accepted
Quick Links:
This project is open source. See LICENSE file for details (if available).
- Chess piece SVGs from public domain sources
- Spring Boot and Next.js communities
- Contributors and testers
Built with: Java 17, Spring Boot 3.1, Next.js 13, TypeScript 5, React 18
Maintained by: mgierschdev