Own product · Play & Learn Chess

A chess platform, built from the first move.

chessGM is a free chess app: live online games, human-like bots, full game reviews with a voice coach, rated puzzles and courses, in English, Bangla and Hindi. We wrote the chess engine, the server, the apps and the voice service ourselves, and we run them on our own infrastructure.

Live on the web. The iOS app is in App Review and the Android app is in closed testing: coming soon to the App Store and Google Play.

  • Web (PWA)
  • Android
  • iOS
  • iPadOS
rated puzzles, every one engine-verified
15,200
courses, plus a track that starts from zero
60
Elo against Stockfish 19 limited to 3000 (200 games; Stockfish’s own scale)
+164
p99 move write in a load test with 2,500 concurrent games
3 ms

Inside the app

Real screens from the shipping app, as they appear in the store listings.

What players get

  • Live online play

    Quick pairing at bullet, blitz, rapid and classical, rated or casual, with server clocks, Glicko-2 ratings, friends, challenges, messages and spectating.

  • Bots that play like people

    13 original characters and bots inspired by famous players’ public games (not affiliated). Each makes the mistakes a human of its rating would make.

  • Game review with a coach

    Blunder arrows on the board, “See the line” with spoken steps, move-label badges and a coach panel that explains why. Accuracy is calibrated against 739 public chess.com games (typical difference about 4 points) and move labels are tuned against chess.com’s Game Review. Not affiliated with chess.com.

  • Puzzles and Puzzle Rush

    About 15,200 rated puzzles with themes, hints and a daily puzzle. Puzzle Rush in 3 min, 5 min and Survival, plus online Rush Battle with its own rating.

  • Courses with spaced repetition

    30 opening courses of about 50 lines each, 30 tactics, middlegame and endgame courses, and a beginner track from a 200 rating. Every line is engine-verified and reviewed with FSRS.

  • A coach that explains and speaks

    Our chess engine and explanation rules, not a chatbot, write what was found, what was missed and why a move was bad, in English, Bangla and Hindi. A voice service running open-source voice models speaks it; the voices are machine-generated. No outside AI service is called.

  • Works offline, and can notify you

    Puzzles, bots, two-player games and the analysis board work offline on the website and in the Android app. Website notifications work in desktop and Android browsers; on iPhone, after adding the site to the Home Screen.

  • Free, with daily limits and consent

    No in-app purchases. Some features have free daily limits (10 hints, 3 deep reviews, 3 calls, 3 voice-chat games) and a rewarded ad in the apps adds one more of each. New players get an ad-free start, and ads follow the player’s consent choices (personalised ads only with consent). Sign in with Google, Apple or email, and delete your account in the app.

  • Beat the bots, one rung at a time

    A ladder of 13 practice bots, from the easiest to the hardest, with our own guide for each, practice partners, review of games you paste in as text, puzzles made from your mistakes and saved progress. It never connects to anyone else’s bots.

  • Learn how to defeat your opponent

    Type a chess.com username: your browser reads that player’s recent public games from chess.com’s public data API, and chessGM turns them into a plan with steps and reminders. Not affiliated with Chess.com.

  • Voice chat and calls

    Voice only, no video. Audio goes directly between the two devices (through a relay only when a direct connection is not possible); our server passes the setup messages and nothing is recorded or stored. Free each day: 3 voice-chat games and 3 answered calls.

  • Boards and pieces

    Our own chessGM piece sets and boards, plus four premium sets of original artwork: Ebony & Boxwood, Royal Gold, Marble and Crystal. They are all free; “Premium” is only a label.

Built from scratch

Every layer is ours, from the rules of the game to the server it runs on.

  1. One Go server

    A single Go binary serves the HTTP API and the WebSocket hub, and runs the game clocks, matchmaking, a fleet of 1,200 house-bot accounts (always labelled as bots), and the puzzle and course engines.

    • Go
    • WebSocket
    • SQLite (WAL)
    • Glicko-2
  2. Our own chess engine

    Bitboard move generation verified with perft and an alpha-beta search, all written in Go. Full strength adds a small neural network (NNUE) that we trained ourselves, mainly on lichess’s open evaluations, with some positions scored by Stockfish as a teacher; no other engine’s network weights are used. It measures about 3160 on Stockfish 19’s UCI_Elo scale (200-game matches at 10+0.1, single thread; the previous engine measured 2840), a scale that is not FIDE or website Elo. Newer versions are stronger still. The same engine runs on the server, with a larger network, and compiled to WebAssembly in the browser and the apps, with a smaller one. Game Review, the coach and the lower bots use the earlier frozen engine, so their numbers stay put.

    • Go
    • Bitboards
    • NNUE
    • WebAssembly
  3. Web app

    A static SvelteKit app in TypeScript, with a service worker for offline play and languages loaded only when needed.

    • SvelteKit
    • TypeScript
    • Service worker
    • PWA
  4. iOS and Android apps

    Capacitor apps with native sign-in, ads with consent, push notifications, native speech and an offline copy of the app built into the iOS version.

    • Capacitor
    • AdMob
    • Firebase Cloud Messaging
    • APNs
  5. Voice service

    A text-to-speech service in Go with a small C helper on sherpa-onnx, running open neural voice models and caching what it says. The same models also run in the browser.

    • Go
    • C
    • sherpa-onnx
    • onnxruntime-web
  6. Voice chat and calls

    Peer-to-peer WebRTC audio between the two devices, with a relay when a direct path is blocked. The server only passes the setup messages and counts the free daily limits.

    • WebRTC
    • TURN

Operations

We run the servers ourselves

No game-backend service in between: our own server, our own deploys, our own monitoring.

  • One self-managed Linux server behind nginx and Cloudflare, with TLS end to end
  • The game server runs as a systemd service; WebSockets pass through nginx
  • One-command deploys: build, upload a timestamped release, switch, health-check, keep old releases for instant rollback
  • Many deploys a day, each switching over in seconds, with a holding page during the restart
  • SQLite in WAL mode with nightly backups
  • Content Security Policy, client IPs trusted only from Cloudflare, cross-origin writes refused, WebSocket rate limits

Hard problems we solved

The parts players never see, with the numbers we measured.

  1. Saving every move without slowing the game

    The problem
    Under load, writing each move straight to the database pushed the slowest writes to about 100 ms.
    What we did
    Moves are batched and written behind the game every 250 ms, on SQLite in WAL mode, while clocks stay on the server.

    Result p99 move write about 100 ms → 3 ms with 2,500 concurrent games in a load test. Profile query 17 ms → 1.1 ms.

  2. Accuracy players can trust

    The problem
    Players compare their accuracy score with the numbers they already know from the big chess sites.
    What we did
    We calibrated our accuracy model on 739 real games against chess.com’s published scores (we are not affiliated), and tested it on games it had never seen.

    Result A typical difference of about 4 points of accuracy on held-out games, with a correlation of 0.9. Move labels agree with chess.com’s exactly about half the time, and the counts are close.

  3. Puzzles with exactly one answer

    The problem
    A puzzle with two good answers, or one already seen as a mirror image, feels broken to the player.
    What we did
    We generate puzzles in-house from engine self-play and human-model games. A deep engine search proves every solver move is the only one, and duplicates are removed, including colour and board mirrors.

    Result About 15,200 rated puzzles, including about 4,900 new ones from the latest run.

  4. Offline on iPhone, with ads still working

    The problem
    Apple’s web view allows offline service workers only with app-bound domains, and app-bound domains break AdMob.
    What we did
    The next iOS build carries its own offline copy of the web app, with native shared storage that syncs when the connection comes back.

    Result Full offline play on iOS for +0.06 MB of app size, in the next store build.

  5. Fast on slow networks

    The problem
    Many of our players are on mobile data, and the review page jumped around while it loaded.
    What we did
    A static build, languages loaded on demand, reserved space for every board and panel, and a service worker cache.

    Result First contentful paint 2.8 s → 1.0 s on slow 4G. Layout shift on the review page 0.81 → 0.

  6. Scores nobody can forge

    The problem
    Leaderboards invite cheating when the phone decides what counts as a correct answer and how long it took.
    What we did
    Puzzle Rush answers are checked on the server and timed by the server clock. If no human is found within 5 seconds, a house bot joins the Rush Battle, solving at a speed and accuracy modelled on its rating.

    Result Fair leaderboards, and bots that cost almost no CPU: Rush bots simulate their solving instead of running the engine, and a game-bot move takes a few milliseconds.

  7. A neural-network engine without a GPU farm

    The problem
    A stronger engine had to run in a browser and on one small server, and training had one Mac and no GPU cluster.
    What we did
    We trained a small NNUE network on lichess’s open evaluations (more data was the biggest lever: 10M, 20M and 94M positions gave +111 and then +99 Elo), updated it move by move instead of recomputing it, and wrote fast code for the server’s processors that is checked bit for bit against the plain version. A change ships only if a match against the previous version says it wins.

    Result +349 ± 37 Elo over the previous engine in 600 self-play games, and 164 Elo above Stockfish 19 limited to 3000 and about level with it limited to 3190 (200 games each, 10+0.1; Stockfish’s limiter is its own scale, not a rating list).

  8. Free daily limits, extended by an ad that can’t be faked

    The problem
    A player can watch an ad for one more hint, deep review, call or voice-chat game, and nothing on the phone alone should be able to grant itself that reward.
    What we did
    The server grants the reward when it receives Google AdMob’s signed server-side verification of the ad view (with a capped fallback confirmed by the app), and it verifies, caps and counts the rewards and the daily limits itself.

    Result Free each day: 10 hints, 3 deep reviews, 3 calls and 3 voice-chat games, and one more of each per rewarded ad (the defaults; the operator can change them).

Tested like a product, not a demo

  • Move generation verified with perft against known positions
  • An engine change ships only if a match against the previous version says it wins, and strength is checked against Stockfish at fixed levels
  • Fast engine code for the server’s processors checked bit for bit against the plain version
  • Server integration tests, engine tests and WebAssembly build tests
  • Load tests that simulate thousands of concurrent games
  • Spoken coach answers in 0.3–2 s for a new sentence, instantly when cached, with 18 voices

Technology

  • Go
  • SQLite
  • WebSocket
  • SvelteKit
  • TypeScript
  • NNUE
  • WebAssembly
  • WebRTC
  • Capacitor
  • sherpa-onnx
  • nginx
  • Cloudflare
  • systemd

Carrom: a board game with physics we wrote ourselves

See all our work

Want a game or a realtime app built this way?

We design, build and run games and realtime platforms end to end: apps, servers, stores and operations.