A modern, real-time typing speed test application with multiplayer racing capabilities.
Practice your typing skills solo or compete against friends in live races.
- Real-time WPM (Words Per Minute) calculation
- Accuracy percentage tracking
- Dynamic text generation using Markov chains
- Create or join rooms with unique 6-character codes
- Real-time progress synchronization across players
- Live WPM tracking during races
- Finish position indicators
- Three.js powered 3D keyboard key animations
- Interactive orbit controls
| Category | Technologies |
|---|---|
| Frontend | Next.js 15, React 19, TypeScript 5 |
| Styling | Tailwind CSS 4, Shadcn UI |
| 3D Graphics | Three.js |
| Real-time | Socket.io |
| Backend | Express.js 5 |
| Tooling | Bun, Turbopack, Biome |
graph TB
subgraph Client["Client (Browser)"]
UI[React Components]
Socket[Socket.io Client]
Three[Three.js 3D Renderer]
end
subgraph Server["Server (Node.js/Bun)"]
Express[Express.js]
SocketServer[Socket.io Server]
NextHandler[Next.js SSR Handler]
RoomManager[Room Manager]
end
UI --> Socket
UI --> Three
Socket <-->|WebSocket| SocketServer
Express --> NextHandler
SocketServer --> RoomManager
style Client fill:#234C6A,color:#fff
style Server fill:#1B3C53,color:#fff
sequenceDiagram
participant P1 as Player 1
participant S as Server
participant P2 as Player 2
P1->>S: join_room (roomId, username)
S->>P1: room_players (existing players)
P2->>S: join_room (roomId, username)
S->>P1: new_player (P2 info)
S->>P2: room_players (existing players)
P1->>S: paragraph_set (text)
S->>P1: room_paragraph (text)
S->>P2: room_paragraph (text)
loop Typing Race
P1->>S: send_keystroke (progress)
S->>P2: receive_keystroke (P1 progress)
P2->>S: send_keystroke (progress)
S->>P1: receive_keystroke (P2 progress)
end
P1->>S: Race Complete
Note over P1: Confetti if 1st place
graph LR
subgraph Pages
Home["/"]
Type["/type"]
Multi["/multiplayer"]
end
subgraph Components
Keyboard[Keyboard.tsx<br/>3D Key]
Header[Header.tsx]
UI[UI Components]
end
subgraph Hooks
UseSocket[useSocket.tsx]
end
subgraph Utilities
Markov[markov.ts<br/>Text Generation]
Utils[utils.ts]
end
Home --> Keyboard
Type --> Markov
Multi --> UseSocket
Multi --> Markov
UseSocket -->|Socket.io| Server[(Server)]
style Pages fill:#456882,color:#fff
style Components fill:#234C6A,color:#fff
style Hooks fill:#1B3C53,color:#fff
stateDiagram-v2
[*] --> Lobby: User opens /multiplayer
Lobby --> WaitingRoom: Creates/Joins room
WaitingRoom --> Racing: Host starts game
Racing --> Finished: User completes text
Finished --> WaitingRoom: Play Again
Finished --> Lobby: Leave Room
WaitingRoom --> Lobby: Leave Room
- Bun (recommended) or Node.js 18+
# Clone the repository
git clone https://github.com/yourusername/keyflow.git
cd keyflow
# Install dependencies
bun install# Start the development server (includes Socket.io server)
bun run devOpen http://localhost:4000 in your browser.
# Build the application
bun run build
# Start production server
bun start| Event | Direction | Payload | Description |
|---|---|---|---|
join_room |
Client → Server | roomId |
Join a specific room |
player_joined |
Client → Server | { room, username } |
Announce player with username |
send_keystroke |
Client → Server | { room, message, sender, username } |
Broadcast typing progress |
receive_keystroke |
Server → Client | { message, sender, username } |
Receive others' progress |
new_player |
Server → Client | { id, username } |
New player joined notification |
room_players |
Server → Client | Player[] |
List of current players |
player_left |
Server → Client | playerId |
Player disconnection |
paragraph_set |
Client → Server | { room, paragraph } |
Set race text |
room_paragraph |
Server → Client | paragraph |
Receive race text |
| Variable | Default | Description |
|---|---|---|
PORT |
4000 |
Server port |
CORS_ORIGIN |
localhost:3000,localhost:4000 |
Allowed CORS origins (comma-separated) |
NODE_ENV |
development |
Environment mode |
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
