LiveKit-based alternative to Mumble and Discord
  • Rust 86.7%
  • Scheme 11.2%
  • PowerShell 1.4%
  • Nix 0.3%
  • Shell 0.2%
  • Other 0.2%
Find a file
Sebastian Benjamin 158a1c515c
Some checks failed
CI / test (push) Has been cancelled
CI / test-ui (push) Has been cancelled
Rust / lint (push) Has been cancelled
Rust / build (push) Has been cancelled
Release / build (push) Has been cancelled
Release / release (push) Has been cancelled
issue/rhai-component-framework (#98)
Co-authored-by: Sebastian Benjamin <hex@hextraza.moe>
Reviewed-on: #98
Co-authored-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
Co-committed-by: Sebastian Benjamin <sebastiancbenjamin@gmail.com>
2026-08-03 21:13:41 -07:00
.cargo issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
.forgejo/workflows issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
.githooks issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -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
crates issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
docs MOQ port (#97) 2026-06-29 10:12:49 -07:00
packs issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
proto MOQ port (#97) 2026-06-29 10:12:49 -07:00
scripts issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
server MOQ port (#97) 2026-06-29 10:12:49 -07:00
vendor issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -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 issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
.gitmodules MOQ port (#97) 2026-06-29 10:12:49 -07:00
Cargo.lock issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
Cargo.toml issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -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
README.md issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00
rust-toolchain.toml issue/rhai-component-framework (#98) 2026-08-03 21:13:41 -07:00

microclimate

A LiveKit-based alternative to Mumble and Discord, written in Rust.

The client is built on GPUI and gpui-component. The server is a separate Cargo workspace under server/ that speaks gRPC + Axum.

Requires

  • Rust nightly (pinned in rust-toolchain.tomlcold_path intrinsic on GPUI main)
  • protoc, the protobuf compiler
  • A server/.env file, see server/.env.example for required values

Project structure

crates/
  store, proto, auth, channels, users, audio   # backend / domain
  ui                                           # shared GPUI views
  app                                          # desktop entrypoint (mac/linux/win)
  app-web                                      # wasm32 entrypoint (stub)
  app-mobile                                   # iOS/Android entrypoint (stub)
server/                                        # separate workspace, untouched
proto/                                         # .proto definitions

crates/app is the desktop binary. crates/app-web and crates/app-mobile are reserved for the wasm and mobile targets; they don't build for their target triples yet (the LiveKit/CPAL/rdev deps in the shared crates need a trait seam first — tracked under "Phase 1 step 4").

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 committed under server/.sqlx/, so a live database is only needed when changing 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

In production, migrations run automatically when the server starts.

Client

No JS/Node tooling is required.

If on Windows, the project tree's nested path can exceed the OS path limit during compilation. Create .cargo/windows.toml with:

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

…or set CARGO_TARGET_DIR=C:/t in your shell.

Git hooks

The repo ships a pre-commit hook in .githooks/ that runs cargo fmt --check for both workspaces — 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 desktop client (from the project root)
cargo run -p microclimate-app

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

  • Use Yaak for testing gRPC features without a client.