- Rust 86.7%
- Scheme 11.2%
- PowerShell 1.4%
- Nix 0.3%
- Shell 0.2%
- Other 0.2%
|
Some checks failed
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> |
||
|---|---|---|
| .cargo | ||
| .forgejo/workflows | ||
| .githooks | ||
| .vscode | ||
| .zed | ||
| crates | ||
| docs | ||
| packs | ||
| proto | ||
| scripts | ||
| server | ||
| vendor | ||
| .dockerignore | ||
| .gitattributes | ||
| .gitignore | ||
| .gitmodules | ||
| Cargo.lock | ||
| Cargo.toml | ||
| Dockerfile | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| rust-toolchain.toml | ||
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.toml—cold_pathintrinsic on GPUImain) protoc, the protobuf compiler- A
server/.envfile, seeserver/.env.examplefor 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=[::]:3340starts the embedded relay (plain-HTTP websocket service) and is the only required setting: the advertised URL defaults tohttp://<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.comoverrides 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 setMOQ_IROH_PUBLIC_ADDRS=<wan-ip>:7800so 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.