CLI tool
Devolutions/IronRDP avatar
Devolutions/IronRDP

IronRDP: a sans-I/O Rust implementation of Microsoft RDP

Rust implementation of the Microsoft Remote Desktop Protocol (RDP).

3,194 stars284 forksRustApache-2.0

At a glance

What is it?
IronRDP splits RDP into composable crates with a fuzzed, no_std-compatible core that performs no I/O. It suits Rust developers embedding an RDP client, server or proxy, and it is the wrong choice if you just want a desktop app to click through.
Who is it for?
Adopt IronRDP if you are writing a Rust or WebAssembly RDP client, server or proxy and want to own the transport and event loop yourself; the screenshot and server examples are the fastest way to confirm the crate layout fits before you commit. Do not adopt it if you need a finished, packaged remote desktop application, since the windowed viewer is at 0.1.0 and the workspace still excludes some client crates as non-compiling.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What IronRDP actually solves, and for whom

RDP is a large, stateful protocol: an X.224 negotiation, MCS channel joins, capability exchange, licensing and reactivation, then a session carrying virtual channels and compressed graphics. Writing that from scratch in Rust means reimplementing both the wire formats and the connection state machine, and getting security details such as CredSSP right. IronRDP exists to remove that work. It is a crate suite rather than an application, and the README describes it as "a modular Rust implementation of RDP, the protocol behind Windows Remote Desktop." The intended reader is a developer building an RDP client, server or proxy, not someone looking for a program to install and double-click. The README's own list of users is telling: Devolutions Gateway, Cloudflare Access, Teleport, Lamco RDP Server, MacRDP and qemu-rdp all embed the crates in something else. If your goal is a remote desktop window on your laptop, the project ships two binaries, but they are the smaller part of the story.

The sans-I/O core and how a connection is driven

The design decision that shapes everything else is the absence of I/O in the core. The README states that the "continuously fuzzed, `no_std`-compatible core performs no I/O, so applications supply the transport and runtime." In practice that means the connection and session logic is a state machine: you feed it bytes you read from a socket and it hands back bytes to write. Because the core never blocks, the same code can be driven by blocking I/O, `tokio`, `futures`, or a custom event loop, and the same protocol logic can be compiled to WebAssembly or wrapped for .NET. That is a real architectural commitment, not a marketing claim: it is why the project can ship native clients, WASM bindings and C# bindings generated with Diplomat from one implementation. The cost is that you own the plumbing. There is no built-in transport, no reconnect policy and no thread model handed to you. The README's two runnable examples make the split concrete: `screenshot` is described as blocking and synchronous, while the viewer is described as asynchronous with software rendering. Same protocol core, two different runtimes.

Installing IronRDP and taking a first screenshot

The README offers two installation routes. Prebuilt, checksummed `.tar.gz` archives are attached to each GitHub release, one per supported platform, under tags like `ironrdp-viewer-v*` and `ironrdp-agent-v*`. The second route is Cargo. Note the native dependency before you start: the README says both binaries link native audio, so Linux builds need the ALSA development headers and Windows builds need NASM.

bash
cargo install ironrdp-viewer
cargo install ironrdp-agent

On Debian or Ubuntu the README names `libasound2-dev` as the package that provides the ALSA headers. With the viewer installed, the simplest invocation passes host and credentials on the command line; omitted credentials are prompted for interactively.

bash
ironrdp-viewer <HOSTNAME> --username <USERNAME> --password <PASSWORD>

If you already keep connection settings in a `.rdp` file, the viewer reads it directly, and the viewer README documents which properties are supported.

bash
ironrdp-viewer --rdp-file ./my-server.rdp

For a library first use, the README gives a meta-crate dependency with opt-in features, and two examples that ship with it. The screenshot example connects, decodes the desktop and writes a PNG using blocking I/O, which is the shortest path to confirming that your toolchain, feature flags and target server all agree.

bash
cargo run --example=screenshot -- --host <HOSTNAME> -u <USERNAME> -p <PASSWORD> -o out.png

In `Cargo.toml`, enable only the subsystems you need. Each feature maps to a standalone crate, so you can also depend on `ironrdp-pdu`, `ironrdp-connector` or `ironrdp-session` directly.

toml
[dependencies]
ironrdp = { version = "0.17", features = ["connector", "session", "graphics"] }

Logging is controlled with the `IRONRDP_LOG` environment variable, for example `IRONRDP_LOG="info,ironrdp_connector=trace"`.

ironrdp-agent and the daemon-backed CLI

The second binary takes a different shape. `ironrdp-agent` pairs a long-lived daemon with short-lived CLI calls, which the README frames as being for scripts and LLM-driven automation. The daemon starts in one terminal with an overlay file, and commands run in another.

bash
ironrdp-agent daemon-start --overlay ./credentials.rdp
ironrdp-agent connect --server <HOSTNAME> --username <USER>
ironrdp-agent screenshot ./desktop.png

The split exists for a security reason worth understanding: `connect` fails with `missing required fields` unless credentials are available, and preloading them through `daemon-start --overlay <FILE>` keeps secrets away from the IPC caller. Passing `--password` to `connect` is the alternative, and it puts the secret back in the caller's hands. For an automation harness that runs untrusted or generated commands, that distinction is the whole point. The README points to `ironrdp-agent --help-agent` for a machine-readable description of every operation, and to the agent README for the IPC format, secret handling and remote execution support.

Where IronRDP is the wrong tool

The sharpest limitation is visible in the workspace manifest rather than the README. Three crates are listed under `exclude` with the comment "FIXME: fix compilation": `ironrdp-client-glutin`, `ironrdp-glutin-renderer` and `ironrdp-replay-client`. Anyone planning to build a GPU-accelerated native client on the included glutin renderer should read that before starting, because those crates are not part of the workspace build. The viewer that does ship is described as using software rendering, and it is at version 0.1.0, so treat it as a working demonstration rather than a finished product. A second boundary is the codec split. Client-side decoding and server-side encoding are not symmetric: the README lists ClearCodec, RemoteFX Progressive and the EGFX graphics pipeline PDUs as "additional codec primitives available as libraries" rather than as wired-up client or server paths, and NSCodec and QOI are optional on the server side. If your deployment depends on a specific codec being negotiated end to end, verify it against your actual hosts instead of assuming parity. Finally, the no-I/O core means IronRDP will not manage reconnection, network changes or transport security for you. A team that wants those decisions made for them will spend more time on plumbing than expected.

IronRDP compared with xrdp and browser-based RDP

The closest thing to a like-for-like alternative in the search results is xrdp, and the difference is architectural rather than feature-level. xrdp is a server you install on a Linux machine so that Windows clients can connect to it; it is a finished daemon with its own configuration and process model. IronRDP is a library suite with a server skeleton, so you assemble the server yourself from `ironrdp-server` and the acceptor, and you decide how sessions are managed, authenticated and terminated. The README's server example is a single command, which shows the entry point but not the operational surface you would have to build. The other comparison people search for is browser-based RDP. IronRDP does target that case: it ships WebAssembly bindings and a protocol-agnostic web component published as `@devolutions/iron-remote-desktop`, and the README lists Devolutions Gateway, Cloudflare Access and Teleport as projects using it for browser access. But the WASM bindings are a compilation target for the same core, not a hosted service. You still provide the transport, typically a WebSocket bridge to a gateway, and you still handle the browser-side lifecycle. Choosing between these approaches is really a question of whether you want a daemon to configure or a protocol to embed.

Licence, MSRV and the cost of keeping up

The repository carries both `LICENSE-APACHE` and `LICENSE-MIT`, and the workspace manifest declares `license = "MIT OR Apache-2.0"`, so the crates are dual-licensed and you choose which terms apply to your use. The GitHub metadata lists Apache-2.0; the manifest is the more precise statement. This is a permissive arrangement with no copyleft obligation, but the choice between the two licences is yours to make and worth a look if your organisation has a policy on patent grants. On versioning, the README states that the MSRV is the oldest of three versions, and the sentence is truncated in the available text, so the exact rule cannot be quoted here; check the README directly. The workspace uses edition 2024 and pins a toolchain through `rust-toolchain.toml`, which means an older compiler is a real obstacle rather than a warning. Upgrade cost is shaped by the crate split: because features map to standalone crates, you can pin `ironrdp-pdu` and move the rest independently, which limits blast radius. The trade-off is that the meta crate's feature list is the thing most likely to shift between releases, and the repository has `release-plz.toml` and `cliff.toml` at the top level, so releases are generated from commit history. Read the generated changelog rather than assuming a minor bump is inert. The last push to the default branch was on 2026-07-10.

Editorial conclusion

Adopt IronRDP if you are writing a Rust or WebAssembly RDP client, server or proxy and want to own the transport and event loop yourself; the screenshot and server examples are the fastest way to confirm the crate layout fits before you commit. Do not adopt it if you need a finished, packaged remote desktop application, since the windowed viewer is at 0.1.0 and the workspace still excludes some client crates as non-compiling. Before writing code, verify the MSRV rule in the README against your toolchain, confirm which graphics codecs your target servers actually negotiate, and check whether your product needs the Apache-2.0 or the MIT half of the dual licence.

Frequently asked questions

Is RDP being discontinued?

Nothing in the IronRDP README says so. The project implements the protocol as it currently stands, covering TLS 1.2 and 1.3, CredSSP with NTLM and Kerberos, and RemoteFX, and the README lists active users including Devolutions Gateway, Cloudflare Access and Teleport.

Can I get RDP for free?

IronRDP itself is free to use: the workspace manifest declares MIT OR Apache-2.0, and the repository ships both licence files. What you supply is the transport and runtime, since the core performs no I/O.

Is RDP still used?

The README's list of projects built on IronRDP answers this indirectly: Devolutions Gateway, Cloudflare Access, Teleport, Lamco RDP Server, MacRDP and qemu-rdp all rely on the protocol for remote desktop access.

What is RDP now called?

The README does not give a new name. It calls RDP "the protocol behind Windows Remote Desktop" and refers to it as RDP throughout.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/devolutions-ironrdp.svg)](https://hysenlabs.com/projects/devolutions-ironrdp)