LiveKit-based alternative to Mumble and Discord
  • Rust 58.6%
  • TypeScript 39.8%
  • CSS 0.8%
  • Nix 0.3%
  • Shell 0.3%
  • Other 0.2%
Find a file
Sebastian Benjamin 13549846d2
Some checks failed
CI / test (push) Successful in 10m54s
CI / test-ui (push) Successful in 1m4s
Deno / lint (push) Successful in 12s
Rust / lint (push) Successful in 6m57s
Rust / build (push) Successful in 9m57s
Release / build (linux, docker, x86_64-unknown-linux-gnu) (push) Failing after 5m15s
Release / build (macos, docker, universal-apple-darwin) (push) Failing after 26s
Release / build (windows, docker, x86_64-pc-windows-msvc) (push) Failing after 1m42s
Release / release (push) Has been skipped
MOQ port (#97)
Removes LiveKit and ports everything to Iroh+MOQ

Co-authored-by: Sebastian Benjamin <hex@hextraza.moe>
Reviewed-on: #97
Co-authored-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
Co-committed-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
2026-06-29 10:12:49 -07:00
.cargo Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
.forgejo/workflows Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
.githooks Implement sonora processing pipeline (#91) 2026-06-09 09:37:50 -07:00
.storybook Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
.vscode init tauri app 2026-02-10 18:22:49 -08:00
.zed Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
app MOQ port (#97) 2026-06-29 10:12:49 -07:00
docs MOQ port (#97) 2026-06-29 10:12:49 -07:00
proto MOQ port (#97) 2026-06-29 10:12:49 -07:00
public Setting up react-router and shadcn 2026-02-11 19:29:18 -08:00
server MOQ port (#97) 2026-06-29 10:12:49 -07:00
src-tauri MOQ port (#97) 2026-06-29 10:12:49 -07:00
stories Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
vendor MOQ port (#97) 2026-06-29 10:12:49 -07:00
.dockerignore Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
.gitattributes Adding server url page and channels sidebar 2026-02-18 17:28:39 -08:00
.gitignore #82 Changing target directory for client on windows (#82) 2026-04-10 14:38:57 -07:00
.gitmodules MOQ port (#97) 2026-06-29 10:12:49 -07:00
components.json Adding server url page and channels sidebar 2026-02-18 17:28:39 -08:00
deno.jsonc MOQ port (#97) 2026-06-29 10:12:49 -07:00
deno.lock MOQ port (#97) 2026-06-29 10:12:49 -07:00
Dockerfile MOQ port (#97) 2026-06-29 10:12:49 -07:00
flake.lock Adjusting flake for mac build (#92) 2026-04-14 16:38:22 -07:00
flake.nix Adjusting flake for mac build (#92) 2026-04-14 16:38:22 -07:00
package.json MOQ port (#97) 2026-06-29 10:12:49 -07:00
react-router.config.ts Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
README.md MOQ port (#97) 2026-06-29 10:12:49 -07:00
tsconfig.json Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
tsconfig.node.json Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
vite.config.ts Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
vitest.config.ts Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00
vitest.shims.d.ts Add a bunch of tests (#89) 2026-05-29 14:45:48 -07:00

microclimate

A LiveKit-based alternative to Mumble and Discord.

Requires

  • Rust
  • Deno
  • protoc, the protobuffer compiler
  • A server/.env file, see server/.env.example for required values

Project structure

The server and Tauri client are separate Cargo workspaces. Most server-side Cargo commands should be run from the server/ directory; most client-side commands are run from the project root (via Deno tasks) or src-tauri/.

Setup

Server

The server uses SQLx compile-time query verification, which requires either a live database or a pre-generated query cache. The cache is already committed to the repository under server/.sqlx/, so a live database is only needed when you change the schema.

# Copy and fill in the environment file
cp server/.env.example server/.env

# JWT_SECRET is required — the server uses it to sign session tokens issued
# after a successful ATProto OAuth login. Use a long random value, e.g.:
#   openssl rand -base64 32

# (First time only, or after changing migrations) Install sqlx-cli and
# run migrations to set up the database
cargo install sqlx-cli --no-default-features --features sqlite
cd server && sqlx migrate run

# (After changing migrations) Regenerate the SQLx query cache and commit it
cd server && cargo sqlx prepare

Note: In production, migrations run automatically when the server starts.

Client

Install dependencies with deno i

If on windows create a windows.toml file in the .cargo folder then add the following:

[build]
target-dir = "C:/t"

Without it vite will choke itself scanning the target folder, and the application will never run.

Git hooks

The repo ships a pre-commit hook in .githooks/ that runs deno fmt --check, deno lint, and cargo fmt --check for both crates — the fast checks CI also runs. To enable for your clone:

git config core.hooksPath .githooks

Use git commit --no-verify to skip on a one-off basis.

Running

# Start the gRPC server (from server/)
cd server && cargo run

# Start the Tauri desktop app (from project root, use cmd.exe on Windows)
deno task tauri dev

Note: cargo build from the project root only builds the Tauri client. To build the server, run cargo build from server/.

Self-hosted voice relay

Voice transport runs over iroh, which uses a relay server as rendezvous point and NAT-traversal fallback. By default that's iroh's public infrastructure (currently canary-tier while iroh 1.0 is in release candidates). For a production deployment, host your own — the relay is embedded in the server binary and enabled with env vars (see server/.env.example):

  • IROH_RELAY_BIND=[::]:3340 starts the embedded relay (plain-HTTP websocket service) and is the only required setting: the advertised URL defaults to http://<PUBLIC_HTTP_URL host>:3340, so exposing the port on the same host as the gRPC server just works. With the relay active, voice has no third-party dependencies: clients skip iroh's DNS discovery entirely and dial the addresses the server hands out over gRPC.
  • IROH_RELAY_URL=https://relay.example.com overrides the advertised URL — set it when the relay sits behind a TLS reverse proxy.
  • MOQ_IROH_BIND_V4=0.0.0.0:7800 (optional) pins the voice endpoint to a stable UDP port. Forward it on your router and set MOQ_IROH_PUBLIC_ADDRS=<wan-ip>:7800 so clients connect directly; without it, traffic falls back to the relay (which always works, just adds a hop).

If a session still drops, the client now notices: it shows "reconnecting…" in the sidebar and rejoins automatically with backoff.

For the full configuration reference (required values, ports, reverse-proxy setup), see docs/deployment.md.

Tips

  • If you're developing on Windows, I've observed that the Tauri app will not render when executing deno task tauri dev from Powershell. Using cmd seems to work just fine, though.
  • On Windows, set CARGO_TARGET_DIR=C:/t (or another short path) to redirect Cargo build artifacts off the project tree.
  • I recommend using Yaak for testing gRPC features without a client
  • Use cargo test export_bindings from src-tauri/ to generate TypeScript types from structs using ts-rs