Play chess on your iPhone — against a built-in engine, or live against other people.
100% Swift: SwiftUI app, hand-written engine, Vapor multiplayer server.
- ♟️ Play the engine — four strengths from Beginner to Expert, driven by a negamax search with a transposition table, quiescence, and an opening book. Get hints, take moves back, drag or tap pieces.
- 🌍 Play people online — Bullet 1+0, Blitz 5+3, or Rapid 10+5, with rating-based matchmaking, server-enforced clocks, draw offers, Elo ratings, and a leaderboard. No sign-up: a guest account is created for you on first play and lives in your Keychain — add Sign in with Apple to recover it on a new device.
- 📈 Review every game — engine analysis of each move (best → blunder), accuracy scores, an evaluation graph, "best was …" suggestions, and full board playback. Works for engine and online games alike, and online games sync from the server, so your history follows you across devices.
All you need is a Mac with Xcode 16+ (Swift 6 toolchain, iOS 17 SDK).
git clone https://github.com/testtest126/chess.git
cd chess
open ios-chess-client/ios-chess-client.xcodeprojPress Run (⌘R), pick a color and an engine strength, and play. Hints, takebacks, and post-game review all work offline — no server needed.
Start the server, then launch the app in two simulators and tap Play Online in both — they'll be matched against each other:
swift run --package-path chess-server App serve --hostname 127.0.0.1 --port 8080Debug builds of the app connect to 127.0.0.1:8080 automatically. For a real
deployment (Postgres, JWT secret, Docker, TLS) see the
server README.
The short version is below. For the full story — an interactive module map, a single move traced end to end, the wire protocol, and the engine pipeline — see the architecture overview.
And for a different story — how this whole thing was built by a swarm of Claude agents coordinating over git, with one human steering — see the illustrated making-of, How the Agents Talked.
| Directory | What it is |
|---|---|
ChessKit/ |
Swift package, three libraries: ChessKit (board, legal moves, SAN/FEN/PGN, game state, review), ChessProtocol (engine, opening book, UCI adapter), ChessOnline (wire protocol shared by app & server) |
ios-chess-client/ |
SwiftUI app (iOS 17+) |
chess-server/ |
Vapor backend: guest auth, matchmaking, realtime games over WebSockets, clocks, Elo, history |
Three design decisions worth knowing:
- The server is authoritative. Clients mirror the game locally for highlights and SAN, but every online move is legality-checked server-side with ChessKit before it's broadcast; clocks and results are enforced there too.
- One wire protocol, compiled twice. The
ChessOnlinetarget is the single source of truth for client/server messages — no JSON drift. - The engine is deterministic (fixed-seed hashing, no randomness unless an opening book is attached), which makes search behavior testable down to exact node counts.
swift test --package-path ChessKit # rules, engine, protocol
swift test --package-path chess-server # auth + WebSocket match integrationCI runs both suites on every PR. The app's UI test suite includes a true end-to-end online match: the test process registers its own account, queues over a WebSocket, and plays engine moves against the app in the simulator.
New here? Issues tagged
good first issue
are picked to be approachable. See CONTRIBUTING.md for
setup and ground rules.