---
title: "How ShareX itself goes cross-platform"
url: https://endomint.com/p/N4xxaUOZ8ONPFKy2adktpw/how-sharex-itself-goes-cross-platform
published: 2026-11-13
updated: 2026-11-13
tags: ["architecture", "avalonia", "linux", "macos", "sharex", "wayland", "windows"]
---

# How ShareX itself goes cross-platform

ShareX is moving its operating system code behind one layer so the same application runs on Windows, macOS and Linux. The work is on the `cross-platform` branch of [ShareX/ShareX](https://github.com/ShareX/ShareX/tree/cross-platform) and tracked in [issue #8867](https://github.com/ShareX/ShareX/issues/8867). [XerahS](https://endomint.com/p/KuYzFeU67XcOkiTx-g7oDA/how-xerahs-runs-on-three-platforms), a separate app started from scratch in December 2025, targets the same three platforms with a different design.

![ShareX platform tree: the app and portable libraries on ShareX.Platform, with Windows, macOS and Linux implementations below, and Linux split into a session classifier and distro families](https://endomint.com/images/sharex-platform-tree.png)

## One check at start up

`Program` looks at the operating system once and hands `PlatformServices.Initialize` one of three implementations: Windows, macOS or Linux. That is the only operating system check in shared code. Everything after it asks `PlatformServices.Current` for a service.

The app and its libraries (ShareX, ShareX.Avalonia, HelpersLib, UploadersLib, ScreenCaptureLib, ImageEditor, HistoryLib, Tools) all target plain `net10.0`. Underneath them, `ShareX.Platform` holds the interfaces and makes no operating system calls. `IPlatformServices` has one service per area: paths, startup, clipboard, capture, recording, hotkeys, windows, input, notifications, shell, credentials, secrets, thumbnails, printing, sound, taskbar and system info.

Every service reports a `FeatureSupport` value. When something cannot work on the current system, the user gets a reason instead of a silent failure.

## What each platform brings

Windows (`ShareX.Platform.Windows`) is Win32, COM and WinRT. It does GDI capture with HDR tone mapping and transparent window capture, records through FFmpeg (gdigrab, ddagrab, DirectShow) or a WinRT native recorder, and keeps Credential Manager, DPAPI, the Run key and Explorer's thumbnails. Its behaviour is meant to be identical to the code it replaces.

macOS (`ShareX.Platform.MacOS`) calls AppKit, CoreGraphics and Carbon through the Objective-C runtime. Capture goes through `screencapture` and needs Screen Recording permission, recording through FFmpeg's avfoundation, and input through Quartz events, which needs Accessibility permission. Secrets go to the Keychain, startup is a LaunchAgent, and Finder gets Quick Actions.

## Linux picks once

Linux has a shared freedesktop.org layer that works on any desktop: XDG paths and autostart, D-Bus notifications, Secret Service, the thumbnail cache, `xdg-open`, and sound through pw-play, paplay or aplay.

The rest depends on the session, so `Desktop/LinuxDesktop` classifies it as X11, Hyprland, sway, GNOME, KDE or other Wayland, and each service asks it which backend to use.

| Desktop | Capture | Recording | Hotkeys |
| :-: | :-: | :-: | :-: |
| X11 | Xlib | FFmpeg x11grab | XGrabKey |
| Hyprland | grim | wf-recorder | portal, with keys bound by ShareX |
| sway | grim | wf-recorder | sway IPC binds |
| GNOME, KDE | Screenshot portal | ScreenCast portal and GStreamer | portal |

KDE gets one extra: the portal path first tries KWin's ScreenShot2 interface for captures that do not need a picker, and a KWin script places ShareX's own windows. GNOME, KDE and other Wayland desktops do not let ShareX list other windows, so window features there are reported as unsupported.

This is where it differs from XerahS. XerahS tries a list of capture methods in order until one returns an image. ShareX decides at the start of the session which backend fits, then uses it.

Hyprland needs the most care. Its GlobalShortcuts portal registers ShareX's hotkeys but does not assign keys, so ShareX binds them itself with `hyprctl` while it runs. Keys the configuration already uses, such as Omarchy's Print Screen, are left alone and shown as in use.

## Naming the package, not installing it

`PlatformDetector` reads `/etc/os-release` and sorts the system into a family: Debian (apt), Fedora (dnf, or rpm-ostree on immutable variants such as Bazzite, Bluefin and Aurora), Arch (pacman, which covers Omarchy, EndeavourOS, Manjaro, CachyOS and SteamOS), openSUSE (zypper), NixOS, and Alpine, Gentoo, Void and Solus.

Users see the family when a feature needs a program that is missing: the reason names that distribution's package. It never runs an install and never shows an install command. Installing optional programs is left to the user.

## Shipping it

Linux gets `Scripts/install-linux.sh`, which installs a self-contained build to `~/.local` without root, or packs a `.tar.gz` with its own `install.sh`. Flatpak is deferred, because its sandbox blocks the compositor IPC, X11 window access and grim that capture relies on. XerahS ships a Flatpak and goes through the portal there, which is one of the trade-offs between the two designs.

macOS gets a `.zip` and a `.dmg` per architecture, signed with a Developer ID and notarised for a release.

The architecture is described in `docs/cross-platform.md` on the branch, with the roadmap beside it.
