How to Build Claude Desktop on Linux Using a Local Windows Installer

You can build Claude Desktop for Debian, RPM, or AppImage distributions from a local Windows installer by running ./build.sh --exe /path/to/Claude-Setup.exe, which extracts the Electron app, applies Linux-specific patches, and packages it for your native package manager.

The aaddrick/claude-desktop-debian repository provides a complete build pipeline that converts the official Windows-only Claude Desktop installer into native Linux packages. This guide explains how to build Claude Desktop using a local Windows installer instead of relying on automatic downloads, giving you full control over the source version and enabling offline builds.

Build Pipeline Overview

The build process orchestrated by build.sh operates in three distinct stages:

  1. Extraction: The Windows installer (Claude-Setup-*.exe) is unpacked using 7z to extract the embedded NuGet package (AnthropicClaude-*.nupkg), which contains the original app.asar and resources.
  2. Patching: Windows-only native modules are replaced with Linux equivalents, and runtime patches are applied to the minified JavaScript inside app.asar to enable Linux-compatible Cowork mode, menu-bar visibility control, and various Wayland/KDE bug fixes.
  3. Packaging: The patched resources are re-assembled into an Electron distribution and packaged as .deb, .rpm, AppImage, or a Nix flake based on your distribution family.

Building from a Local Windows Installer

When you have a local copy of the Windows installer—perhaps for a specific version or offline use—pass the file path to the build script using the --exe flag.


# Clone the repository

git clone https://github.com/aaddrick/claude-desktop-debian.git
cd claude-desktop-debian

# Build using a local Windows installer

./build.sh --exe /path/to/Claude-Setup-x64.exe

The download_claude_installer() function in build.sh detects the --exe argument and skips the automatic download logic. Instead, it copies the supplied installer into the temporary work directory and proceeds directly to the extraction phase. This approach is particularly useful when the automated URL resolver in scripts/resolve-download-url.py is out of date or when building in air-gapped environments.

Extraction and Patching Process

After the local installer is staged, the script performs deep extraction and transformation:

Extracting the Electron App

The build script uses 7z to unpack the installer executable, locating the AnthropicClaude-*.nupkg file nested inside. This NuGet package is then extracted to reveal the original app.asar and resource files. The setup_electron_asar() function in build.sh manages this extraction and prepares the directory structure for patching.

Applying Linux Compatibility Patches

The build.sh script applies a series of targeted patches to enable full Linux functionality:

  • patch_cowork_linux(): Modifies the platform gate to accept process.platform === "linux", implements Unix-domain socket communication at $XDG_RUNTIME_DIR/cowork-vm-service.sock, and forces the download status to NotDownloaded to prevent auto-navigation to the Cowork tab.
  • patch_titlebar_detection(): Fixes window frame detection for Linux desktop environments.
  • patch_tray_menu_handler(): Corrects system tray behavior on KDE and GNOME.

These patches modify the minified JavaScript within app.asar to replace Windows-specific APIs with Linux-compatible implementations.

Key Linux Compatibility Features

The build introduces several runtime components that provide native Linux integration:

Frame-Fix Wrapper

The scripts/frame-fix-wrapper.js is injected into the Electron runtime to intercept require('electron'). It replaces BrowserWindow with a subclass that:

  • Forces native window frames for the main window while hiding frames for popup windows (Quick-Entry, About).
  • Implements menu-bar visibility control via the CLAUDE_MENU_BAR environment variable (auto, visible, hidden).
  • Injects CSS for thin, theme-aware scrollbars.
  • Applies debounce-jiggle fixes to work around stale compositor caches on KWin, Hyprland, and i3.

Because the wrapper loads before the original app code, all downstream windows inherit the corrected behavior without modifying the upstream source.

Cowork Mode Support

The scripts/cowork-vm-service.js implements a minimal Node.js VM service daemon that enables the Cowork remote-desktop feature on Linux. The daemon listens on a Unix-domain socket at $XDG_RUNTIME_DIR/cowork-vm-service.sock and communicates with the patched client code to provide seamless remote desktop integration previously limited to Windows and macOS.

Verification and Launch Options

After installation, verify the build using the built-in diagnostic tool:

claude-desktop --doctor

This command validates the sandbox backend, required libraries, and Cowork-mode readiness. Typical output includes architecture detection, distribution identification, and backend confirmation (bubblewrap).

Control the menu-bar visibility using environment variables:


# Hide the menu bar permanently

CLAUDE_MENU_BAR=hidden claude-desktop

# Force visible menu bar

CLAUDE_MENU_BAR=visible claude-desktop

# Auto-hide with Alt toggle (default)

CLAUDE_MENU_BAR=auto claude-desktop

The frame-fix wrapper logs the resolved mode to the console for debugging purposes.

Summary

  • Local Installer Builds: Use ./build.sh --exe /path/to/Claude-Setup.exe to build Claude Desktop from a local Windows installer, bypassing automatic downloads.
  • Deep Extraction: The build pipeline extracts the AnthropicClaude-*.nupkg from the installer using 7z and processes the embedded app.asar.
  • Linux Patches: Key functions in build.sh—including patch_cowork_linux(), patch_titlebar_detection(), and patch_tray_menu_handler()—enable full Linux compatibility.
  • Runtime Wrappers: scripts/frame-fix-wrapper.js provides native window framing and menu control, while scripts/cowork-vm-service.js enables remote desktop support via Unix sockets.
  • Package Formats: The build automatically detects your distribution and generates .deb, .rpm, or AppImage packages, or you can specify a format with --build <format>.

Frequently Asked Questions

Can I build Claude Desktop without an internet connection?

Yes, provided you have a local copy of the Windows installer. Use the --exe flag to point to a previously downloaded Claude-Setup-*.exe file. The download_claude_installer() function in build.sh will skip the network fetch and proceed with extraction and patching. You will still need the build dependencies (7z, wget, icoutils, imagemagick, and either dpkg-deb or rpmbuild) installed locally.

What file formats does the build script support for local installers?

The build script accepts the official Windows installer executable, typically named Claude-Setup-x64.exe or Claude-Setup-arm64.exe. The script uses 7z to extract the embedded AnthropicClaude-*.nupkg package from this executable, regardless of whether it was downloaded automatically or supplied via the --exe flag. Ensure the file matches the architecture you intend to build for (amd64 or arm64).

How do I enable the Cowork remote desktop feature on the Linux build?

The Linux build includes experimental Cowork support through the patch_cowork_linux() function in build.sh and the scripts/cowork-vm-service.js daemon. The patches modify the platform detection to accept Linux and implement Unix-domain socket communication at $XDG_RUNTIME_DIR/cowork-vm-service.sock. To use it, ensure the cowork-vm-service.js daemon is running (it starts automatically on first connection), then use the Cowork option within Claude's interface as you would on Windows or macOS.

Where are the runtime patches for window framing and menu bars implemented?

The window framing, menu bar visibility, and scrollbar styling are handled by scripts/frame-fix-wrapper.js, which the build injects into the Electron runtime. This wrapper intercepts require('electron') and replaces BrowserWindow with a subclass that forces native frames and respects the CLAUDE_MENU_BAR environment variable (auto, visible, or hidden). The build script applies the initial platform patches via functions like patch_titlebar_detection() in build.sh, but the runtime behavior is governed by the wrapper script loaded at application startup.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →