A real-time multiplayer chess app built with React and WebSockets. No accounts, no friction — just pure chess.
- Real-time moves via WebSockets
- Automatic color assignment (white / black)
- Move validation with
chess.js - Coordinate labels (a–h, 1–8) with correct board flip for black
- Last-move highlight
- Move history panel
- Resign support
- Game-over notification
| Layer | Technology |
|---|---|
| Frontend | React + Vite |
| Routing | React Router v6 |
| Chess | chess.js |
| Styling | Tailwind CSS + inline CSS |
| Backend | Node.js WebSocket server |
├── src/
│ ├── components/
│ │ ├── Landing.jsx # Home page
│ │ ├── Game.jsx # Game page + WebSocket logic
│ │ └── Chessboard.jsx # Board UI + move handling
│ └── App.jsx
├── public/
│ ├── wk.png wp.png wq.png wr.png wb.png wn.png # White pieces
│ └── bk.png bp.png bq.png br.png bb.png bn.png # Black pieces
npm installnode server/index.jsRuns on ws://localhost:8080 by default.
npm run dev- Open the app in two browser tabs (or two devices)
- Click Find Opponent in both tabs
- The server pairs the two players and assigns colors
- Make moves by clicking a piece, then clicking the destination square
- Click Resign to end the game
| Type | Direction | Payload |
|---|---|---|
init_game |
Client → Server | {} |
init_game |
Server → Client | { color: "white" | "black" } |
move |
Client → Server | { from: "e2", to: "e4" } |
move |
Server → Client | { move: "e2e4" } |
invalid_move |
Server → Client | { message: string } |
game-over |
Server → Client | { reason: string } |
resign |
Client → Server | {} |
Piece images should be placed in /public and named using standard notation:
w = white, b = black
k = king, q = queen, r = rook, b = bishop, n = knight, p = pawn
Example: wk.png = white king, bn.png = black knight.