RustDesk
Audited from github.com/rustdesk/rustdesk
RustDesk is an open-source remote desktop client and protocol, written in Rust with a Flutter UI, that connects two peers via a rendezvous/relay server or a self-hosted one.
- Language
- Rust
- Hosting
- Docker
- License
- AGPL-3.0
- Running for
- 4 years
- Team
- 6-20 people
Why this architecture
A shared Rust core (libs/hbb_common) keeps the client and the separate rustdesk-server protocol implementation in sync, while Flutter gives one UI codebase across desktop and mobile targets.
Tech stack by layer
5 technologies · audited Sep 17, 2026- DockerProvides a reproducible Debian-based container with vcpkg and the Rust toolchain for building Linux binaries.
- GitHub ActionsBuilds and tests the Rust core and Flutter clients across desktop and mobile targets on every change.
RustDesk architecture diagram
Open SVGDiagram as text
- Flutter app (Dart · flutter_rust_bridge) → librustdesk core (Rust): FFI
- Linux tray (GTK) → librustdesk core (Rust): control
- librustdesk core (Rust) → Capture & input (scrap · enigo): video · input
- librustdesk core (Rust) → Session services (audio · clipboard): services
- librustdesk core (Rust) → hbb_common (codec · config · net): protocol
- hbb_common (codec · config · net) → rustdesk-server (rendezvous / relay): TCP hole punch
- hbb_common (codec · config · net) → Remote peer (RustDesk client): direct or relay
Key architectural decisions
6 decisions- 01
Workspace splits shared server code from client-only platform code
libs/hbb_common holds the codec, config and tcp/udp wrapper shared with the separate rustdesk-server project, while libs/base is explicitly reserved for protobuf, filesystem and platform code "that only RustDesk itself uses," per the comment at the top of libs/base/Cargo.toml.
- 02
DRM screen capture is loaded at runtime, never link-time linked
libs/scrap/Cargo.toml documents that the drm feature dlopens libdrmtap.so.0 at a commit pinned by DRMTAP_SHA in build.py instead of depending on the libdrmtap-sys crate, "which would defeat the dlopen model," so a missing library falls back to PipeWire instead of failing to build.
- 03
Legacy Sciter UI is kept only as a deprecated fallback to Flutter
src/ui holds the older Sciter-based interface, marked obsolete in the README, while flutter/lib is the primary GUI built and shipped through flutter-build.yml; new features target Flutter only.
- 04
Cross-platform dependencies are forked under the rustdesk-org GitHub org
Cargo.toml pulls cpal, arboard, rdev, tao, wallpaper, keepawake and several other crates from git branches under github.com/rustdesk-org instead of crates.io, so platform-specific patches (for example the osx-screencapturekit branch of cpal) ship without waiting on upstream releases.
- 05
libxdo is replaced by an in-repo stub to drop a hard runtime dependency
The [patch.crates-io] section of Cargo.toml redirects libxdo-sys to libs/libxdo-sys-stub, a dynamic-loading wrapper so RustDesk builds and runs on Wayland-only systems that lack libxdo installed at compile or link time.
- 06
Codec and capture backends are compiled in per platform via Cargo features
Cargo.toml defines hwcodec, vram, mediacodec and drm as opt-in features layered on scrap, so a given build only links the hardware video paths its target platform needs instead of every backend at once.
How RustDesk is built
How RustDesk is structured
RustDesk is a single Cargo workspace (Cargo.toml) rather than a client repo plus a UI repo. The workspace members are libs/scrap (capture), libs/hbb_common (codec, config, the tcp/udp wrapper, and everything shared with the separate rustdesk-server project), libs/base (protobuf and filesystem/platform code specific to the client), libs/enigo (keyboard/mouse control), libs/clipboard, libs/virtual_display and libs/portable. The root crate builds both a naming and a service binary and a librustdesk cdylib/staticlib/rlib that the Flutter shell in flutter/ calls into through flutter_rust_bridge, pinned to 1.80.1 in both Cargo.toml and flutter/pubspec.yaml. src/core_main.rs and src/flutter_ffi.rs are the boundary between the two halves.
Frontend
The GUI is flutter/lib, a Flutter/Dart application (flutter/pubspec.yaml, Dart SDK ^3.1.0) that ships to desktop, Android and iOS from the same codebase, built by .github/workflows/flutter-build.yml and flutter-tag.yml. It depends on several packages RustDesk forked under the rustdesk-org GitHub org and pins by git ref rather than a published version — window_manager, desktop_multi_window, flutter_custom_cursor, texture_rgba_renderer and flutter_gpu_texture_renderer among them — because the upstream Flutter desktop-embedding ecosystem moves independently of RustDesk's release cycle. An older, deprecated interface built on the Sciter engine still lives in src/ui and is documented in the README as obsolete; the CI-built artifact is Flutter only. On Linux, gtk = "0.18" in the root Cargo.toml's Linux target dependencies backs the system tray (src/tray.rs) and windowing glue that Flutter does not own directly.
Backend & APIs
There is no server process bundled in this repository — RustDesk's protocol server (rustdesk-server) is maintained separately, and src/rendezvous_mediator.rs is the client-side code that "communicates with rustdesk-server, wait[ing] for remote direct (TCP hole punching) or relayed connection," per the README's file-structure section. The client's own core is organized under src/: src/server holds the audio, clipboard, input and video services and network connections a controlled machine runs; src/client.rs starts a peer connection from the controlling side; src/platform isolates OS-specific code (Windows, macOS, Linux, Android, iOS) behind common interfaces used by libs/base and libs/enigo. Feature flags in the root Cargo.toml — hwcodec, vram, mediacodec, drm, flutter, inline — let a given build only compile the codec and capture backends its target platform needs.
Realtime / collaboration
Connections use the shared libs/hbb_common crate built with its webrtc feature, giving RustDesk ICE-based NAT traversal for direct peer links. The [patch.crates-io] block in Cargo.toml documents two behavioral patches on top of the upstream webrtc crates: webrtc-util misreads a Windows adapter's IPv6 addresses as host-order values, breaking IPv6 ICE candidate gathering on Windows, and webrtc-sctp's RFC 4960 1-second retransmit floor is too slow for the sub-100ms links RustDesk expects, so a faster retransmit path is patched in. When no direct/hole-punched path is available, src/rendezvous_mediator.rs falls back to a relay through the same rendezvous server. Screen data flows through libs/scrap, whose drm feature captures Linux scanouts by dynamically loading libdrmtap.so.0 at a version pinned in build.py, with an automatic fallback to PipeWire capture when that library or EGL isn't present.
Build, test & deploy
Builds require vcpkg for libvpx, libyuv, opus and aom (README, Dockerfile), then cargo run or cargo build --release for the native core. The provided Dockerfile bootstraps a Debian trixie container with the C++ toolchain, GTK, PulseAudio, GStreamer and GNOME libs, vcpkg, and rustup, so docker build -t rustdesk-builder . followed by docker run ... rustdesk-builder reproduces a Linux build without installing dependencies on the host. CI is split across .github/workflows/ci.yml (native Rust checks), flutter-ci.yml/flutter-build.yml (Flutter/Dart builds per platform) and flutter-nightly.yml, with bridge.yml presumably regenerating the flutter_rust_bridge bindings and fdroid.yml producing the F-Droid build.
Self-hosting notes
RustDesk's client works unmodified against a self-hosted deployment: point it at your own rendezvous/relay server instead of RustDesk's public one. The server side (rustdesk-server) is a separate GitHub project referenced from this README rather than code in this repository, so this deep dive cannot audit its stack — only that this client repository's protocol layer, libs/hbb_common, is the piece both sides share.
What to copy (and what not to)
The workspace split between libs/hbb_common (protocol, shared with the server) and libs/base (client-only platform code) is a reusable pattern for any project that ships a client and a server from related but separate repos: it keeps the wire format and its dependents in one crate that both sides can vendor. The libs/libxdo-sys-stub patch — swapping a [patch.crates-io] entry for an in-tree stub instead of forking the real crate — is a cheap way to make an optional system library truly optional without carrying a full fork. What's less reusable outside RustDesk's exact constraints is the dependency graph of git-pinned forks under rustdesk-org: it works because RustDesk maintains that org, but it means cargo update alone won't pick up upstream fixes for those crates.
Sources & repo audit
- Root Cargo.toml (workspace, features, git-forked dependencies, patches)
- flutter/pubspec.yaml (Flutter client dependencies)
- libs/scrap/Cargo.toml (capture backend features, DRM dlopen note)
- Dockerfile (Linux build container)
Independent analysis of repository at github.com/rustdesk/rustdesk. Spotted an inaccuracy? Use the claim form to request a correction.
Show this stack on your README or website
[](https://stackitfast.com/project/rustdesk)Paste it into your README. It shows your current stack and links to this page.
Scaffold it with your agent
Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with RustDesk's architecture.
- 1Copy the promptThe full markdown spec, with every layer and decision.
- 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
- 3Paste and scaffoldUse it as the first instruction; review before you ship.
# MISSION: Scaffold "RustDesk" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **RustDesk**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: RustDesk
- **What It Does**: RustDesk is an open-source remote desktop client and protocol, written in Rust with a Flutter UI, that connects two peers via a rendezvous/relay server or a self-hosted one.
- **Domain & Category**: Remote Desktop Infrastructure
- **Production Scale**: 6-20 people
- **Development Mode**: CLASSIC
- **Architectural Rationale**: A shared Rust core (libs/hbb_common) keeps the client and the separate rustdesk-server protocol implementation in sync, while Flutter gives one UI codebase across desktop and mobile targets.
- **Live Website Reference**: https://rustdesk.com
- **Source Repository**: https://github.com/rustdesk/rustdesk
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: Rust, Flutter, Dart, WebRTC, Docker
- **Primary Language(s)**: Rust, Dart
- **License of the reference repo**: AGPL-3.0
- **Frontend**: Flutter — Renders the desktop and mobile UI (connection manager, session view, settings) on top of the native Rust core.; GTK — Provides native GTK bindings for Linux tray icon and windowing integration.
- **Backend & APIs**: Rust — Implements the core engine: screen capture, input injection, clipboard, audio and the connection/session state machine.; WebRTC — hbb_common is built with the webrtc feature for ICE-based NAT traversal between peers.
- **Infrastructure & deploy**: Docker — Provides a reproducible Debian-based container with vcpkg and the Rust toolchain for building Linux binaries.; GitHub Actions — Builds and tests the Rust core and Flutter clients across desktop and mobile targets on every change.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/rustdesk/rustdesk @ 0b3a1dd)
1. **Workspace splits shared server code from client-only platform code**: libs/hbb_common holds the codec, config and tcp/udp wrapper shared with the separate rustdesk-server project, while libs/base is explicitly reserved for protobuf, filesystem and platform code "that only RustDesk itself uses," per the comment at the top of libs/base/Cargo.toml.
2. **DRM screen capture is loaded at runtime, never link-time linked**: libs/scrap/Cargo.toml documents that the drm feature dlopens libdrmtap.so.0 at a commit pinned by DRMTAP_SHA in build.py instead of depending on the libdrmtap-sys crate, "which would defeat the dlopen model," so a missing library falls back to PipeWire instead of failing to build.
3. **Legacy Sciter UI is kept only as a deprecated fallback to Flutter**: src/ui holds the older Sciter-based interface, marked obsolete in the README, while flutter/lib is the primary GUI built and shipped through flutter-build.yml; new features target Flutter only.
4. **Cross-platform dependencies are forked under the rustdesk-org GitHub org**: Cargo.toml pulls cpal, arboard, rdev, tao, wallpaper, keepawake and several other crates from git branches under github.com/rustdesk-org instead of crates.io, so platform-specific patches (for example the osx-screencapturekit branch of cpal) ship without waiting on upstream releases.
5. **libxdo is replaced by an in-repo stub to drop a hard runtime dependency**: The [patch.crates-io] section of Cargo.toml redirects libxdo-sys to libs/libxdo-sys-stub, a dynamic-loading wrapper so RustDesk builds and runs on Wayland-only systems that lack libxdo installed at compile or link time.
6. **Codec and capture backends are compiled in per platform via Cargo features**: Cargo.toml defines hwcodec, vram, mediacodec and drm as opt-in features layered on scrap, so a given build only links the hardware video paths its target platform needs instead of every backend at once.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
- Structure as a Turborepo monorepo with strict package boundaries:
- `apps/web`: Application UI, routing, layouts, and server endpoints.
- `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
- `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
- `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
- Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
- Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
- Isolate interactive UI state to leaf components. Keep core pages lightweight and performant.
4. **Design System & Aesthetics**:
- Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
- Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
- Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
- Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer: client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.Frequently asked about RustDesk
What is RustDesk built with?
The core client and its networking, capture and input stack are written in Rust (Cargo.toml, libs/*), with a Flutter and Dart UI in flutter/lib rendered on top of it for desktop and mobile.
Does RustDesk need a backend server to work?
It can use the public rendezvous/relay servers RustDesk operates, but the client works the same way against a self-hosted rustdesk-server instance since the protocol lives in the shared libs/hbb_common crate.
Can I self-host RustDesk?
Yes. The client connects to any rendezvous/relay server address you configure; RustDesk publishes a separate rustdesk-server project and docs at rustdesk.com/server for running your own.
Does RustDesk use WebRTC?
Yes, for peer connection negotiation: the root Cargo.toml builds libs/hbb_common with its webrtc feature enabled, and Cargo.toml patches webrtc-util and webrtc-sctp for Windows IPv6 and fast-retransmit fixes.
Is RustDesk written in Rust?
Yes. The core client, networking, screen capture and input handling are Rust crates (Cargo.toml, libs/*); only the user interface is written in Dart with Flutter on top of that Rust core.
Is the RustDesk desktop app built with Flutter?
Yes. flutter/lib is the primary GUI for desktop and mobile, built and shipped through flutter-build.yml; the older Sciter UI in src/ui is kept only as a deprecated fallback.
One email a month: new deep dives and stack trends
New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.
Similar architectures
- AppFlowyHybridLocal-First Privacy Workspace · 6-20 PeopleShares Flutter · Dart · Rust
- InfisicalHybridSecret Management · 6-20 peopleShares Docker · Rust
- vLLMAI-agentHigh-Throughput LLM Inference & Serving Engine · 20+ peopleShares Rust · Docker
- ImmichHybridPhoto & Video Management Platform · 6-20 peopleShares Flutter · Dart · Docker
- Rocket.ChatClassicOpen-Source Team Communications & WebRTC · 20+ peopleShares WebRTC · Docker
- Tailwind CSSClassicUtility-First CSS Engine & Framework · 1M+ MAUShares Rust