Skip to content

About

Open-source desktop bridge between Chessnut e-boards (Air, Air+, Pro, Go) and chess.com, using chess.com's own Connected Board protocol. Play on the physical board; your opponent's moves light up on its LEDs. Rust + Tauri, no browser extension. GPL-3.0. Work in progress, not affiliated with Chessnut or chess.com.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chessnut Bridge

A lightweight desktop app that connects a Chessnut electronic chessboard to chess.com, using chess.com's own Connected Board protocol. You play on the physical board; your moves reach chess.com, and your opponent's moves light up on the board for you to play.

Chessnut Bridge is free, open-source software under the GNU General Public License v3.0 or later. It is not sold or monetized in any way.

It is written in Rust with Tauri, so it uses the system WebView instead of bundling a browser: the app is a few megabytes rather than a couple of hundred, and it doesn't need Chrome or a browser extension.

Status: the board side is complete, and chess.com already recognizes the app as a connected board. Sending moves to chess.com is waiting on OAuth credentials; see Status.

Contents

Status

Area State
Reading the board over Bluetooth LE, driving its LEDs Working. Tested on a Chessnut Go; the protocol is shared by the Air family (Air, Air+, Pro, Go).
Move detection (legal moves, slides, captures, castling, en passant, promotion, takebacks) Working. 50 unit tests.
Standalone play from the command line Working.
Test site that follows chess.com's protocol, for development Working.
chess.com recognizing the app as a connected board Working on macOS. chess.com sends connected, game-started and its positions, and the board follows them.
Sending the player's moves to chess.com Waiting on OAuth. chess.com correctly rejects positions without a valid token.
OAuth login Not started; waiting on chess.com's approval of our application.
chess.com mode on Windows and Linux Not started. The board side already runs on all three.

How it works

flowchart LR
    board["Chessnut board"] -- "Bluetooth LE<br/>positions, LEDs" --> core
    subgraph app["Chessnut Bridge (Rust)"]
        core["Board session<br/>protocol → move tracker"] --> link["Site link<br/>(chess.com protocol)"]
    end
    link -- "pushChesscomConnectedBoardMessage" --> site["chess.com page<br/>(system WebView)"]
    site -- "native chesscomConnectedBoard handler" --> link
Loading

The project has three layers:

  1. The board session (src/, a plain Rust library) talks to the board over Bluetooth LE, decodes each position report, and turns the stream of positions into legal moves. It reports everything as typed events, and drives the board's LEDs to show what needs to change.
  2. The desktop app (app/, Tauri) runs the board session and speaks chess.com's Connected Board protocol. chess.com runs in its own window, and that window's only link to the app is one native message handler.
  3. The test site (ui/) is a stand-in for chess.com that follows the same protocol, used to develop and test the app without touching chess.com.

The command-line tool (src/main.rs) runs the same board session on its own, for standalone play and hardware testing.

chess.com integration

chess.com's web page already supports connected boards: its page code talks to a board through a native WebView message handler (the mechanism chess.com's own mobile apps use) and a JavaScript function for messages in the other direction. Chessnut Bridge provides that handler natively. It does not click on the page, read the page's contents, or send anything to chess.com's servers itself; the page does all of that, as it would for any connected board.

Messages

These are the messages the app handles, as observed from chess.com's page. We would welcome official documentation and will align with it.

Direction Message Meaning
site → board board-status: connected The page found a connected board.
site → board board-status: not-authenticated / authenticated Whether the board has presented a valid token.
site → board game-status: ready The page is ready; includes available bots, colors and time controls.
site → board game-started A game began; includes which color the board plays.
site → board board-position chess.com's authoritative position (FEN) after every move.
site → board board-status: synced / move-made / not-synced Replies to the board's positions.
board → site authentication The board's OAuth token.
board → site board-position A position from the board, with the token.

Sending a move

Each move from the board is sent the same way chess.com's page expects:

  1. The board sends the position before the move, and waits for synced.
  2. It sends the position after the move, and waits for move-made.
  3. chess.com replies with its own board-position, which the app adopts as the authoritative game state, move counters included.

If chess.com replies with anything else, the app shows the player its status and reason and follows chess.com's position instead. Without a token the reply is, for example:

{ "type": "board-status", "status": "not-authenticated", "reason": "Compact JWS must be a string or Uint8Array" }

Where games start

chess.com only enables its connected-board code on its Connected Board page (/play/online/connected-board), and in the rest of a browser tab that has visited it. The app therefore opens that page first, and the player continues from there.

Fair play and data handling

The app is designed so that it cannot give a player an advantage:

  • It only relays moves the player makes by hand. The board player's own moves are sent; the opponent's moves only ever come from chess.com, and are shown on the board's LEDs for the player to make.
  • No engine, analysis, or hints. The app checks that moves are legal so it can tell a finished move from a piece in the player's hand. It never evaluates positions or suggests moves.
  • No page automation. It doesn't click, type, or read content in the chess.com page; everything goes through the connected-board protocol.
  • The site owns the game. While following chess.com, local features such as takebacks and new-game detection are switched off; chess.com decides.
  • Tokens stay private. Tokens are hidden in all logs. Once OAuth is in place, tokens will be stored in the macOS Keychain, not in files.
  • The chess.com window is isolated. It has no access to the app's internal commands, only the one board message handler.
  • No secrets in the code. OAuth will use the standard flow for open-source desktop apps: a public client with PKCE, so no client secret is stored in the repository or the app.
  • Everything is open. Anyone, including chess.com, can read exactly what the app sends and when, and build it from source.

During development, a diagnostic script runs in the chess.com window to report whether chess.com's connected-board code has started. It only reads, and it will move behind a debug setting before any release.

Move detection

A physical move passes through in-between states: a piece in the hand, a captured piece being removed, a king moved before its rook. The tracker only accepts a board once exactly one legal move explains it, and waits a moment where a piece could still be moving on:

Situation What the app does
A move nothing else could be (Nf3, a4) Confirms immediately.
A move on the way to another legal square (a3 on the way to a4, Kf1 before castling) Confirms after 1 s, so a slide isn't mistaken for a move.
A piece in the hand that a legal move explains Stays quiet (10 s fallback).
A move partway done (half-castled, captured piece set down elsewhere) Lights the squares after 1 s.
One of the player's pieces on an unexplained square, nothing else changed Lights after 700 ms (usually a piece mid-slide).
Anything no legal move explains Lights the squares after 150 ms, with a message naming each piece.

The same logic handles setup (the board must match the starting position, or chess.com's position, before play begins), takebacks in standalone play, and following the opponent's moves from chess.com.

Getting started

Requirements

  • macOS (the chess.com connection is macOS-only for now)
  • Rust 1.82 or newer
  • A Chessnut Air-family board, with the Chessnut app closed (a board accepts one Bluetooth connection at a time)

The first run asks for Bluetooth access for your terminal.

Commands

# Unit tests (move detection, protocol decoding, events)
cargo test -p chessnut-bridge

# Standalone play from the terminal; --led-test checks the LED mapping
cargo run
cargo run -- --led-test

# The app with the built-in test site (needs internet for chess.js)
cargo run -p chessnut-bridge-app

# The app with chess.com
cargo run -p chessnut-bridge-app -- --chesscom

Project layout

src/
  protocol.rs   Chessnut Bluetooth protocol: position decoding, LED commands
  tracker.rs    Legal-move tracking from raw board positions
  events.rs     Everything the bridge reports, with level and category
  session.rs    One board session: connection, timing, LEDs, site positions
  main.rs       Command-line tool
app/
  src/main.rs          Desktop app and the chess.com protocol
  src/site_handler.rs  Native chesscomConnectedBoard handler (macOS)
ui/
  index.html    App window: status, scoresheet, message log, test site

Roadmap

  1. OAuth login, with tokens in the macOS Keychain (waiting on chess.com).
  2. Moves to chess.com end to end, including clocks and game results.
  3. A packaged, signed macOS app.
  4. chess.com mode on Windows and Linux.
  5. Support for other boards with public protocols.

Acknowledgements

  • Graham O'Neill's Chessnut chess board communications and Chessnut's EasyLinkSDK, for the board protocol.
  • shakmaty for chess rules, btleplug for Bluetooth LE, and Tauri for the app.
  • The Chessconnect browser extension, which showed that chess.com's connected-board protocol can serve third-party boards.

License

Copyright © 2026 Paper Scissors S.R.L.

Chessnut Bridge is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. It is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; see the LICENSE file for details.

The GPL also matches the project's dependencies: the chess-rules library, shakmaty, is GPL-3.0-or-later, and the other dependencies are under permissive licenses compatible with it.

Chessnut Bridge is an independent project. It is not affiliated with or endorsed by Chess.com or Chessnut.

Developed and maintained by Paper Scissors S.R.L..

About

Open-source desktop bridge between Chessnut e-boards (Air, Air+, Pro, Go) and chess.com, using chess.com's own Connected Board protocol. Play on the physical board; your opponent's moves light up on its LEDs. Rust + Tauri, no browser extension. GPL-3.0. Work in progress, not affiliated with Chessnut or chess.com.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages