# Grayjay Desktop adds streaming sources to a player through plugins

> Grayjay is a multi-platform media application where the interesting part is the plugin system: developers write integrations that add new sources, and the plugins are cross-compatible between Android and the desktop app. The desktop repository is a C# application built on an embedded Chromium engine, with scripts for building and deploying on Linux and Windows, and a NixOS configuration for running it in a FHS environment.

**futo-org/Grayjay.Desktop** — Read-only mirror of Grayjay.Desktop repo for issue tracking

- Repository: https://github.com/futo-org/Grayjay.Desktop
- Website: https://gitlab.futo.org/videostreaming/Grayjay.Desktop
- Stars: 894 · Forks: 60
- Language: C#
- License: NOASSERTION
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/futo-org-grayjay-desktop

## The GitHub repository is a mirror, the code lives on GitLab

The first thing to understand about this repository is that it is not the source of truth. The project description says it plainly: read-only mirror of the Grayjay.Desktop repo for issue tracking, and the homepage points at the real one, gitlab.futo.org/videostreaming/Grayjay.Desktop.

That is an unusual but sensible arrangement. The code and the issues tracker's real home live on a self hosted GitLab instance, and GitHub is kept as a read-only copy so that people who look for the project on GitHub can find it, read the documentation and open an issue. The README links the site, the documentation and the issue tracker, and the top level of the repository contains a.gitmodules file, which is what a mirror with submodules needs.

The practical consequence for an engineer is that a clone of the GitHub repository is not a working development setup. The build scripts, the CI definitions and the deployment pipelines in the tree are the ones the organisation uses, and the.gitlab-ci.yml and.gitlab-ci-desktop-deploy.yml files at the root show that continuous integration runs on GitLab.

It also means the project is self hosted rather than a GitHub hosted project, which is a deliberate choice by an organisation whose stated purpose is, in the README's words, developing technologies that frustrate centralization and industry consolidation, both through in-house engineering and through investment.

For a reader evaluating the project, the honest summary is that this is one organisation's application, mirrored for visibility, and the dependency on that organisation is structural rather than incidental.

## The plugin system is the product, and it crosses Android and desktop

Grayjay is described as a multi-platform media application that lets you watch content from multiple platforms in a single application, and the mechanism is an extendable plugin system through which developers can make new integrations with additional platforms.

The detail that matters is in the next sentence: plugins are cross-compatible between Android and Desktop. That is a stronger claim than a plugin API per platform, and it changes what a plugin is. A source plugin is not a user interface for the desktop app, it is an integration with a content platform, and the same plugin artifact serves both the Android and the desktop application. A developer who writes an integration for a platform writes it once.

The Sources screen is where that becomes visible to the user. It is where you install new source plugins, change which sources are used, or configure the behaviour of a source. So the set of platforms the application supports is not fixed by the organisation, it is extended by whoever writes a plugin and distributes it.

The other screens in the README are more conventional but worth noting for scope. The Home screen holds the recommendations found in the respective applications, so recommendations are aggregated across sources rather than belonging to one platform. There is a Channels screen, a Details screen for the player, and a Downloads screen.

The Downloads feature is worth calling out because it goes beyond watching. Grayjay supports downloads for offline viewing of videos, and it can also export them to files usable outside of Grayjay. For a media application built on a plugin architecture, being able to take a video away with you is a deliberate capability rather than an incidental one.

## The player is an embedded Chromium, and the repository shows the seams

The repository listing is where the architecture of a desktop shell becomes visible, and there are several directories whose names are informative.

Grayjay.Desktop.CEF/ is the clearest one. CEF is the Chromium Embedded Framework, so the desktop application renders its interface in an embedded browser rather than in a native widget toolkit. JustCef/ is a second directory in the same family, and curlbind/ is a native component, which is consistent with an application that has to talk to services the browser stack will not do for it.

Around that sit the other layers. Grayjay.Engine/ is the application engine, Grayjay.ClientServer/ handles the client and server relationship, SyncServer/ is a separate synchronisation component, and Keychain.MacOS/ is the macOS keychain integration, which is a platform specific credential store.

There is also Grayjay.Desktop.Web/, which is the web front end, and Grayjay.Desktop.Tests/ and Grayjay.Windows.Tests/, so there is a test project for the desktop code and one specifically for Windows behaviour. The solution file is Grayjay.Desktop.sln.

The Linux packaging files are at the root and are a good indicator of the deployment story. app.grayjay.Grayjay.desktop is a desktop entry file, app.grayjay.Grayjay.metainfo.xml is the AppStream metadata, which is how software is described to the Linux software centres, and rcedit-x64.exe is a Windows tool for editing binary resources such as the icon and version information inside a Windows executable. There is also FUTO.MDNS, which suggests the application announces itself on the local network.

None of this is required reading for a user, but for an engineer it explains why the repository carries so many platform specific files: a cross-platform media shell with an embedded browser, a native helper and per-platform packaging is a lot of moving parts by nature.

## Build, deploy and maintenance scripts live in the repository root

The root of the repository is a set of shell scripts, and they describe the release process better than any prose would.

There is build.sh, plus platform variants: build_linux.sh, build_linux_steam.sh, and run.sh for running from a checkout. Then the deployment scripts: deploy_linux.sh, deploy_windows.sh, deploy_windows_installer.sh and sign_windows.sh, which is the Windows code signing step and therefore tells you that the Windows builds are signed. cloudflare_purge_desktop.sh is a content cache purge, which fits an application that fetches manifests and media metadata from a CDN, and remote_maintenance.sh is a maintenance trigger against the running service. generate_changelogs.sh assembles the changelog.

Two of those deserve attention from a user rather than a developer. build_linux_steam.sh means there is a Steam build, so the application is distributed through a store as well as directly, and the presence of a Steam variant alongside a standalone Linux build is a distribution decision the organisation has made explicitly.

The CI definitions are separate: .gitlab-ci.yml for the general pipeline and .gitlab-ci-desktop-deploy.yml for the desktop deployment, which implies the desktop application has its own release pipeline with its own triggers, separate from the other components in the organisation's GitLab.

For someone who wants to run Grayjay Desktop, the practical answer is that you download it from the site, grayjay.app/desktop/, and the README explicitly says the website is the place for a more elaborate showcase of features and downloads. The scripts in the repository are for building and shipping the application, not for an end user install.

## The macOS build is not fully signed yet, and it says so

There is a caveat at the top of the README for macOS users, and it is the kind of caveat that saves a user an hour.

The README says that the Apple signing and notarization is not entirely done yet, and that you have to run a command once to run the application. The command removes the quarantine attribute from the downloaded bundle:

```bash
xattr -c ./Grayjay_osx-arm64.app
```

and for the Intel build:

```bash
xattr -c ./Grayjay_osx-x64.app
```

Both are one time commands, and the reason they exist is that the application is not notarised, so macOS quarantines the download and refuses to open it until the user clears that attribute. This is a normal consequence of an unsigned or unnotarised build, and it is also a warning about the state of the macOS packaging: the organisation is telling you plainly that the Apple path is not finished.

The two architectures matter too. The arm64 build is the Apple Silicon one and the x64 build is the Intel one, so a user on either has to pick the command that matches what they downloaded.

The same pattern shows up in the repository, where Keychain.MacOS/ is a separate component for the platform keychain and sign_windows.sh exists for Windows but has no visible macOS equivalent, which is consistent with the signing and notarization work not being finished on the Apple side.

For a macOS user this is a small friction point with a one line fix, and for anyone evaluating the project's polish it is a useful, current signal about where the platform support stands.

## The NixOS configuration is the clearest statement of the dependencies

The README ends with a NixOS configuration, and it is more informative than it looks, because an FHS environment has to declare everything the application expects to find on the system.

The configuration builds a fake hierarchy sandbox with the name fhs, and lists the packages the application needs:

```nix
(pkgs.buildFHSEnv {
  name = "fhs";
  targetPkgs = _: with pkgs; [
    libz
    icu
    libgbm
    openssl # For updater

    xorg.libX11
    xorg.libXcomposite
    xorg.libXdamage
    xorg.libXext
    xorg.libXfixes
    xorg.libXrandr
```

The list describes the application precisely. libz and openssl are the compression and TLS libraries, and the comment on openssl says it is for the updater, so the application checks for and applies its own updates. icu is the Unicode library, which a media application with user generated titles needs for text handling. libgbm is the graphics buffer manager, which Chromium needs to render.

Then there is the X11 client library set, libXcomposite, libXdamage, libXext, libXfixes and libXrandr, which are the libraries Chromium and its sandboxing and rendering layers depend on, and further down the list gtk3, glib, nss, nspr, dbus, atk, cups, libdrm, expat, libxkbcommon, pango, cairo, udev, alsa-lib, mesa, libGL and libsecret.

Two of those are worth pausing on. alsa-lib and libGL mean the application is an ordinary desktop program with audio and hardware accelerated graphics, not a headless service. And libsecret is the freedesktop secret service, which is the keyring interface, which connects to the Keychain.MacOS component on the other side of the platform divide.

So the NixOS configuration is a complete dependency bill for the desktop application, and a good place to check what a given Linux system needs before you try to run it.

## One organisation, a custom licence, and no tagged releases

FUTO describes itself in the README as an organisation dedicated to developing, both through in-house engineering and investment, technologies that frustrate centralization and industry consolidation. That is a mission statement with consequences, and the most concrete one is that Grayjay is a single company's product rather than a community project.

The licence field on the repository records a custom licence that GitHub cannot classify, and the root of the tree holds a LICENSE.md file, which is the authoritative text. Unlike the earlier projects in this set, there is no standard SPDX identifier to lean on, so anyone planning to redistribute the application, or to build on its plugin interface, should read that file rather than assume a permissive licence.

There is a second, non standard aspect worth noting. The application is designed to aggregate content from platforms that are themselves centralised services, and the plugins are the extension point through which that happens. The FUTO position, stated plainly, is that centralisation is the thing to be frustrated with, and an application that puts a plugin boundary between the user and the platform is consistent with that.

On maintenance, the repository is not archived and the last push was on 2026-10-21, so work continues. There are no GitHub releases in the mirror, which follows from the mirror arrangement.

The practical summary for a user is that Grayjay Desktop is a well built application with an unusually open extension model, distributed by one organisation whose stated purpose is to compete with the platforms it aggregates, and whose macOS packaging is the one part that is not yet finished.

## Conclusion

Adopt Grayjay Desktop if you want one player for several video platforms, you are willing to write or install source plugins, and you value that the plugins are shared between the Android and desktop applications. Do not adopt it if you need a single service with guaranteed long term support, since the project is run by one organisation and the GitHub repository is only a mirror, and do not adopt it on macOS without reading the signing caveat, because the app is not yet fully signed and notarised. Before you build on it, clone from the GitLab repository at gitlab.futo.org rather than the GitHub mirror, check whether a plugin exists for the platform you need, and read LICENSE.md, since the repository records a custom licence rather than a standard one.

## FAQ

### What is Grayjay Desktop?

It is a multi-platform media application from FUTO that lets you watch content from multiple platforms in a single application, using an extendable plugin system so developers can add integrations for additional platforms.

### What does the Grayjay plugin system let a user do?

The Sources screen is where you install new source plugins, change which sources are used, or configure source behaviour. Plugins are cross-compatible between the Android and the desktop applications, so one integration serves both.

### Can I run Grayjay Desktop on macOS?

Yes, but the README says the Apple signing and notarization is not entirely done yet, so you have to run xattr -c on the downloaded .app once, either the arm64 or the x64 build, before it will open.

### Where is the real Grayjay Desktop repository?

The GitHub repository is a read-only mirror kept for issue tracking. The canonical source is the GitLab repository at gitlab.futo.org/videostreaming/Grayjay.Desktop, which is where the CI definitions and the desktop deploy pipeline live.

### What licence does Grayjay Desktop use?

The licence field on the repository records a custom licence that GitHub cannot classify, and the terms are in the LICENSE.md file at the repository root. There are no GitHub releases in the mirror, and the last push was on 2026-10-21.

## Sources

- [futo-org/Grayjay.Desktop on GitHub](https://github.com/futo-org/Grayjay.Desktop)
- [Issues](https://github.com/futo-org/Grayjay.Desktop/issues)
- [Project website](https://gitlab.futo.org/videostreaming/Grayjay.Desktop)
- [README](https://github.com/futo-org/Grayjay.Desktop/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/futo-org-grayjay-desktop
