A Flutter plugin for Remote Desktop Protocol (RDP) connections.
Features:
- Dart APIs to open and manage RDP sessions.
- Native macOS platform view widget to render the remote desktop in Flutter.
- Input forwarding for keyboard, mouse, and touchpad events.
- Bidirectional clipboard support.
- GDI and GFX rendering backends support.

‼️ Development status (Early Stage) ‼️
This project is early-stage / experimental.
- API changes can be breaking, even in minor updates.
- Method-channel contract details may evolve while the plugin matures.
- Current production readiness should be evaluated carefully per use case.
If you adopt frdp now, pin a specific commit or version and test upgrades before rollout.
Platform support
| macOS | Windows | Linux | iOS | Android | Web |
|---|---|---|---|---|---|
| supported ✅ | planned 🗓️ | planned 🗓️ | not planned ❌ | not planned ❌ | not planned ❌ |
Installation
Add the dependency to your pubspec.yaml.
From pub.dev
dependencies:
frdp: ^0.1.0
From GitHub
dependencies:
frdp:
git:
url: https://github.com/riccardo-tralli/frdp.git
ref: main
From local
dependencies:
frdp:
path: ../frdp
Then run:
flutter pub get
Get started
Import the package:
import "package:frdp/frdp.dart";
Create a plugin instance and connect:
final frdp = const Frdp();
final session = await frdp.connect(
const FrdpConnectionConfig(
host: "192.168.1.1",
port: 3389, // optional, default 3389
username: "rdp-user",
password: "rdp-password",
domain: "WORKGROUP", // optional
ignoreCertificate: true, // optional, default false
enableClipboard: true, // optional, default true
disableClipboardPerformanceFallback: false, // optional, default false
renderingBackend: FrdpRenderingBackend.gdi, // optional, default gdi
performanceProfile: FrdpPerformanceProfile.medium, // optional, default medium
connectTimeoutMs: 15000, // optional
),
);
Use a custom profile when you need fine-grained control over FreeRDP settings:
final session = await frdp.connect(
const FrdpConnectionConfig(
host: "192.168.1.1",
username: "rdp-user",
password: "rdp-password",
renderingBackend: FrdpRenderingBackend.gfx,
performanceProfile: FrdpPerformanceProfile.custom,
customPerformanceProfile: FrdpCustomPerformanceProfile(
desktopWidth: 1920,
desktopHeight: 1080,
connectionType: FrdpConnectionType.lan,
colorDepth: 32,
disableWallpaper: false,
allowFontSmoothing: true,
gfxH264: true,
gfxAvc444: true,
),
),
);
Render the remote desktop in your widget tree:
FrdpView(sessionId: session.id)
Disconnect when done:
await frdp.disconnect(session.id);
FreeRDP Library
The plugin builds and caches FreeRDP from source automatically. FreeRDP is expected to be provided through this embedded bootstrap flow rather than through a preinstalled package manager copy.
Default behavior:
- During
pod install/ first macOS build,macos/scripts/ensure_embedded_freerdp.shclones FreeRDP from the official repo and builds static libraries. - Build artifacts are cached in
macos/.freerdp/installand reused on subsequent builds. - Dependencies are also built and cached in
macos/.freerdp/deps/installby default. - The embedded build disables standalone FreeRDP desktop clients such as SDL/X11, WinPR helper executables, and optional media codec stacks like Opus/FFmpeg, keeping only the libraries/channels needed by the plugin.
Build prerequisites:
gitcmakeninja(optional, for faster builds)curl,perl,make(required to build embedded OpenSSL)
Useful environment variables:
# Pin to a specific upstream ref/tag/branch
export FREERDP_GIT_REF=3.24.2
# Change repo (fork/mirror)
export FREERDP_GIT_URL=https://github.com/FreeRDP/FreeRDP.git
# Architecture to build into the static libraries
export FREERDP_ARCH="arm64"
# macOS deployment target for the embedded static libraries and pod target
export FRDP_MACOS_DEPLOYMENT_TARGET=10.15
# Embedded OpenSSL version
export OPENSSL_VERSION=3.3.2
# Embedded jansson source/ref
export JANSSON_GIT_URL=https://github.com/akheron/jansson.git
export JANSSON_GIT_REF=v2.14
Public API overview
Main exports:
Frdp: API client (connect,disconnect, state checks, input forwarding)FrdpConnectionConfig: connection settings and validationFrdpSession: session identifier and current stateFrdpConnectionState:disconnected,connecting,connected,errorFrdpRenderingBackend: rendering backend (gdi,gfx)FrdpPerformanceProfile: preset profile for connection quality/performance trade-offsFrdpCustomPerformanceProfile: fine-grained FreeRDP display/performance settingsFrdpConnectionType: link-type hint used by custom profileFrdpClipboard: utility for clipboard events and remote clipboard writesFrdpView: RDP rendering widget
Input forwarding
frdp forwards:
- Pointer events (
x,y,buttonsbitmask) - Key events (
keyCode,isDown)
The pointer buttons bitmask follows Flutter conventions:
1: left button2: right button4: middle button8: back button16: forward button
Method-Channel Contract Tool
The plugin uses a generated channel contract to keep Dart and native implementations aligned.
- Source of truth:
tool/channel_contract.json - Generated Dart file:
lib/src/channel/frdp_channel_contract.dart - Generated macOS file:
macos/Classes/plugin/FrdpChannelContract.swift - Generator:
tool/generate_channel_contracts.dart
Maintenance
Do not edit files manually. Update tool/channel_contract.json and regenerate contract files:
dart tool/generate_channel_contracts.dart
Example app
A working example app is available in example.
Run it with:
cd example
flutter pub get
flutter run -d macos
License
frdp is distributed under the MIT License. See LICENSE.