Files
nixos-config/pkgs/claude-desktop/package.nix
T
Miguel Palhas 938a900fbe feat(home): package Claude Desktop and T3 Code, with per-host UI scaling
Add two Electron AI desktop apps built from their official upstream
binaries and wire them into the home config (x86_64 only):

- claude-desktop: Anthropic's official Linux .deb, unpacked via dpkg +
  autoPatchelfHook. Wrapper disables the SUID sandbox (nix store can't
  set it up) and adds the NixOS GL driver path so it hardware-accelerates
  instead of falling back to software rendering.
- t3-code: pingdotgg/t3code AppImage via appimageTools.wrapType2, with
  desktop entry + hicolor icons.

Both share a new custom.aiApps.deviceScaleFactor option feeding
--force-device-scale-factor; konishi's 4K@1x monitors set it to "1.5",
arrakis stays native.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 14:06:55 +01:00

162 lines
3.6 KiB
Nix

{
lib,
stdenv,
fetchurl,
autoPatchelfHook,
dpkg,
makeWrapper,
wrapGAppsHook3,
# runtime / autopatchelf libs
alsa-lib,
at-spi2-atk,
at-spi2-core,
atk,
cairo,
cups,
dbus,
expat,
gdk-pixbuf,
glib,
gtk3,
libcap_ng,
libGL,
libdrm,
libnotify,
libseccomp,
libsecret,
libuuid,
libxkbcommon,
mesa,
nspr,
nss,
pango,
systemd,
xdg-utils,
libX11,
libxcb,
libxcomposite,
libxcursor,
libxdamage,
libxext,
libxfixes,
libxi,
libxkbfile,
libxrandr,
libxscrnsaver,
libxshmfence,
libxtst,
# UI scaling: null = native, or a string like "1.5" for --force-device-scale-factor.
deviceScaleFactor ? null,
}:
stdenv.mkDerivation (finalAttrs: {
pname = "claude-desktop";
version = "1.21459.3";
# Official Anthropic Linux build, pulled straight from their apt pool.
# To bump: find the newest entry in
# https://downloads.claude.ai/claude-desktop/apt/stable/dists/stable/main/binary-amd64/Packages
# then update version + hash (nix hash convert --to sri the listed SHA256).
src = fetchurl {
url = "https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_${finalAttrs.version}_amd64.deb";
hash = "sha256-My0k7439p83WM+9iTvM1zrMatUtHHijXhavGAWrmqb4=";
};
nativeBuildInputs = [
autoPatchelfHook
dpkg
makeWrapper
wrapGAppsHook3
];
buildInputs = [
alsa-lib
at-spi2-atk
at-spi2-core
atk
cairo
cups
dbus
expat
gdk-pixbuf
glib
gtk3
libcap_ng
libGL
libdrm
libnotify
libseccomp
libsecret
libuuid
libxkbcommon
mesa
nspr
nss
pango
stdenv.cc.cc.lib
systemd
libX11
libxcb
libxcomposite
libxcursor
libxdamage
libxext
libxfixes
libxi
libxkbfile
libxrandr
libxscrnsaver
libxshmfence
libxtst
];
# dlopen'd at runtime; make autoPatchelf bake them into the rpath.
runtimeDependencies = [
libnotify
libGL
(lib.getLib systemd)
];
unpackCmd = "dpkg-deb -x $curSrc .";
sourceRoot = ".";
dontConfigure = true;
dontBuild = true;
# gappsWrapperArgs feed into the makeWrapper call below.
dontWrapGApps = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r usr/lib $out/lib
cp -r usr/share $out/share
# chrome-sandbox needs setuid-root, which the nix store can't provide.
# Disable the SUID sandbox and rely on user namespaces instead.
# The bundled Chromium/ANGLE dlopen()s the system libEGL.so.1 for GL; give it
# libglvnd + NixOS's GPU driver path so it hardware-accelerates instead of
# falling back to software rendering.
makeWrapper $out/lib/claude-desktop/claude-desktop $out/bin/claude-desktop \
"''${gappsWrapperArgs[@]}" \
--add-flags "--no-sandbox${lib.optionalString (deviceScaleFactor != null) " --force-device-scale-factor=${deviceScaleFactor}"}" \
--prefix PATH : ${lib.makeBinPath [ xdg-utils ]} \
--prefix LD_LIBRARY_PATH : "${lib.makeLibraryPath [ libGL mesa ]}:/run/opengl-driver/lib"
# Point the .desktop Exec/Icon at our wrapper (names already match).
substituteInPlace $out/share/applications/com.anthropic.Claude.desktop \
--replace-fail "Exec=claude-desktop" "Exec=$out/bin/claude-desktop"
runHook postInstall
'';
meta = {
description = "Desktop application for Claude.ai (official Linux build)";
homepage = "https://claude.ai";
license = lib.licenses.unfree;
sourceProvenance = [ lib.sourceTypes.binaryNativeCode ];
platforms = [ "x86_64-linux" ];
mainProgram = "claude-desktop";
};
})