Low-latency desktop and game streaming with first-class Linux and Windows hosts.
Run the host on a Linux machine or a Windows PC, connect from a Mac, PC, phone, tablet, or TV, and stream your desktop or games — each device at its **own native resolution and refresh rate**, over your local network. 📖 **Documentation: [docs.punktfunk.unom.io](https://docs.punktfunk.unom.io)** — start with [How It Works](https://docs.punktfunk.unom.io/docs/how-it-works) or the [Quick Start](https://docs.punktfunk.unom.io/docs/quickstart). 💬 **Community: [Discord](https://discord.gg/kaPNvzMuGU)** — chat, support, and **Android beta access** · **[r/Punktfunk](https://www.reddit.com/r/Punktfunk/)**. 🔒 **Security:** found a vulnerability? Report it privately to **security@punktfunk.com** — see [SECURITY.md](SECURITY.md). Please don't open a public issue. Punktfunk pairs a **virtual-display streaming host** with native clients on every platform. It speaks the existing **GameStream** protocol, so any [Moonlight](https://moonlight-stream.org/) client works day one — and adds its own faster **`punktfunk/1`** protocol that breaks the ~1 Gbps FEC wall with a **GF(2¹⁶) Leopard-RS** transport. A single shared **Rust core** (`punktfunk-core`) holds the protocol, FEC, and crypto, linked into the host and every native client — directly as a Rust crate on Linux and Windows, and over a stable C ABI from the Apple and Android apps. ## What makes it different - **Your device's exact mode.** For each client that connects, the host spins up a virtual display sized to that device — 1080p60 to a laptop, 1440p120 to a desktop, 4K to a TV, all at once. No letterboxing, no scaling, no rearranging your real monitors. - **Displays you configure, not just create.** Keep a game's display (and the game) alive across disconnects so a reconnect drops straight back in; make the stream your sole desktop or extend alongside your monitors; let several devices become monitors of one desktop; keep each client's scaling. One-click presets in the console — a dedicated couch box, a shared desktop, a multi-monitor workstation. See [Virtual displays](docs-site/content/docs/virtual-displays.md). - **A real virtual display on Windows, too.** On Linux the host uses per-compositor virtual outputs; on Windows you get the same on-the-fly virtual display — at the client's exact mode, no physical monitor or dummy HDMI plug, even on the secure desktop (UAC / lock screen). It also has **its own indirect display driver (IDD)** the host pushes finished frames straight into, rather than scraping a screen — tight, push-based integration that's unusual for a Windows streaming host. - **Low latency, GPU end to end.** Frames go straight from the compositor to the NVENC encoder with zero CPU copies (dmabuf → CUDA/Vulkan → NVENC), over a transport tuned for responsiveness rather than throughput. Stable 240 fps at 5120×1440; sub-millisecond capture-to-reassembly on-box, ~1.3 ms cross-machine on a LAN. (On Linux AMD/Intel, Vulkan Video for HEVC and AV1 with VAAPI for H.264 and as the fallback; a GPU-less software H.264 encoder exists as a last resort.) - **A library that fills itself.** Steam and non-Steam titles show up as a grid on every client, and plugins add their own sources — ROM Manager (your ROM collection, matched to installed emulators), Playnite, VirtualHere. Install them from the console's **Plugins** page or with `punktfunk-host plugins add`. See [Plugins](https://docs.punktfunk.unom.io/docs/plugins). - **Works with what you already have.** Any Moonlight/Artemis client connects over GameStream — and native apps for macOS, Linux, Windows, and Android use the lower-latency `punktfunk/1` protocol. - **Secure by default.** Hosts require a one-time SPAKE2 **PIN pairing**; after that, devices reconnect on a pinned identity. No accounts, no cloud. Hosts auto-advertise over mDNS, so clients find them on the network without typing an IP. ## Status | Component | State | |-----------|-------| | **Core** — `punktfunk-core` + C ABI (protocol · FEC · crypto · QUIC) | ✅ Complete & hardened | | **GameStream host** → stock Moonlight | ✅ Live end-to-end: pairing, RTSP, audio, per-client virtual output at native resolution, GPU zero-copy NVENC, gamepads | | **Native protocol** — `punktfunk/1` | ✅ Validated live: QUIC control + GF(2¹⁶) FEC/AES-GCM data plane, PIN pairing, mDNS discovery, mid-stream mode renegotiation | | **Windows host** (Windows 11 22H2+, x64) | ✅ Beta — shipping as a signed installer: its own all-Rust IddCx **virtual display** (secure-desktop capable) with a **sealed IDD-push** capture path — finished frames pushed straight into its own driver, not screen-scraped (no DDA/WGC) · GPU encode (NVENC on NVIDIA, AMF/QSV on AMD/Intel, software H.264 without a GPU) · WASAPI audio · bundled virtual-gamepad drivers (no ViGEmBus) · HDR incl. Vulkan-game HDR. NVIDIA live-validated; AMD/Intel CI-green | | **macOS / iOS / tvOS client** (`clients/apple`) | ✅ Streaming live: VideoToolbox decode (HEVC, and AV1 on hardware that decodes it), controllers incl. DualSense, discovery, pairing, speed test | | **Linux client** (`clients/linux` + `clients/session`) | ✅ Streaming live: relm4/GTK4 launcher shell that spawns a Vulkan session binary — Vulkan Video / VAAPI / software decode, PipeWire audio, SDL3 controllers, Skia console UI; ships as Flatpak/apt/rpm/Arch | | **Android client** (`clients/android`, phone + TV) | ✅ Streaming live: AMediaCodec decode + HDR10, AAudio audio, controllers, discovery, pairing | | **Windows client** (`clients/windows`, WinUI 3) | ✅ Streaming live: WinUI 3 shell + Vulkan session presenter, hardware decode on all GPU vendors via Vulkan Video → D3D11VA → software (NVIDIA + Intel validated on glass), WASAPI audio, SDL3 controllers, discovery, pairing; ships as signed MSIX (x64 + ARM64). Hardware decode and HDR10 present validated on glass on NVIDIA and Intel, including HDR pass-through on the Intel D3D11VA path | | **Web console + management API** (`web/`) | ✅ TanStack console over the OpenAPI mgmt API: host status, paired devices, on-demand PIN pairing, game library, virtual-display presets, plugin store, GPU selection, performance capture graphs, live host logs, host updates | Every native client also ships a tiered **stats overlay** (Compact / Normal / Detailed) with a shared vocabulary across platforms, and the session client carries a full gamepad-driven **console shell** (`pf-console-ui`): host list, PIN pairing, settings, and an on-screen keyboard. The **GameStream host works with a stock Moonlight client** — validated live on NVIDIA hardware (RTX 5070 Ti, RTX 4090): PIN pairing that persists across restarts, an app catalog, RTSP/ENet/audio, and **video at the client's exact resolution and refresh** via a per-session virtual output (KWin, gamescope, Mutter, and Sway/wlroots backends), encoded with GPU **zero-copy** (dmabuf → CUDA/Vulkan → NVENC) up to 5120×1440@240. The native **`punktfunk/1`** protocol adds a QUIC control plane and a GF(2¹⁶) Leopard-FEC + AES-GCM data plane (p50 ~0.8 ms capture→received at 720p120), with mid-stream mode renegotiation and a wall-clock skew handshake so latency stays valid across machines. Both run from **one process**: bare `punktfunk-host serve` is the **secure native-only default** (`punktfunk/1` + the management API/web console), and `serve --gamestream` additionally enables the GameStream/Moonlight-compat planes (opt-in, trusted-LAN only — GameStream has inherent on-path weaknesses). The host is managed through a REST API and web console. Builds against FFmpeg 7 or 8. What works where: **[the support matrix](https://docs.punktfunk.unom.io/docs/support-matrix)** · where it's heading: **[the roadmap](https://docs.punktfunk.unom.io/docs/roadmap)**. ## Install the host Pick your platform and install from its package registry — the per-platform guide covers adding the repo, first run, and the web console. The Linux host is the primary, most battle-tested path; on SteamOS the host is built on-device by a script instead, and a Windows host ships as a signed installer (all-vendor: NVIDIA, AMD, Intel). | Platform | Install | Guide | |--------|---------|-------| | **Ubuntu / Debian** (apt) | `sudo apt install punktfunk-host` *(after adding the repo)* | [Ubuntu / Debian](https://docs.punktfunk.unom.io/docs/ubuntu) · [packaging/debian](packaging/debian/README.md) | | **Bazzite / Fedora Atomic** (systemd-sysext) | `curl -fsSLO https://git.unom.io/unom/punktfunk/raw/branch/main/packaging/bazzite/punktfunk-sysext.sh && sudo bash punktfunk-sysext.sh install` *(no layering, no reboot; rpm-ostree + bootc also supported)* | [Bazzite](https://docs.punktfunk.unom.io/docs/bazzite) | | **Fedora** (dnf) | `sudo dnf install punktfunk` *(after adding the repo; the console comes with it)* | [Fedora](https://docs.punktfunk.unom.io/docs/fedora) · [packaging/rpm](packaging/rpm/README.md) | | **Arch / CachyOS** (pacman) | `sudo pacman -Syu punktfunk-host` *(binary repo — always a full `-Syu`)* | [Arch Linux](https://docs.punktfunk.unom.io/docs/arch) · [packaging/arch](packaging/arch/README.md) | | **SteamOS / Steam Deck** (on-device build) | `bash ~/punktfunk/scripts/steamdeck/install.sh` *(after cloning this repo to `~/punktfunk`)* | [SteamOS (Host)](https://docs.punktfunk.unom.io/docs/steamos-host) | | **Windows** (11 22H2+, x64) | `winget install unom.PunktfunkHost` *(after `winget source add -n punktfunk https://winget.punktfunk.unom.io -t Microsoft.Rest`)* · or the signed `setup.exe` from the package registry | [Windows Host](https://docs.punktfunk.unom.io/docs/windows-host) · [packaging/winget](packaging/winget/README.md) | `punktfunk-host` is the streaming host; `punktfunk-web` is the browser console (pairing + status). **Linux:** every package ships systemd **user** units, so you don't launch the host by hand. The host unit won't start until `~/.config/punktfunk/host.env` exists, so copy the template your package installed first: ```sh mkdir -p ~/.config/punktfunk # /usr/share/punktfunk/ on Fedora/Arch/Bazzite, /usr/share/punktfunk-host/ on Debian/Ubuntu # (on Bazzite take host.env.bazzite instead) cp /usr/share/punktfunk/host.env.example ~/.config/punktfunk/host.env systemctl --user enable --now punktfunk-host # the streaming host systemctl --user enable --now punktfunk-web # the web console (Arch: install punktfunk-web first) ``` The shipped host unit runs `serve --gamestream` — the native `punktfunk/1` plane **plus** the GameStream/Moonlight-compat planes, which belong on a trusted LAN only; for a native-only host drop the flag with a `systemctl --user edit punktfunk-host` drop-in (which needs an empty `ExecStart=` line before the replacement — the install guide has the snippet). Then open `https://