RustDesk v1.4.9 compatible

Build branded RustDesk clients on your machine

Server, public key, password, permissions, and branding baked into the installer. No GitHub Actions. No cloud CI. One local page in your browser — pick a target, hit build, done.

terminal
$
Server + public key compiled in
Password + permissions as base64 custom_.txt
App name, icon, logo, theme
Capability board shows what's ready now
Windows .exe / .msi
macOS .dmg
Linux .deb / .rpm / .AppImage
Android .apk
DVForge capability board — targets, toolchains, and hardware detection
The capability board detects your hardware, shows which targets are ready, and lets you install missing toolchains with one click.
DVForge build farm — queue a job, watch it compile on a remote worker
The build farm queue: upload a config, pick a target, and a worker compiles it for you.

Why build locally?

The same customisations as cloud CI, but your server address, API key, and passwords never leave your machine.

Cloud CI (GitHub Actions)

Your server IP, public key, permanent password, and API credentials are stored as GitHub secrets — on someone else's infrastructure.

Builds require a public or private repo, a workflow file, and a paid plan for longer runners. Every change is a commit-push-wait cycle.

DVForge (local)

Everything stays on your own hardware. Open a browser tab, fill in the config, press Build. Installers land in a folder on your disk.

No repo needed. No runner minutes. No secrets in the cloud. Python 3.8+ is the only prerequisite — toolchains install into a private folder automatically.

What's inside

A local web app with three tabs — Targets, Config, Build — and a toolchain manager in the sidebar.

Capability board

Detects your hardware and OS, lights up which targets this machine can produce. Amber means ready; click "install" on anything missing.

Full config editor

Server, key, API, app name, icon, logo, accent color, password, permissions, connection direction — all with a live preview of the baked-in payload.

Live build console

Streams compiler output in real time. Dry-run mode prints every command without compiling. Cancel any time.

Portable toolchains

Rust, Flutter, LLVM, vcpkg, NDK, JDK — all download into .toolchains/. Nothing installed system-wide. Delete the folder to start clean.

🖨

Open printer adapter

Clean-room replacement for RustDesk's signature-locked printer_driver_adapter.dll. Remote printing works in your branded builds.

🔑

Code signing

Generate a self-signed PFX for Windows or bring your own. macOS Developer ID supported. Signing is optional — builds work without it.

🌐

Multi-machine build farm

Shared inbox/outbox on a NAS. Mac worker builds DMGs, Windows worker builds EXEs. Submit via CLI or a queue API behind nginx.

📱

Android cross-build

Build APKs for arm64, armeabi, x86_64, or a universal package — from Linux, WSL, or macOS. Debug-signed by default; bring your own keystore for production.

🔧

Source patches

Auto-applies allowCustom, hide connection manager, remove version nag, remove server-setup tip, privacy screen, and offline-peer styling.

How it works

A zero-dependency Python server drives detection, config generation, source patching, and the build — all through a browser GUI.

Browser GUI index.html · app.js · style.css app.py Python stdlib HTTP + SSE 127.0.0.1:8765 builder/ detect.py prereqs.py toolchains.py config_gen.py customize.py orchestrator.py signing.py precheck.py build pipeline checkout patch bridge build sign collect workspace/output/v1.4.9/ .exe · .dmg · .deb · .rpm · .apk configs/RustDesk.json patches/*.diff · *.py .toolchains/ farm/ multi-machine queue printer-adapter/

Who can build what

Desktop clients compile on their own OS. Android is cross-compiled from Linux, WSL, or macOS.

You want Build it on Output
Windows app Windows portable .exe optional .msi
macOS Apple Silicon any Mac aarch64 .dmg
macOS Intel any Mac x86_64 .dmg
macOS Universal any Mac universal .dmg
Linux packages Linux / WSL .deb .rpm .AppImage
Android APK Linux, WSL, or macOS arm64 · armeabi · x86_64 · universal
Windows PCs cannot build APKs — the capability board hides that target automatically. APKs use debug signing unless you add your own keystore.

Quick start

Clone, run the one-time setup for your OS, then launch. The UI opens at 127.0.0.1:8765.

1

Clone

git clone https://github.com/VenimK/DVForge.git && cd DVForge
2

Run setup

Add --with-android if you want to build APKs too.

bash Setup-DVForge-macOS.sh
3

Launch

./run.sh
1

Clone

git clone https://github.com/VenimK/DVForge.git && cd DVForge
2

Run setup

powershell -NoProfile -ExecutionPolicy Bypass -File .\Setup-DVForge-Windows.ps1
3

Launch

run.bat
1

Clone

git clone https://github.com/VenimK/DVForge.git && cd DVForge
2

Run setup from PowerShell

This installs WSL 2, sets up Ubuntu inside it, and configures the toolchains.

powershell -NoProfile -ExecutionPolicy Bypass -File .\Setup-DVForge-WSL2.ps1
3

Launch inside WSL

./run.sh
1

Clone

git clone https://github.com/VenimK/DVForge.git && cd DVForge
2

Install dependencies and launch

The app detects missing toolchains and offers one-click install from the sidebar. Or install them manually — the README has the full list.

./run.sh
3

Open the UI

Navigate to http://127.0.0.1:8765 in your browser.

python3 app.py also works. Add --no-browser to skip auto-open. Set RDLB_PORT=9000 to change the port.

Real build times

Measured on the project's test machines. First run is slower (Rust downloads crates); subsequent builds reuse the cache.

Linux .deb
~0 min
Linux .rpm
~0 min
Android arm64
~0 min
Android armeabi
~0 min
Android x86_64
~0 min
Android universal
~0 min

Toolchains

The sidebar detects what you have. For most tools it downloads a portable copy into .toolchains/ — no admin, nothing system-wide.

Tool Pinned version Used for
Python3.8+The app itself
GitanySource checkout
Rust1.75 (1.81 on macOS)Every native build
Flutter3.24.5Every Flutter UI
LLVM / libclang15.0.6bindgen / ffigen
vcpkgpinned commitFFmpeg / hwcodec
JDK17Android builds
Android NDKr28cAndroid native lib (16 KB pages)
Android SDKAPI 34flutter build apk
Xcode + create-dmgmacOS .dmg packaging
VS C++ Build Tools2022Windows .msi / linker
Xcode and Visual Studio can't be silently sideloaded — the UI gives the exact install hint. Delete .toolchains/ to start clean. Uninstall scripts included for each OS.

Source patches

Applied automatically during the build. These strip upstream locks and clean up the branded client.

allowCustom

Strips the 9-line signature check from src/common.rs and renames custom.txtcustom_.txt so your config loads.

hidecm

Hides the connection manager UI when connection direction is restricted.

removeNewVersionNotif

Suppresses the "new version available" prompt that would point users to upstream RustDesk.

removeSetupServerTip

Removes the "set up your own server" tip from the connection page — irrelevant when the server is already baked in.

privacyScreen

Adds privacy-screen support by embedding a custom image as a C++ byte array.

xoffline

Adjusts the offline peer styling in the address book for better visual clarity.

Flutter dropdown fix

Patches Flutter 3.24.4's DropdownMenu enableFilter regression.

Multi-machine build farm

Share a NAS folder (or use the HTTP queue) between machines. Each worker claims only the targets its OS can build.

How it works

Drop a job JSON into farm/inbox/. The Mac worker picks up macOS DMGs, the Windows worker picks up EXEs, the Linux worker picks up DEBs and APKs. Finished installers land in farm/outbox/.

No public website needed. No third-party builders. DVForge stays on 127.0.0.1.

HTTP queue

Run queue.py behind nginx for remote submissions. Workers claim jobs over HTTPS with a bearer token. Status page at /status shows online workers, queue depth, and recent builds.

Workers are rated by success rate — higher-rated idle workers get jobs first.

python3 farm/submit.py --targets macos-arm64-dmg

Everything you can customize

Every field below is configurable through the DVForge GUI. No code editing required.

Branding
  • App name (replaces every "RustDesk" string)
  • EXE / binary file name
  • Company name (About + installer copyright)
  • Slogan text (About banner)
  • Custom app icon (title bar, taskbar, tray)
  • Custom logo (home screen circle)
  • Accent / theme color
  • UI theme (dark, light, or follow system)
  • Android package ID
Server & connection
  • Host / relay / ID server address
  • API server URL
  • Public key (baked into the binary)
  • Custom website URL
  • Custom download / update URL
  • Connection direction (both / incoming / outgoing)
  • Deny LAN discovery
  • Enable direct IP access
Security & access
  • Permanent password (baked in for unattended access)
  • Accept-session mode (password / click / both)
  • Hide connection manager window
  • Auto-disconnect when idle
  • IP whitelist (restrict who can connect)
  • Lock permissions (users can't change them)
  • Lock theme (users can't switch it)
Permissions
  • Keyboard & mouse control
  • Clipboard sharing
  • File transfer
  • Audio streaming
  • TCP tunnelling
  • Remote restart
  • Session recording
  • Block user input
  • Remote printing
  • Camera access
  • Terminal access
  • Remote config modification
Behaviour & UI
  • Disable installation (portable-only mode)
  • Disable settings tab
  • Remove wallpaper during sessions
  • Remove "new version" notification
  • Default peer view (grid / tiles / list)
  • Default UI language (15+ languages)
  • Privacy screen image
Advanced
  • Default image quality (best / balanced / low)
  • Default codec (auto / VP8 / VP9 / AV1 / H264 / H265)
  • Auto-record incoming sessions
  • Auto-record outgoing sessions
  • Windows startup delay fix
  • Raw default-settings (key=value overrides)
  • Raw override-settings (forced, users can't change)
  • Code signing (self-signed PFX or your own cert)
💡

Can't find a setting you need, or want to customize something not listed here? Let us know — we're actively adding new options.

🎨

See it before you build it

The RustDesk Client Customizer gives you a 1:1 live preview of every config field. Change the name, icon, colors, permissions, and theme — then export the same RustDesk.json that DVForge uses.

Under the hood

For the curious. How DVForge customizes, patches, and compiles a RustDesk client.

How customization actually works

RustDesk reads its config from two places, and DVForge writes to both:

WhatHowWhen it takes effect
Server, key, API, app name, URLs, feature flagssed-patched into the Rust and Dart source filesCompiled into the binary
Password, permissions, approve-modeWritten to custom_.txt as base64 JSONRead at runtime

The base64 encoding is mandatory — RustDesk's read_custom_client() starts with decode64(). Raw JSON will silently fail. DVForge handles this automatically.

On Android, custom_.txt can't be file-read, so the base64 config is also embedded into MainService.kt (native code) and native_model.dart (Flutter), plus bundled as flutter/assets/custom_.txt.

The 7-step build pipeline

When you press Start build, orchestrator.py runs these steps in order. Each streams its output to the live console.

StepWhat happens
1. CheckoutClones RustDesk v1.4.9 into workspace/rustdesk-src/. Any previous source tree is wiped first (customizations mutate the tree).
2. PatchApplies allowCustom (strips signature check, renames config file), then all optional diffs: hidecm, removeNewVersionNotif, removeSetupServerTip, xoffline, privacyScreen, Flutter dropdown fix.
3. CustomizeRuns customize.py — sed-patches server, key, app name, company, URLs into source. Writes custom_.txt. On Android, embeds config into native code.
4. Bridge codegenRuns flutter_rust_bridge_codegen to regenerate Rust↔Dart FFI bindings. Version pinned to 1.80.1.
5. BuildInvokes the OS-specific build: cargo build for Rust, flutter build for the UI. On Windows, also sets up vcpkg for FFmpeg/hwcodec.
6. SignOptional. On Windows: Authenticode with your PFX. On macOS: codesign with Developer ID. Skipped if no cert is configured.
7. CollectGathers the finished installer from the build tree into workspace/output/v1.4.9/ with your app name in the filename.

Dry run prints every command without executing anything — useful for reviewing the plan or debugging.

Why patches exist and what they do

RustDesk's upstream code has several locks and behaviors that don't make sense in a custom-branded build. DVForge applies minimal, targeted patches:

allowCustom is the critical one — RustDesk verifies a cryptographic signature on custom.txt and refuses to load configs not signed by RustDesk Inc. This 9-line block is removed so your own config works. The file is also renamed to custom_.txt (underscore) to avoid collisions.

The remaining patches are quality-of-life: hidecm hides the connection manager for restricted-direction clients; removeNewVersionNotif suppresses the "update available" prompt that points to upstream; removeSetupServerTip removes the "set up your own server" banner; xoffline fixes peer-offline styling; and the Flutter dropdown patch fixes a framework regression.

All patches are in patches/ as standard diffs — readable, auditable, and easy to update when upstream RustDesk changes.

The printer adapter (and why it exists)

RustDesk's remote printing feature depends on printer_driver_adapter.dll, which verifies the calling executable's Authenticode signature against a hardcoded allowlist of RustDesk's own certificates. Custom-branded builds fail with "printer service init failed" — even if you sign with your own cert.

DVForge includes a clean-room reimplementation: same four-function C ABI (init, uninit, get_prn_data, free_prn_data), same spool-directory polling mechanism, no signature check. It's ~140 KB with zero dependencies. The build process compiles it from source and swaps it into the installer automatically.

This is legal because the ABI is declared in RustDesk's own AGPL-licensed source, and the adapter contains no RustDesk code.

Config file format (RustDesk.json)

The config lives at configs/RustDesk.json — a single JSON file with ~70 keys covering everything from server addresses to base64-encoded icon images. You edit it through the DVForge GUI; it's also importable/exportable.

Key groups: serverIP, key, apiServer (server); appname, compname, iconbase64, logobase64 (branding); permanentPassword, passApproveMode, enableKeyboardenableCamera (security & permissions); direction, installation, settings (behavior).

The file can be large (~5 MB) when icon and logo images are embedded as base64. This is normal — it's how the build farm transmits branding assets between machines.

Project layout
PathRole
app.pyPython stdlib HTTP server + SSE log stream. Zero pip dependencies.
builder/detect.pyHardware & OS detection → capability matrix
builder/prereqs.pyToolchain presence checks & install hints
builder/toolchains.pyDownloads portable SDKs into .toolchains/
builder/config_gen.pyConfig → compiled-in values + base64 custom_.txt
builder/customize.pySource patching (sed, Android embedding, allowCustom)
builder/orchestrator.pyBuild pipeline: checkout → patch → bridge → build → sign → collect
builder/signing.pySelf-signed PFX creation & cert trust
web/Browser GUI (vanilla HTML/CSS/JS, no framework)
patches/Source diffs + Python patch scripts
farm/Multi-machine build queue (workers, submitter, HTTP queue)
printer-adapter/Open-source printer adapter DLL (Rust crate)
configs/RustDesk.jsonYour baked-in config (edit through the GUI)
workspace/output/Finished installers appear here

Frequently asked questions

The questions people ask before their first build.

Is my server IP / password safe?
Everything stays on your machine. DVForge runs on 127.0.0.1 — it never phones home, has no analytics, and sends nothing to the internet. Your config is a local JSON file.
Does it work offline?
After the first setup (which downloads toolchains and clones the RustDesk source), yes. The build itself is entirely local. No network needed once the tools and source are cached.
Can I use this commercially?
DVForge is GPL v3. RustDesk is AGPL-3.0. You can build and distribute clients for your company's internal use. Check both licenses for redistribution terms if you plan to sell or distribute publicly.
Do I need admin / root?
Not for most tools — Flutter, Rust, LLVM, NDK, JDK all install into a user-level .toolchains/ folder. The exceptions are Xcode (macOS) and Visual Studio Build Tools (Windows), which require elevation.
How much disk space does it need?
The toolchains total ~15–20 GB across all platforms. A single build needs ~5–8 GB of scratch space for the source checkout, Cargo cache, and Flutter build. The output installer is typically 15–30 MB.
Can I build for a different OS than I'm on?
Desktop clients are host-locked (Windows builds Windows, Mac builds Mac, Linux builds Linux). Android APKs can be cross-compiled from any OS. The capability board only shows what your machine can actually produce.
Play Protect warns about my APK?
Normal. Sideloaded APKs always trigger "unknown developer" on Android. Tap "Install anyway." If you sign with your own keystore instead of the default debug key, some warnings disappear.
Will it break when RustDesk updates?
DVForge is pinned to a tested RustDesk version (currently v1.4.9). When upstream releases a new version, the patches and build steps may need updating. Watch the repo or Discord for compatibility updates.

Contributors

DVForge is built and maintained by these people.

Support the project

☕ Donate

If DVForge saves you time or money, consider buying the maintainer a coffee.

PayPal

💬 Join the community

Ask questions, share builds, report bugs, and help shape the roadmap.

Discord server

⭐ Star on GitHub

Stars help new users find the project and signal that the tool is actively used.

Star the repo
🍺 This one's for VenimK — Stella time. Cheers!