SessionKit · RemoteViewer
.NET remote-desktop SDK

Remote desktop,
as a library.

Drop cross-platform screen sharing and remote control into your own .NET app — capture a screen, stream it, inject the operator's input — over any byte channel you already have. SessionKit is the session layer; you bring the pipe.

Get started →
$dotnet add package RemoteViewer.SessionKit
net8.0 · net9.0 one dependency (SkiaSharp) 0.9.0
host · capturing
delta tiles · H.264 · input ⟶
Two ends, one channel

A host captures. A viewer drives. You supply the wire.

SessionKit never opens a socket or traverses a NAT. Anything that carries a byte message — a WebSocket, a framed socket, an SSH tunnel, ConnectKit — is a valid transport. The whole session rides it, multiplexed by a one-byte tag.

host + viewer · C#
// Device — capture this screen, apply the operator's input
var host = new SessionHost(
    channel,                                 // any ISessionChannel you provide
    WindowsScreenCapture.CreateBest(out _),  // DXGI → GDI  (or X11 / CoreGraphics)
    new WindowsInputSink());
host.Start();

// Operator — show frames, drive the machine
var viewer = new ViewerSession(channel);
viewer.OnFrame += f => Blit(f.Bgra, f.Width, f.Height);
viewer.SendMouseMove(0.5f, 0.5f);
viewer.SendText("hello");

01 Bring your own channel

One interface — Send, OnData, OnClosed. The single rule: one send arrives as one message. It slots into apps that already have a connection.

02 Video that just works

Changed 16×16 tiles, JPEG-compressed, by default — no codec, runs everywhere. Opt into hardware H.264 and the codec is negotiated automatically, with JPEG as the fallback.

03 More than pixels

Two-way clipboard (text + image), chunked hash-verified file transfer, and audio all ride the same channel. Input is source-agnostic — a phone's touch maps to the same calls a mouse makes.

What's in the box

Native on every side. Honest about the edges.

Windows, Linux, and macOS can each be the host and the viewer. Backends are chosen per OS behind stable seams — and where a backend isn't there yet, the table says so.

CapabilityWindowsLinuxmacOS
Screen captureDXGI → GDIX11 (XGetImage)CoreGraphics ¹
Input injectionSendInputXTest + UnicodeCGEvent + Unicode
H.264 encodeMedia FoundationVA-APIVideoToolbox
H.264 decodeMedia FoundationVA-APIVideoToolbox
ClipboardWin32 · text + imagexclip · text + imagein-memory ²
File transferchunked + hashedchunked + hashedchunked + hashed
AudioWASAPI loopback

¹ Needs Screen Recording permission — SessionKit ships preflight & request helpers.   ² Native macOS clipboard is a planned backend behind the same interface.

Verified, not asserted

Every codec decodes every other codec.

The H.264 wire format is platform-independent Annex-B. The full encode/decode matrix cross-decodes in every direction — tested on real Windows, macOS, and Linux hardware, colorspace and multi-slice handling included.

encoded on →
enc ╲ dec
Media Foundation
VideoToolbox
VA-API
Media Foundation
✓ self
VideoToolbox
✓ self
VA-API
✓ self

A Linux box captured its screen over X11, encoded on its Intel iGPU, and streamed over TCP to a decoding viewer — end to end. ✓ = decodes pixel-accurate

Where it fits

Built to embed, not to install.

The hard, valuable parts of a remote-desktop product are transport, relay, and support — SessionKit deliberately leaves those to you, and does the session layer exceptionally well.

.NET-native

One managed package. No native SDK to vendor, no C++ interop to maintain — the building blocks elsewhere are C, C++, Rust, or JavaScript.

Transport-agnostic

You own the channel and its security. Pair it with ConnectKit for an encrypted, NAT-traversing pipe — or anything else.

License-clean H.264

Encoding rides each OS's own codec, so the platform covers the H.264 patent licensing — not your shipped binary.

Composable by design

Screen source, input sink, clipboard, and channel are all interfaces. Use the built-ins, or swap in your own.

Small & auditable

A focused surface with a single dependency. You can read it, test it, and reason about what crosses the wire.

For real products

Remote support, RMM, kiosk & POS, industrial-HMI consoles — anywhere a .NET app needs "see and control that machine."

Status · 0.9.0

Release-candidate, in the open.

50
unit tests
3
OSes, both ends
9 / 9
codec paths

The public API is settling toward 1.0 and broadly verified: an offline self-test, live two-process sessions on all three OSes, and the cross-OS codec matrix above. Remaining work is additive behind existing seams — it won't break your code.

  • shippedCross-platform host & viewer, negotiated hardware H.264, clipboard, files, audio.
  • shippedDecoder colorspace (BT.601/709) and macOS Screen-Recording permission UX.
  • nextWayland capture (PipeWire + portal) — today X11/XWayland is covered.
  • nextmacOS ScreenCaptureKit and a native macOS clipboard backend.
Get started

Five minutes to a live session.

Install the package, run the offline self-test, then wire your channel. The whole path — host, viewer, H.264, clipboard, files — is in the quickstart.

$dotnet add package RemoteViewer.SessionKit
View on NuGet →

Evaluating for a product? Talk to us about licensing →