Claude Desktop for Debian-based Linux distributions
  • Shell 75.2%
  • JavaScript 21.7%
  • Nix 1.9%
  • Python 1.2%
Find a file
Aaddrick 5c8191e82f
feat(linux): hybrid titlebar mode for clickable in-app topbar (#538)
* feat(linux): hybrid titlebar mode for clickable in-app topbar

Default `CLAUDE_TITLEBAR_STYLE` is now `hybrid`: native OS frame
plus a BrowserView preload shim that convinces claude.ai's bundle
to render its in-app topbar (hamburger / sidebar / search / nav /
Cowork ghost). Stacked layout instead of Windows's combined bar,
but every button is clickable.

Why not the upstream `frame:false` + WCO config: investigation
(see docs/learnings/linux-topbar-shim.md) ruled out
`titleBarOverlay`, `titleBarStyle:'hidden'`, and the `.draggable`
CSS class as the source of the topbar click-eating drag region.
The remaining cause is a Chromium-level implicit drag region for
`frame:false` windows that exists on both X11 and Wayland and has
no Electron-API knob. With `frame:true` the OS handles dragging
and Chromium pushes no drag-region map, so the buttons receive
mouse events normally.

Modes:
- `hybrid` (default) — system frame + shim, topbar visible and
  clickable
- `native` — system frame, no shim, no in-app topbar
- `hidden` — frameless + WCO config, matches Windows/macOS
  upstream; topbar visible but not clickable on Linux. Kept for
  Wayland comparison and future investigation

Tests: tests/launcher-common.bats grew 16 cases covering
`_resolve_titlebar_style`, `build_electron_args` flag selection
per mode, and `setup_electron_env` env-var wiring per mode.
`claude-desktop --doctor` now reports the resolved mode and
warns when `hidden` is set.

Co-Authored-By: Claude <claude@anthropic.com>

* docs(learnings): add hybrid-mode screenshot

Visual reference of the stacked layout: DE-drawn titlebar on top
with native window controls, claude.ai's in-app topbar
(hamburger / search / back-forward) immediately below it.

Co-Authored-By: Claude <claude@anthropic.com>

* docs(learnings): fix codespell hit (Pre-emptive → Preemptive)

Codespell flags hyphenated "Pre-emptive" as a misspelling of
"Preemptive". Drops the hyphen to clear the spellcheck CI gate
on PR #538.

Co-Authored-By: Claude <claude@anthropic.com>

---------

Co-authored-by: Claude <claude@anthropic.com>
2026-05-01 02:47:16 -04:00
.claude feat(linux): hybrid titlebar mode for clickable in-app topbar (#538) 2026-05-01 02:47:16 -04:00
.github ci: pin third-party actions to commit SHAs (#535) 2026-04-28 07:25:28 -04:00
docs feat(linux): hybrid titlebar mode for clickable in-app topbar (#538) 2026-05-01 02:47:16 -04:00
nix Update Claude Desktop download URLs to version 1.5354.0 2026-04-30 01:40:21 +00:00
scripts feat(linux): hybrid titlebar mode for clickable in-app topbar (#538) 2026-05-01 02:47:16 -04:00
tests feat(linux): hybrid titlebar mode for clickable in-app topbar (#538) 2026-05-01 02:47:16 -04:00
worker docs: remove worker-apt-plan.md now that Phase 4a has shipped (#511) 2026-04-23 16:25:56 -04:00
.codespellrc Add rudimentary codespell config 2025-04-03 10:41:13 -04:00
.gitignore chore(gitignore): ignore worker/.wrangler/ cache (#523) 2026-04-25 08:41:53 -04:00
AGENTS.md docs: add AGENTS.md redirecting to CLAUDE.md 2026-02-26 03:39:13 -05:00
build.sh feat(linux): hybrid titlebar mode for clickable in-app topbar (#538) 2026-05-01 02:47:16 -04:00
CLAUDE.md feat(linux): hybrid titlebar mode for clickable in-app topbar (#538) 2026-05-01 02:47:16 -04:00
flake.lock chore: update flake.lock 2026-04-27 03:18:43 +00:00
flake.nix fix: move claude-desktop-fhs to let block so default can reference it 2026-03-30 18:59:00 -07:00
LICENSE-APACHE Initial commit: Claude Desktop for Debian-based Linux distributions 2024-12-26 11:08:01 -05:00
LICENSE-MIT Initial commit: Claude Desktop for Debian-based Linux distributions 2024-12-26 11:08:01 -05:00
README.md docs(readme): credit cbonnissent for bwrap {src, dst} mount form (#543) 2026-05-01 00:50:02 -04:00
STYLEGUIDE.md feat: add Claude Code hooks and /simplify skill for code quality 2026-01-25 03:02:38 -05:00

Claude Desktop for Linux

This project provides build scripts to run Claude Desktop natively on Linux systems. It repackages the official Windows application for Linux distributions, producing .deb packages (Debian/Ubuntu), .rpm packages (Fedora/RHEL), distribution-agnostic AppImages, an AUR package for Arch Linux, and a Nix flake for NixOS.

Note: This is an unofficial build script. For official support, please visit Anthropic's website. For issues with the build script or Linux implementation, please open an issue in this repository.


⚠️ APT migration notice (April 2026)

The APT/DNF repo moved to pkg.claude-desktop-debian.dev (#493) — binaries are now served from GitHub Releases via a Cloudflare Worker so they don't hit the 100 MB per-file push cap on gh-pages. DNF users are unaffected. APT users on the legacy aaddrick.github.io sources.list will see a scheme-downgrade error on apt update. One-line sed fix.


Features

  • Native Linux Support: Run Claude Desktop without virtualization or Wine
  • MCP Support: Full Model Context Protocol integration Configuration file location: ~/.config/Claude/claude_desktop_config.json
  • System Integration:
    • Global hotkey support (Ctrl+Alt+Space) - works on X11 and Wayland (via XWayland)
    • System tray integration
    • Desktop environment integration

Screenshots

Claude Desktop running on Linux

Global hotkey popup

Installation

Add the repository for automatic updates via apt:

# Add the GPG key
curl -fsSL https://pkg.claude-desktop-debian.dev/KEY.gpg | sudo gpg --dearmor -o /usr/share/keyrings/claude-desktop.gpg

# Add the repository
echo "deb [signed-by=/usr/share/keyrings/claude-desktop.gpg arch=amd64,arm64] https://pkg.claude-desktop-debian.dev stable main" | sudo tee /etc/apt/sources.list.d/claude-desktop.list

# Update and install
sudo apt update
sudo apt install claude-desktop

Future updates will be installed automatically with your regular system updates (sudo apt upgrade).

Add the repository for automatic updates via dnf:

# Add the repository
sudo curl -fsSL https://pkg.claude-desktop-debian.dev/rpm/claude-desktop.repo -o /etc/yum.repos.d/claude-desktop.repo

# Install
sudo dnf install claude-desktop

Future updates will be installed automatically with your regular system updates (sudo dnf upgrade).

Migrating from the old aaddrick.github.io URL

If you installed claude-desktop before April 2026, your repo config points at https://aaddrick.github.io/claude-desktop-debian. That URL now auto-redirects to pkg.claude-desktop-debian.dev — DNF follows the redirect transparently, but apt refuses it as a security downgrade, so apt update fails. Update your sources list to the new URL:

# APT (Debian/Ubuntu)
sudo sed -i 's|https://aaddrick\.github\.io/claude-desktop-debian|https://pkg.claude-desktop-debian.dev|g' \
  /etc/apt/sources.list.d/claude-desktop.list
sudo apt update

# DNF (Fedora/RHEL) — optional refresh; the old URL still works but pointing directly at the new host is cleaner
sudo curl -fsSL https://pkg.claude-desktop-debian.dev/rpm/claude-desktop.repo \
  -o /etc/yum.repos.d/claude-desktop.repo

Background: binaries for recent releases are no longer committed to the gh-pages branch — .deb files grew past GitHub's 100 MB per-file cap (#493). The new URL is fronted by a small Cloudflare Worker that serves the existing metadata directly and 302-redirects package downloads to the corresponding GitHub Release asset. Bandwidth and package bytes still come from GitHub; the Worker just handles the routing.

Using AUR (Arch Linux)

The claude-desktop-appimage package is available on the AUR and is automatically updated with each release.

# Using yay
yay -S claude-desktop-appimage

# Or using paru
paru -S claude-desktop-appimage

The AUR package installs the AppImage build of Claude Desktop.

Using Nix Flake (NixOS)

Install directly from the flake:

# Basic install
nix profile install github:aaddrick/claude-desktop-debian

# With MCP server support (FHS environment)
nix profile install github:aaddrick/claude-desktop-debian#claude-desktop-fhs

Or add to your NixOS configuration:

# flake.nix
{
  inputs.claude-desktop.url = "github:aaddrick/claude-desktop-debian";

  outputs = { nixpkgs, claude-desktop, ... }: {
    nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
      modules = [
        ({ pkgs, ... }: {
          nixpkgs.overlays = [ claude-desktop.overlays.default ];
          environment.systemPackages = [ pkgs.claude-desktop ];
        })
      ];
    };
  };
}

Using Pre-built Releases

Download the latest .deb, .rpm, or .AppImage from the Releases page.

Building from Source

See docs/BUILDING.md for detailed build instructions.

Configuration

Model Context Protocol settings are stored in:

~/.config/Claude/claude_desktop_config.json

For additional configuration options including environment variables and Wayland support, see docs/CONFIGURATION.md.

Troubleshooting

Run claude-desktop --doctor for built-in diagnostics that check common issues (display server, sandbox permissions, MCP config, stale locks, and more). It also reports cowork mode readiness — which isolation backend will be used, and which dependencies (KVM, QEMU, vsock, socat, virtiofsd, bubblewrap) are installed or missing.

For additional troubleshooting, uninstallation instructions, and log locations, see docs/TROUBLESHOOTING.md.

Acknowledgments

This project was inspired by k3d3's claude-desktop-linux-flake and their Reddit post about running Claude Desktop natively on Linux.

Special thanks to:

  • k3d3
    • Original NixOS implementation
    • Native bindings insights
  • emsi
    • Title bar fix
    • Alternative implementation approach
  • leobuskin for the Playwright-based URL resolution approach
  • yarikoptic
    • Codespell support
    • Shellcheck compliance
  • IamGianluca for build dependency check improvements
  • ing03201 for IBus/Fcitx5 input method support
  • ajescudero for pinning @electron/asar for Node compatibility
  • delorenj for Wayland compatibility support
  • Regen-forest for suggesting Gear Lever as AppImageLauncher replacement
  • niekvugteveen for fixing Debian packaging permissions
  • speleoalex for native window decorations support
  • imaginalnika for moving logs to ~/.cache/
  • richardspicer for the menu bar visibility fix on Linux
  • jacobfrantz1
    • Claude Desktop code preview support
    • Quick window submit fix
  • janfrederik for the --exe flag to use a local installer
  • MrEdwards007 for discovering the OAuth token cache fix
  • lizthegrey
    • Version update contributions
    • Close-to-tray on Linux to keep in-app schedulers, MCP servers, and the tray icon alive across window close
    • "Run on startup" persistence on Linux via XDG Autostart, fixing the toggle that would silently revert
  • mathys-lopinto
    • AUR package
    • Automated deployment
  • pkuijpers for root cause analysis of the RPM repo GPG signing issue
  • dlepold for identifying the tray icon variable name bug with a working fix
  • Voork1144
    • Detailed analysis of the tray icon minifier bug
    • Root-cause analysis of the Chromium layout cache bug
    • Direct child setBounds() fix approach
  • sabiut
    • --doctor diagnostic command
    • SHA-256 checksum validation for downloads
    • Post-build integration tests for deb, rpm, and AppImage artifacts
  • milog1994
    • Popup detection
    • Functional stubs
    • Wayland compositor support
  • jarrodcolburn
    • Passwordless sudo support in container/CI environments
    • Identifying the gh-pages 4GB bloat fix
    • Identifying the virtiofsd PATH detection issue on Debian
    • Detailed analysis of the CI release pipeline failure caused by runner kills during compare-releases
    • Diagnosing the session-start hook sudo blocking issue with three solution approaches
  • chukfinley for experimental Cowork mode support on Linux
  • CyPack
    • Orphaned cowork daemon cleanup on startup
    • COWORK_VM_BACKEND documentation, Cowork troubleshooting sections, and unknown-value warning in --doctor
  • IliyaBrook
    • Fixing the platform patch for Claude Desktop >= 1.1.3541 arm64 refactor
    • Fixing the duplicate tray icon on OS theme change with an in-place setImage/setContextMenu fast-path that avoids the KDE Plasma SNI re-registration race
  • MichaelMKenny
    • Diagnosing the $-prefixed electron variable bug
    • Root cause analysis and workaround
  • daa25209 for detailed root cause analysis of the cowork platform gate crash and patch script
  • noctuum
    • CLAUDE_MENU_BAR env var with configurable menu bar visibility
    • Boolean alias support
  • typedrat
    • NixOS flake integration with build.sh
    • node-pty derivation
    • CI auto-update
    • Fixing the flake package scoping regression
  • cbonnissent
    • Reverse-engineering the Cowork VM guest RPC protocol
    • Fixing the KVM startup blocker
    • Fixing RPC response id echoing for persistent connections
    • Configurable bwrap mount points via a dedicated Linux config file
    • {src, dst} mount form in coworkBwrapMounts for distinct host/sandbox paths (e.g. persistent /tmp across Bash tool calls)
  • joekale-pp for adding --doctor support to the RPM launcher
  • ecrevisseMiroir for the bwrap backend sandbox isolation with tmpfs-based minimal root
  • arauhala for detailed root cause analysis of the NixOS isPackaged regression
  • cromagnone for confirming the VM download loop on bwrap installs with detailed logs that disproved the initial triage
  • aHk-coder for diagnosing the hardcoded minified variable crash in the cowork smol-bin patch
  • RayCharlizard
    • Detailed analysis of the self-referential .mcpb-cache symlink ELOOP bug
    • Fixing auto-memory path translation on HostBackend
    • Fixing the ion-dist static asset copy for the app:// protocol handler
  • reinthal for fixing the NixOS build breakage caused by the nixpkgs nodePackages removal
  • gianluca-peri
    • Reporting the GNOME quit accessibility issue
    • Confirming tray behavior with AppIndicator
  • martin152 for detailed diagnosis and a complete patch for three launcher cleanup bugs: cleanup_orphaned_cowork_daemon self-match, cleanup_stale_cowork_socket socat dependency no-op, and the same self-match in --doctor
  • hfyeh for diagnosing the Ubuntu 24.04 AppArmor unprivileged-userns block on Cowork bwrap and contributing the AppArmor profile workaround
  • davidamacey for identifying and fixing the XRDP GPU compositing blank-window issue on remote desktop sessions
  • pb3ck for diagnosing the Cowork CLAUDE_CODE_OAUTH_TOKEN env-strip bug with a working reference diff
  • aJV99 for exporting GDK_BACKEND=wayland in native Wayland mode to fix XWayland fallback blur on HiDPI displays
  • Andrej730
    • Quick-window regex readability refactor (String.raw + escapeRegExp helper)
    • Fixing the visibility-function regex break on Claude Desktop 1.3883.0 (#495)

Sponsorship

If this project is useful to you, consider sponsoring on GitHub.

License

The build scripts in this repository are dual-licensed under:

The Claude Desktop application itself is subject to Anthropic's Consumer Terms.

Privacy

This repository uses an automated triage bot that sends issue contents to Anthropic's API for classification and investigation when you file a bug report or feature request. The bot reads the issue body, title, and any referenced related issues; it does not follow URLs, execute code blocks, or read content outside the triggering issue.

Do not include credentials, tokens, personal data, or anything you wouldn't put on a public issue tracker. If you post sensitive content and then edit it out, the bot's original read is preserved as a run artifact for audit — GitHub's UI hides the edit, but the bot's view of what you wrote is recoverable by maintainers.

Full design and data inventory: docs/issue-triage/README.md.

Contributing

Contributions are welcome! By submitting a contribution, you agree to license it under the same dual-license terms as this project.