Discord for indoor cycling. Your crew rides one structured workout together, every smart trainer on its own rider's FTP, with voice built in. No virtual world: your watts are the game.
Ride now at wattroom.ch · Desktop app · Game modes · Self-host · Contribute
Indoor training is boring alone, and riding with friends usually means three apps: a training app, Discord for voice, and something for music, all fighting over one headset. Zwift answers boredom with a game world. WattRoom answers it with your crew:
- A place, not an event. A crew has text channels for the week and voice channels for ride night, like a Discord server for your pain cave. Anyone in the voice channel starts a workout. There is no Meetup to set up first.
- Different FTPs, one session. Workouts are written in percentages of FTP, and every trainer holds its own rider's share in ERG mode. The 180 W rider and the 320 W rider ride the same intervals side by side, and it hurts both of them the same.
- Talk the whole way. Voice is one tap, the camera is optional, and the crew's music ducks when someone speaks.
- Free, in the browser, open source. Chrome or Edge talks to your trainer over Bluetooth. Nothing to install and nothing to pay.
|
Crews with text and voice channels. Invite by a six-character code. Plan rides on a shared schedule, pin what you keep asking about, and talk before, during and after.
|
Seven game modes, decided by watts alone and measured on each rider's own FTP, so the smallest engine in the crew can win.
|
|
A shared jukebox. YouTube links, playlists and your own MP3s play in sync for everyone in the voice channel. Vote tracks up. |
Rides that count. Power curve and zones, XP and trophies, a
|
|
Workouts. A curated library, an editor, and import for the
|
On the phone on your bars. A phone follows the session, with everyone's numbers, the chat and the voice channel, while the laptop runs the trainer. |
| Mode | How it plays |
|---|---|
| Sprint Roulette | Five sprints land at random, a klaxon three seconds before each. |
| Points Race | Two-minute intervals with sprints hidden in them. Every one scores. |
| Watt Golf | Hit a wattage for ten seconds, with the meter turned off. |
| Backyard Ramp | Three-minute rounds, +5 % FTP each. Ten seconds below and you're out. |
| Collective Ramp | The same, on the crew's average. Nobody gets dropped alone. |
| Floor is Lava | A power zone is called. Leave it and you burn a life. |
| Team Relay | One rider on the front at 110 %, everyone else recovering. |
The parameters live in docs/SPEC.md. You can try a sprint on the website.
Note
Hardware and browsers. WattRoom needs a smart trainer that speaks Bluetooth FTMS, which most current trainers do. Pre-FTMS Wahoo units are not supported yet. It also needs Chrome or Edge on Windows, macOS or Android, or the desktop app. On Linux, Chrome keeps Web Bluetooth behind a flag. Safari and Firefox cannot reach a trainer, so iPhone and iPad riders can join the crew and the call but not ride. That is a researched decision, not an oversight.
| WattRoom | Zwift | TrainerRoad | MyWhoosh | |
|---|---|---|---|---|
| Price | Free | US$19.99/mo | US$21.99/mo per rider | Free |
| One workout, each on own FTP | ✓ anyone in the channel starts it | ✓ via a Meetup | ✓ up to 11 riders | pacer-led group workouts |
| Voice built in | ✓ | text chat | ✓ voice and video | text chat |
| Virtual world | none, on purpose | ✓ | none | ✓ |
| Runs in a browser | ✓ | – | – | – |
| Open source | ✓ AGPL | – | – | – |
Checked September 2026. There are sources and a "pick them if…" for each on wattroom.ch/zwift-alternative. We make WattRoom, so check for yourself.
- Hosted, free: wattroom.ch. Start a crew and send the code.
- Desktop app for macOS, Windows and Linux: wattroom.ch/download.
- Your own server: one Go binary with the web app embedded, Postgres and LiveKit, all in one Docker Compose stack on a small VM.
Self-host in five minutes
mkdir -p /opt/wattroom && cd /opt/wattroom
# copy this repository's deploy/ directory here
cp .env.example .env # every value is explained inside
cp livekit.yaml.example livekit.yaml # same keys as .env
docker compose -f docker-compose.prod.yml up -dReleases are CalVer tags (ghcr.io/natrontech/wattroom:2026.09.1). An update
is a tag bump, and a rollback is the previous tag: migrations only ever add
(ADR-0019).
The full guide, including how LiveKit reaches the server and what to back up,
is in deploy/README.md.
Requirements: Go 1.26+, Node 22+, pnpm, Docker. The pnpm version is pinned in
web/package.json (packageManager), and pnpm 10+ or corepack installs it for you.
make infra # Postgres + LiveKit (dev mode) in containers
make dev-server # terminal 1: Go server with hot reload on :8080
make dev-web # terminal 2: Vite dev server on :5174 (proxies /api + /ws)No smart trainer needed: the simulated trainer covers development, and
/dev/channel is a full mock voice channel. make screenshots redraws every
screenshot in this README, and every page's share card, from the running dev pair. Start with
CONTRIBUTING.md; every product and architecture decision is
in WATTROOM.md and docs/decisions/.
flowchart LR
subgraph Browser["Browser (Chrome / Edge)"]
SPA["SvelteKit SPA<br/>+ prerendered public pages"]
end
Trainer(["Smart trainer<br/>BLE FTMS"]) <-- Web Bluetooth --> SPA
SPA <-- "REST + WebSocket" --> Server["Go server<br/>live hub in memory"]
SPA <-- WebRTC --> LiveKit["LiveKit SFU<br/>voice + camera"]
Server --> PG[("PostgreSQL<br/>durable data only")]
SPA -. "YouTube IFrame" .-> YT(["Jukebox"])
The seams are deliberate. The browser owns the trainer, the server owns live state in memory, and Postgres owns only what has to last (docs/ARCHITECTURE.md). WattRoom ships several times a day: a release only ever adds a small, merged change, and rolling back means repointing the image at the previous tag.
AGPL-3.0, © Natron, built in Switzerland. If WattRoom made a Tuesday night better, star the repo. It helps other pain-cave dwellers find it.






