Everything you need to run HQ World locally and test P2P connectivity between two instances.
| Requirement | Version | Notes |
|---|---|---|
| Node.js | ≥ 20 | For the relay server and frontend build |
| Rust | stable | Tauri v2 compiles a Rust binary |
| Tauri CLI | ≥ 2.0 | Installed via npm install (devDep) |
| macOS | ≥ 10.15 | Catalina or later (bundle target) |
Install Rust via rustup.rs if you don't have it:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
git clone https://github.com/indigoai-us/hq-world.git
cd hq-world
npm install
This installs both the frontend dependencies and the Tauri CLI.
HQ World peers discover each other through a lightweight circuit relay. The relay runs locally on ws://localhost:9001.
# Terminal 1
npm run relay
You should see output like:
[relay] Local dev relay started
[relay] PeerId: 12D3KooWRhYvdA1qu57VZCo8LKn21wrWC5Y8fCZgSCCPvcAUQYYH
[relay] Listening on:
[relay] /ip4/127.0.0.1/tcp/9001/ws/p2p/12D3KooWRhYvdA1qu57VZCo8LKn21wrWC5Y8fCZgSCCPvcAUQYYH
The relay uses a deterministic PeerId (derived from a seed), so the address is stable across restarts. The app's config already points to this address.
# Terminal 2
npm run tauri dev
The first launch compiles the Rust backend (takes 1–2 minutes). Subsequent launches are fast.
Once loaded, the lobby shows:
Open a second Tauri instance to test room connectivity:
# Terminal 3
npm run tauri dev
Click the profile button in each window and set different display names so you can tell them apart.
In window 1, click Create Room. You'll enter the room view. The room ID appears in the header.
Copy the room ID. In window 2, paste it into the input field and click Join. Or use Browse Rooms to find it in the directory.
Both windows should show each other in the participant list with display names. Start video to see live feeds.
When you enter a room, click Join with Video for camera + mic, or Audio Only for mic only. Controls at the bottom: mute, toggle camera, leave.
Drag a file onto the room view (or click the file button). If multiple peers are present, you'll be asked to pick a recipient. The peer gets an accept/decline prompt. Transfer shows a progress bar with speed.
When a room is closed, the directory shows a Knock button instead of Join. The host gets a native notification and can accept or decline from the knock dialog.
The room creator is the host. Open the participant list (top-right count badge) to see actions: promote to co-host, force-mute, or boot a participant. Co-hosts have the same powers except they can't modify other co-hosts or the host.
Hosts see a collapsible bandwidth panel showing upload/download kbps, RTT, and per-peer quality indicators. The SFU auto-adjusts video resolution when bandwidth drops.
Set your status to Available, Busy, or Away from the lobby dropdown. This shows in the room directory next to your name when hosting.
| Command | Description |
|---|---|
npm run dev | Vite dev server (web only, no Tauri) |
npm run build | TypeScript check + Vite production build |
npm run tauri dev | Full Tauri dev mode (Rust + web) |
npm run tauri build | Build release .dmg / .app |
npm run relay | Start local circuit relay on ws://localhost:9001 |
npm run test | Run unit tests (Vitest) |
npm run test:watch | Run tests in watch mode |
npm run test:e2e | Run E2E tests with coverage |
npm run typecheck | TypeScript type check only |
npm run lint | ESLint on src/ |
The relay isn't running or unreachable. Make sure npm run relay is active in another terminal. Check the console for [discovery] Connected to relay.
Both peers must connect to the same relay. Verify both consoles show a successful relay connection. If using different machines, update src/lib/p2p/config.ts to use the host machine's LAN IP instead of 127.0.0.1.
Expected — Rust compiles the entire Tauri runtime on first build (~2 min). Incremental builds are fast.
macOS requires camera and microphone permissions. Check System Settings → Privacy & Security. The Tauri app should prompt on first use.
The Rust lockfile is in src-tauri/Cargo.lock. If it conflicts after pulling, delete it and run npm run tauri dev to regenerate.