{"id":47700549,"url":"https://github.com/stslex/claude-desktop-linux","last_synced_at":"2026-05-16T02:20:11.334Z","repository":{"id":347544756,"uuid":"1194312821","full_name":"stslex/claude-desktop-linux","owner":"stslex","description":"Unofficial Linux port of Claude Desktop — extracts the macOS DMG, replaces native modules with JS stubs, unlocks Cowork, and builds RPM, DEB, Arch, Nix, and AppImage packages via GitHub Actions.","archived":false,"fork":false,"pushed_at":"2026-04-07T18:26:50.000Z","size":457,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-07T20:35:56.771Z","etag":null,"topics":["claude-code","claude-desktop","claude-desktop-app","claude-linux"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stslex.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-28T07:16:38.000Z","updated_at":"2026-04-05T11:14:40.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/stslex/claude-desktop-linux","commit_stats":null,"previous_names":["stslex/claude-desktop-linux"],"tags_count":53,"template":false,"template_full_name":null,"purl":"pkg:github/stslex/claude-desktop-linux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stslex%2Fclaude-desktop-linux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stslex%2Fclaude-desktop-linux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stslex%2Fclaude-desktop-linux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stslex%2Fclaude-desktop-linux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stslex","download_url":"https://codeload.github.com/stslex/claude-desktop-linux/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stslex%2Fclaude-desktop-linux/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31676552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T08:18:19.405Z","status":"ssl_error","status_checked_at":"2026-04-11T08:17:08.892Z","response_time":54,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code","claude-desktop","claude-desktop-app","claude-linux"],"created_at":"2026-04-02T17:07:46.296Z","updated_at":"2026-05-16T02:20:11.316Z","avatar_url":"https://github.com/stslex.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Claude Desktop Linux\n\n\u003e Unofficial Linux repackager for the macOS Claude Desktop application.\n\u003e Produces self-contained RPM, DEB, Pacman, Nix, and AppImage packages from Anthropic's official release.\n\n[![Build](https://github.com/stslex/claude-desktop-linux/actions/workflows/build.yml/badge.svg)](https://github.com/stslex/claude-desktop-linux/actions/workflows/build.yml)\n[![Latest Release](https://img.shields.io/github/v/release/stslex/claude-desktop-linux)](https://github.com/stslex/claude-desktop-linux/releases/latest)\n[![License](https://img.shields.io/badge/scripts-MIT-blue)](LICENSE)\n\n---\n\n## What It Does\n\nAnthropic ships Claude Desktop for macOS and Windows only. This project\ndownloads the official macOS release from Anthropic's CDN via `RELEASES.json`,\nextracts the cross-platform Electron app bundle (`app.asar`), replaces the two\nmacOS-native Node addons with pure-JS stubs, and patches the platform gate\nthat hides the Cowork (Claude Code) feature on non-macOS systems. The result\nis repackaged as a self-contained **RPM**, **DEB**, **Pacman**, **Nix**, and\n**AppImage** — Electron is bundled in all packages, no system-level Electron\ninstallation required.\n\nThe key insight: the VM that Cowork boots on macOS already runs a Linux\nx86_64 rootfs. On Linux we skip the VM entirely and run `claude-code`\ndirectly — the macOS app is already 90% a Linux app.\n\nSee [ARCHITECTURE.MD](ARCHITECTURE.MD) for design decisions and trade-offs.\n\n---\n\n## Features\n\n- **Chat** — full Claude Desktop chat interface on Linux\n- **MCP** — Model Context Protocol support works as-is (it is pure JS)\n- **Cowork (Claude Code)** — unlocked and functional via `bubblewrap` sandbox\n  or direct host execution\n- **Dispatch** — partially supported; works via SSE when the app is open\n  (requires `claude-cowork-service` daemon — see below)\n- **Auto-update pipeline** — GitHub Actions polls for new releases every 6 hours\n  and publishes automatically; AppImage supports delta updates via `AppImageUpdate`\n\n---\n\n## What Is NOT Supported\n\n| Feature | Reason |\n|---|---|\n| **Dispatch** | Partially supported — works via SSE when the app is open; GrowthBook feature flags are force-enabled and `claude-cowork-service` provides the socket backend; background delivery (APNs/FCM push) is not available so tasks won't arrive when the app is closed |\n| **Computer Use** | macOS implementation uses `AXUIElement`; an `xdotool`/`scrot` replacement would be fragile across desktop environments |\n| **ARM64** | Electron binary selection and AppImage build are x86_64 only; ARM64 is a future milestone |\n\n---\n\n## Installation\n\n### AppImage (any distro)\n\n```sh\n# Download from the latest release\nchmod +x claude-desktop-\u003cversion\u003e-x86_64.AppImage\n./claude-desktop-\u003cversion\u003e-x86_64.AppImage\n```\n\n\u003e `--no-sandbox` may be required on some systems: if the app fails to start,\n\u003e re-run with `--no-sandbox`. The AppImage FUSE mount sets `nosuid`, which can\n\u003e prevent the `chrome-sandbox` setuid bit from taking effect.\n\nTo update without re-downloading the full AppImage, use\n[AppImageUpdate](https://github.com/AppImageCommunity/AppImageUpdate):\n\n```sh\nAppImageUpdate claude-desktop-\u003cversion\u003e-x86_64.AppImage\n```\n\n### RPM (Fedora / Silverblue / RHEL)\n\nElectron is bundled — no additional dependencies required.\n\n#### Via DNF repository (recommended — enables `dnf update`)\n\n```sh\nsudo curl -o /etc/yum.repos.d/claude-desktop.repo \\\n  https://stslex.github.io/claude-desktop-linux/claude-desktop.repo\nsudo dnf install claude-desktop\n```\n\nFuture updates: `sudo dnf update claude-desktop`\n\n#### Direct RPM download\n\n```sh\nsudo dnf install claude-desktop-\u003cversion\u003e-repack-\u003cN\u003e-x86_64.rpm\n```\n\n#### Silverblue / Kinoite (atomic desktops)\n\n```sh\nsudo curl -o /etc/yum.repos.d/claude-desktop.repo \\\n  https://stslex.github.io/claude-desktop-linux/claude-desktop.repo\nrpm-ostree install claude-desktop\n# then reboot\n```\n\n### DEB (Debian / Ubuntu / Linux Mint)\n\nElectron is bundled — no additional dependencies required.\n\n#### Via APT repository (recommended — enables `apt update`)\n\n```sh\nsudo curl -o /etc/apt/sources.list.d/claude-desktop.list \\\n  https://stslex.github.io/claude-desktop-linux/claude-desktop.list\nsudo apt update\nsudo apt install claude-desktop\n```\n\nFuture updates: `sudo apt update \u0026\u0026 sudo apt upgrade claude-desktop`\n\n#### Direct DEB download\n\n```sh\nsudo apt install ./claude-desktop-\u003cversion\u003e-repack-\u003cN\u003e-x86_64.deb\n```\n\n### Pacman (Arch Linux / Manjaro / EndeavourOS)\n\nElectron is bundled — no additional dependencies required.\n\n#### Via custom repository (recommended — enables `pacman -Syu`)\n\nAdd to `/etc/pacman.conf`:\n\n```ini\n[claude-desktop]\nSigLevel = Optional TrustAll\nServer = https://github.com/stslex/claude-desktop-linux/releases/latest/download\n```\n\nThen install:\n\n```sh\nsudo pacman -Sy claude-desktop\n```\n\nFuture updates: `sudo pacman -Syu`\n\n#### Direct package download\n\nDownload the `.pkg.tar.zst` from the [latest release](https://github.com/stslex/claude-desktop-linux/releases/latest), then:\n\n```sh\ncurl -fLO https://github.com/stslex/claude-desktop-linux/releases/latest/download/claude-desktop-\u003cversion\u003e-\u003crepack\u003e-x86_64.pkg.tar.zst\nsudo pacman -U claude-desktop-*-x86_64.pkg.tar.zst\n```\n\n### NixOS / Nix\n\nThe repository ships a `flake.nix` with two channels that mirror the RPM /\nDEB / Pacman split:\n\n| Flake attribute | Channel | Source | Who should use it |\n|---|---|---|---|\n| `packages.x86_64-linux.default` | **stable** | Latest non-prerelease GitHub Release | Everyone by default |\n| `packages.x86_64-linux.dev`     | **dev**    | Latest prerelease (`prerelease: true`) GitHub Release | Early adopters who want fixes before they ship to main |\n\nChannel metadata (tarball URL + `sha256` + version) is pinned in\n`nix/stable.json` and `nix/dev.json`. CI updates those files on every\npublish, so `nix flake update` picks up new builds without you having to\npaste hashes by hand.\n\n\u003e Dev version strings carry a `-pre` suffix (e.g. `0.13.45-pre`) so that\n\u003e `builtins.compareVersions` places them strictly *below* the matching\n\u003e stable version. A `nix flake check` in this repo verifies the invariant\n\u003e (`checks.x86_64-linux.channel-version-order`). Practical consequence:\n\u003e if you have both overlays in scope, resolution always prefers the\n\u003e higher version, and stable always wins against a matching dev build.\n\n#### Flake input\n\n\u003e The input is named `claude-desktop-linux` here so the LHS attribute\n\u003e matches the repository name. You can pick any name you like, but\n\u003e whatever you use must match how downstream modules (NixOS, home-manager,\n\u003e overlays) reference it — see the [Troubleshooting](#troubleshooting)\n\u003e section below if `nix flake update` complains about a missing attribute.\n\n```nix\n# flake.nix\n{\n  inputs = {\n    nixpkgs.url     = \"github:NixOS/nixpkgs/nixos-unstable\";\n    claude-desktop-linux.url = \"github:stslex/claude-desktop-linux\";\n    # Or pin to the dev branch — required if you want\n    # `packages.x86_64-linux.dev` (the prerelease channel):\n    # claude-desktop-linux.url = \"github:stslex/claude-desktop-linux/dev\";\n  };\n  # ...\n}\n```\n\n\u003e **Heads-up about the `dev` attribute.** `packages.x86_64-linux.dev`\n\u003e and `claude-desktop-dev` currently live only on the `dev` branch of\n\u003e this repo — pinning the input to the default `main` branch\n\u003e (`github:stslex/claude-desktop-linux`) only exposes\n\u003e `packages.x86_64-linux.default` (stable). If you reference\n\u003e `inputs.claude-desktop-linux.packages.\u003csystem\u003e.dev` against the `main`\n\u003e URL you'll get an `attribute 'dev' missing` error. Switch the URL to\n\u003e the `/dev` form above, or use `.default` instead. This caveat goes\n\u003e away once the dev-channel changes land on `main`.\n\n#### NixOS — `environment.systemPackages`\n\nStable channel (recommended):\n\n```nix\n# configuration.nix\n{ inputs, pkgs, ... }: {\n  environment.systemPackages = [\n    inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.default\n  ];\n}\n```\n\nDev channel (opt-in — see warning below):\n\n```nix\n# configuration.nix\n{ inputs, pkgs, ... }: {\n  environment.systemPackages = [\n    inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.dev\n  ];\n}\n```\n\n#### Home Manager\n\n```nix\n# home.nix\n{ inputs, pkgs, ... }: {\n  home.packages = [\n    # Stable:\n    inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.default\n    # ...or dev (don't install both at once — they conflict on\n    # /bin/claude-desktop):\n    # inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.dev\n  ];\n}\n```\n\n#### Overlay usage\n\n```nix\n# flake.nix — expose both channels on pkgs\n{\n  outputs = { self, nixpkgs, claude-desktop-linux, ... }: {\n    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {\n      system = \"x86_64-linux\";\n      modules = [\n        ({ pkgs, ... }: {\n          nixpkgs.overlays = [(final: prev: {\n            claude-desktop     = claude-desktop-linux.packages.${prev.stdenv.hostPlatform.system}.default;\n            claude-desktop-dev = claude-desktop-linux.packages.${prev.stdenv.hostPlatform.system}.dev;\n          })];\n          environment.systemPackages = [ pkgs.claude-desktop ];\n        })\n      ];\n    };\n  };\n}\n```\n\n#### Rolling back from dev to stable\n\nSwitch the attribute you pull from the flake back to `default`, then\n`nixos-rebuild switch` (or `home-manager switch`):\n\n```diff\n- inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.dev\n+ inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.default\n```\n\n```sh\nsudo nixos-rebuild switch --flake .#myhost\n# or: home-manager switch --flake .#me\n```\n\nNixOS keeps the previous generation around — if the rebuild itself\nfails, roll the system back with `sudo nixos-rebuild switch --rollback`\n(or boot into the previous generation from the bootloader).\n\n\u003e **⚠️ Dev channel warning — same tone as the RPM dev repo.**\n\u003e The dev channel tracks the `dev` branch of this repository and\n\u003e publishes **prereleases**. It may break at any time, break your\n\u003e Claude Desktop session, or ship a partially-working patch while a\n\u003e Claude Desktop upstream change is being investigated. Only opt in if\n\u003e you are comfortable rolling back a NixOS generation. There is no\n\u003e support SLA — if it breaks, file an issue and switch back to stable.\n\n#### Direct tarball download\n\nPre-built Nix-compatible tarballs are available in each GitHub Release:\n\n```sh\n# Stable (latest non-prerelease):\ncurl -fLO https://github.com/stslex/claude-desktop-linux/releases/latest/download/claude-desktop-\u003cversion\u003e-repack-\u003cN\u003e-x86_64-nix.tar.gz\n```\n\n#### Manual override\n\nIf you want to build against a specific release without waiting for CI\nto update `nix/stable.json`, `overrideAttrs` works against either\nchannel:\n\n```nix\n(inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.default.overrideAttrs (_: {\n  version = \"\u003cversion\u003e\";\n  src = pkgs.fetchurl {\n    url = \"https://github.com/stslex/claude-desktop-linux/releases/download/v\u003cversion\u003e-repack-\u003cN\u003e/claude-desktop-\u003cversion\u003e-repack-\u003cN\u003e-x86_64-nix.tar.gz\";\n    sha256 = \"\u003csha256\u003e\";  # from release notes or nix-prefetch-url\n  };\n}))\n```\n\n#### Troubleshooting\n\nThe two errors below both come from a naming mismatch between the input\nURL, the input name in your `flake.nix`, and references in downstream\nmodules (NixOS, home-manager, overlays). The fix in every case is to\nmake all three agree on the same identifier.\n\n**Symptom 1 — HTTP 404 from the GitHub API**\n\n```\nerror: … while updating the flake input 'claude-desktop-linux'\n       … while fetching the input 'github:stslex/claude-desktop'\n       error: unable to download\n       'https://api.github.com/repos/stslex/claude-desktop/commits/HEAD':\n       HTTP error 404\n```\n\nThe input URL is missing the `-linux` suffix. The repository is\n`stslex/claude-desktop-linux`, not `stslex/claude-desktop` (the latter\ndoes not exist and returns 404 from the GitHub API). Two ways this\nsneaks in:\n\n1. **A typo in your `flake.nix`**. Open it and confirm the URL matches\n   the snippet in [Flake input](#flake-input) above:\n\n   ```nix\n   inputs.claude-desktop-linux.url = \"github:stslex/claude-desktop-linux\";\n   #                                                  ^^^^^^ required\n   ```\n\n2. **A stale entry in your `flake.lock`** from before the URL was\n   corrected. `nix flake update` only re-resolves an input when its URL\n   in `flake.nix` changes — if the lock file still pins the old name,\n   force a re-resolve of just the one input:\n\n   ```sh\n   nix flake lock --update-input claude-desktop-linux\n   ```\n\n   If the bad URL keeps resurfacing, delete the `claude-desktop-linux`\n   block from `flake.lock` by hand (or delete `flake.lock` entirely if\n   you're comfortable re-resolving every input) and rerun\n   `nix flake update`.\n\n**Symptom 2 — `attribute 'claude-desktop-linux' missing`**\n\n```\nerror: attribute 'claude-desktop-linux' missing\n   17|     inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.dev\n     |     ^\n```\n\nA downstream module (here, a home-manager `packages.nix`) references the\ninput as `claude-desktop-linux`, but your `flake.nix` declares it under\na *different* name — most commonly `inputs.claude-desktop` (without the\n`-linux` suffix). The input *name* (the LHS attribute in `flake.nix`)\nand the input *URL* are independent in Nix flakes; references in other\nmodules must match the *name*, not the URL.\n\nPick one of these two fixes — both work, the first is recommended\nbecause it matches the convention in the snippets above and most users'\nexpectation that the input name should match the repository name:\n\n1. **Rename the LHS in your `flake.nix`** so the input name matches\n   what downstream modules reference:\n\n   ```nix\n   inputs.claude-desktop-linux.url = \"github:stslex/claude-desktop-linux\";\n   ```\n\n2. **Or rename the reference in the downstream module** to match\n   whatever name your `flake.nix` already uses:\n\n   ```nix\n   # if flake.nix has `inputs.claude-desktop.url = ...`\n   inputs.claude-desktop.packages.${pkgs.stdenv.hostPlatform.system}.dev\n   ```\n\nAfter fixing the name in `flake.nix`, refresh the lock and rebuild:\n\n```sh\nrm flake.lock         # easiest — drops any stale block from the old name\nnix flake lock\nsudo nixos-rebuild switch --flake .#myhost\n```\n\n**Symptom 3 — `attribute 'dev' missing`**\n\n```\nerror: attribute 'dev' missing\n   17|     inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.dev\n     |     ^\n```\n\nThe input now resolves correctly, but you're pinning the **`main`**\nbranch of this repo and asking for the `.dev` package. As called out in\nthe heads-up box on [Flake input](#flake-input) above,\n`packages.x86_64-linux.dev` and `claude-desktop-dev` currently live only\non the `dev` branch — `main` only exposes\n`packages.x86_64-linux.default`. Two ways out:\n\n1. **Switch the input URL to the `dev` branch** if you actually want\n   the prerelease channel:\n\n   ```nix\n   inputs.claude-desktop-linux.url = \"github:stslex/claude-desktop-linux/dev\";\n   ```\n\n2. **Or change the downstream reference from `.dev` to `.default`** if\n   you just want stable on the `main` URL:\n\n   ```nix\n   inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.default\n   ```\n\nThis caveat disappears once the dev-channel changes land on `main`.\n\nAfter any of the three fixes, refresh the lock and rebuild:\n\n```sh\nnix flake lock --update-input claude-desktop-linux\nsudo nixos-rebuild switch --flake .#myhost\n```\n\n`nixos-rebuild switch` should then resolve the input against this\nrepository and pick up `nix/stable.json` (or `nix/dev.json` if you\npinned the `dev` branch) without further intervention.\n\n### Cowork Service (optional — enables Cowork and Dispatch)\n\nThe `claude-cowork-service` daemon provides the socket backend that Cowork and\nDispatch use for session management.  Install it for full Cowork/Dispatch support:\n\n```sh\n./scripts/install-cowork-service.sh\n```\n\nThis downloads the pre-built binary from\n[patrickjaja/claude-cowork-service](https://github.com/patrickjaja/claude-cowork-service),\ninstalls it to `~/.local/bin/`, and creates a systemd user service.  The app\nwill warn on launch if the service is not running, but Chat and MCP still work\nwithout it.\n\n---\n\n### Beta / Development Channel (Testers Only)\n\n\u003e **Not recommended for normal use.** The beta channel contains untested\n\u003e development builds. They may be broken, crash on launch, or have incomplete\n\u003e features. Use the [stable release](#installation) unless you are actively\n\u003e testing changes.\n\nIf you want to help test new features before they reach the stable channel:\n\n#### RPM / Fedora / Silverblue\n\n```sh\nsudo curl -o /etc/yum.repos.d/claude-desktop-dev.repo \\\n  https://stslex.github.io/claude-desktop-linux/claude-desktop-dev.repo\nsudo dnf install claude-desktop\n```\n\n#### DEB / Debian / Ubuntu\n\n```sh\nsudo curl -o /etc/apt/sources.list.d/claude-desktop-dev.list \\\n  https://stslex.github.io/claude-desktop-linux/claude-desktop-dev.list\nsudo apt update\nsudo apt install claude-desktop\n```\n\n#### Pacman / Arch Linux\n\nAdd to `/etc/pacman.conf`:\n\n```ini\n[claude-desktop-dev]\nSigLevel = Optional TrustAll\nServer = https://github.com/stslex/claude-desktop-linux/releases/download/\u003cdev-tag\u003e\n```\n\n#### Nix / NixOS\n\nSwitch the flake attribute you pull from `default` to `dev`:\n\n```nix\n# configuration.nix / home.nix\nenvironment.systemPackages = [\n  inputs.claude-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.dev\n];\n```\n\nOr consume the `dev` branch of this repository directly as a flake\ninput to always track the latest dev-channel metadata:\n\n```nix\ninputs.claude-desktop-linux.url = \"github:stslex/claude-desktop-linux/dev\";\n```\n\nSee the \"NixOS / Nix\" section above for `builtins.compareVersions`\ninvariants and the `checks.x86_64-linux.channel-version-order` flake\ncheck that guards them.\n\n#### Rollback to stable\n\nIf a beta build breaks your install:\n\n```sh\n# Fedora\nsudo dnf downgrade claude-desktop\n# or remove the dev repo and reinstall:\nsudo rm /etc/yum.repos.d/claude-desktop-dev.repo\nsudo dnf reinstall claude-desktop\n\n# Debian / Ubuntu\nsudo rm /etc/apt/sources.list.d/claude-desktop-dev.list\nsudo apt update\nsudo apt install claude-desktop --reinstall\n\n# NixOS — switch the flake attribute back to .default and rebuild:\n#   sudo nixos-rebuild switch --flake .#myhost\n# or roll the previous generation back if the rebuild itself broke:\n#   sudo nixos-rebuild switch --rollback\n```\n\n#### Reporting beta issues\n\nBeta issues should be filed with the `beta` label on GitHub Issues.\nInclude the exact version string from `rpm -q claude-desktop` or\n`claude-desktop --version`.\n\n---\n\n### First Run\n\n1. No special setup needed — the app creates `~/.local/share/claude-linux/sessions/`\n   automatically. No sudo or root symlinks required.\n2. Complete the OAuth flow in your browser — the `claude://` URI scheme is\n   registered by the `.desktop` file and `xdg-mime`.\n\n---\n\n## Building from Source\n\n### Prerequisites\n\n```sh\n# Fedora\nsudo dnf install rpm-build ImageMagick nodejs unzip curl\nnode --version  # must be ≥ 20\n```\n\nAlso required at build time (fetched automatically if missing):\n`appimagetool`, `@electron/asar` (via npx), Electron binary (downloaded by the build scripts).\n\n### Build\n\n```sh\ngit clone https://github.com/stslex/claude-desktop-linux\ncd claude-desktop-linux\nnpm ci --ignore-scripts\n\n./scripts/fetch-and-extract.sh  # download release ZIP, extract app.asar, detect versions\n./scripts/inject-stubs.sh       # replace native modules with JS stubs\n./scripts/patch-cowork.sh       # unlock Cowork on Linux\n./scripts/build-packages.sh     # produce RPM + DEB + Pacman + Nix + AppImage in ./output/\n```\n\nOr trigger the **build.yml** GitHub Action manually — it runs the same\nsteps on `ubuntu-latest` and publishes a GitHub Release with both packages\nand their `.sha256` files.\n\n**Useful env vars:**\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `SKIP_DOWNLOAD` | *(unset)* | Set to `1` to reuse the existing downloaded archive |\n| `COWORK_BACKEND` | `bubblewrap` | `bubblewrap` or `host` |\n| `ELECTRON_OVERRIDE` | *(unset)* | Force a specific Electron version |\n\n---\n\n## How Cowork Works on Linux\n\nOn macOS, Cowork runs `claude-code` inside an Apple Virtualization Framework\nVM. Our approach collapses the VM layer entirely:\n\n```\nmacOS:  Electron → @ant/claude-swift (native) → VZVirtualMachine → Linux VM → claude-code\nLinux:  Electron → @ant/claude-swift (JS stub) → child_process.spawn()      → claude-code\n```\n\nTwo JS stubs do the work:\n\n- **`@ant/claude-native`** — spoofs `getPlatform()` → `\"darwin\"` and\n  `getOSVersion()` → `\"14.0.0\"` to pass the Cowork availability check.\n  `AuthRequest` calls `xdg-open` for the OAuth deep-link.\n- **`@ant/claude-swift`** — implements the `vm.spawn()` / `vm.kill()` /\n  `vm.writeStdin()` interface via `child_process.spawn`. VM filesystem paths\n  (`/sessions/\u003cid\u003e/mnt/\u003cname\u003e/…`) are translated to real host paths\n  (`~/.local/share/claude-linux/sessions/…`).\n\nThe platform gate in `app.asar` (a minified function that checks\n`process.platform`) is patched at build time using an AST rewrite (acorn)\nto unconditionally return `{ status: \"supported\" }`.\n\nWith `COWORK_BACKEND=bubblewrap` (default), `claude-code` runs inside a\nbubblewrap namespace sandbox: home directory read-only, only the session\nworking directory writable, network access preserved.\n\n---\n\n## Security\n\nThis project downloads a proprietary application from Anthropic's CDN and\nmodifies it locally. Key points from [ARCHITECTURE.MD](ARCHITECTURE.MD):\n\n- The downloaded archive SHA256 is verified on every run (transport integrity\n  via HTTPS; no trusted out-of-band checksum source).\n- The injected stubs are ~100 lines of plain JS each — auditable in minutes.\n  They make no outbound network requests and do not read your files.\n- The Cowork patch is a single function-body replacement. The diff ships in\n  each release.\n- RPM packages are not GPG-signed in the initial release (planned follow-up).\n- AppImage has no signature (standard AppImage limitation).\n- `claude-code` runs as your user. With `bubblewrap` it cannot write outside\n  the session directory. With `COWORK_BACKEND=host` it has full filesystem\n  access.\n\n**Threat model:** we trust Anthropic's CDN. If you do not, do not use this\nproject.\n\n---\n\n## Contributing\n\n[CLAUDE.MD](CLAUDE.MD) is the authoritative spec: invariants, script\ncontracts, stub interfaces, patch strategy, and update procedure.\n\nWhen `patch-cowork.sh` breaks after a Claude Desktop update, run:\n\n```sh\nnode patches/find-platform-gate.mjs --dump-candidates\n```\n\nUpdate the AST pattern, commit, and push — the next `check-update.yml` run\npicks it up automatically.\n\n---\n\n## License / Disclaimer\n\nBuild scripts: **MIT**.\n\nClaude Desktop application: **Anthropic proprietary**. This project downloads\nit directly from Anthropic's CDN at build time and does not redistribute it.\n\nThis project is **unofficial** and is not affiliated with, endorsed by, or\nsupported by Anthropic.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstslex%2Fclaude-desktop-linux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstslex%2Fclaude-desktop-linux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstslex%2Fclaude-desktop-linux/lists"}