# Quickstart Get Rutster running and hear your own voice echoed back in under 5 minutes. > **Status:** Slices 1โ€“3 are merged to `main`. Slice 4 (barge-in / VAD-driven playout > kill) is the active build target, in flight on the `slice-4-dev-a-reflex` + > `slice-4-dev-b-tap` branches. This quickstart exercises the slice-1 WebRTC media > loopback, which remains the simplest end-to-end demo on `main`. See > [`docs/superpowers/specs/2026-07-01-slice-4-barge-in-design.md`](superpowers/specs/2026-07-01-slice-4-barge-in-design.md) > for the active build target's design. --- ## Prerequisites ### 1. Rust toolchain Install via [rustup](https://rustup.rs/): ```bash curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh ``` The repo pins a specific stable channel in `rust-toolchain.toml` โ€” `rustup` will pick it up automatically on first `cargo` invocation. No manual toolchain selection needed. ### 2. libopus (FFI dependency) The `opus` crate links system libopus via FFI (per PORT_PLAN ยง7's "๐Ÿฆ€ Core (FFI)" disposition โ€” Opus is the codec surface Rust doesn't need to re-implement). Install the dev headers: | Platform | Command | |---|---| | Debian/Ubuntu | `sudo apt-get install -y libopus-dev` | | Fedora | `sudo dnf install -y opus-devel` | | Arch | `sudo pacman -S opus` | | macOS (Homebrew) | `brew install opus` | Verify: `pkg-config --cflags opus` should print a path with no error. That's the only system dependency in slice 1. Everything else is pure Rust from crates.io. --- ## Run the server ```bash cargo run # listening on http://0.0.0.0:8080 ``` First build takes ~2 minutes (str0m + axum + tokio compile fresh). Subsequent builds are incremental. --- ## Hear the echo 1. Open a browser to . 2. Click **Start call**. 3. Grant microphone permission when the browser prompts. 4. Speak โ€” you should hear yourself back within ~200 ms (no perceptible delay). 5. Click **Hang up** to tear down. The server logs `Closing โ†’ Closed` for the session. Verbose tracing for debugging: ```bash RUST_LOG=rutster=debug cargo run ``` --- ## Troubleshooting | Symptom | Likely cause / fix | |---|---| | `error: linking with cc failed` / `could not find opus` | libopus dev headers not installed. Re-run the install command above. | | Browser shows no mic prompt | Another tab/app holding the mic, or mic permissions disabled for `localhost`. Check browser settings. | | `ICE connection failed` in the browser | Shouldn't happen on loopback (host candidates only). If it does, check the server console for the str0m error. | | Click Start call, nothing happens | Open the browser console (F12). The page logs ICE state + connection state to a `
` element. Look for the failure there. |
| Port 8080 already in use | Set `RUTSTER_HTTP_BIND`, e.g. `RUTSTER_HTTP_BIND=0.0.0.0:8090 cargo run -p rutster` |

The browser test page at `GET /` is a single self-contained HTML file
with inline JS โ€” no build step. View source to see exactly what the
client side is doing.

---

## What's happening

When you click "Start call":

1. Browser captures microphone audio via `getUserMedia`.
2. Browser creates an `RTCPeerConnection` and generates an SDP offer
   (audio-only, Opus codec).
3. Browser POSTs the offer to `POST /v1/sessions/:id/offer`.
4. The Rutster core (built on [`str0m`](https://docs.rs/str0m), a sans-IO
   WebRTC implementation) accepts the offer, generates an SDP answer with
   its DTLS fingerprint + ICE credentials.
5. Browser sets the answer as remote description; ICE + DTLS handshake
   completes.
6. RTP starts flowing: browser โ†’ core terminates DTLS-SRTP โ†’ decodes
   Opus to 16-bit PCM @ 24 kHz mono โ†’ echoes PCM back โ†’ re-encodes to
   Opus โ†’ DTLS-SRTP โ†’ browser plays it.

The "codec-to-PCM boundary" is the canonical point where, in a future
slice, the audio tap for an external AI brain splices in. Slice 1 just
echoes; step 2 of the spearhead swaps the echo for a real tap.

For the why, see [`ARCHITECTURE.md`](ARCHITECTURE.md). For the dev loop,
see [`DEVELOPMENT.md`](DEVELOPMENT.md).