asana flake (and script for non-nixos) to package the official app for Linux
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Kate Meerburg f410eed80f Asana desktop for Linux: repack the official macOS app at nix build time
Asana ships Electron apps for macOS and Windows only, but the app has no
native modules and nothing in app.asar.unpacked, so the official asar runs
unmodified on a same-major Linux Electron (nixpkgs electron 41 vs their
41.1.0).

The official Asana.dmg is a locked flake input; the build extracts app.asar
from it, applies two data-level patches, and repacks:

- Icons: on non-macOS the app resolves icon paths to .ico files (including
  assets/asanaTrayTemplate.ico, which was never shipped), and Linux
  Electron's nativeImage can't decode real ICO — but it sniffs content, so
  PNG bytes at the .ico-named paths work.
- User agent: app.asana.com rejects the desktop login token exchange
  (?error=failed_start_session) for unknown platform strings, so the UA
  template reports darwin_<arch> instead of linux_<arch>.

The build fails if the DMG's version drifts from the flake's version attr,
or if Asana's Electron major stops matching nixpkgs electron. Packaging
includes a desktop entry with x-scheme-handler/asanadesktop for the browser
login handoff and CHROME_DESKTOP so the app's own xdg-settings registration
works.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V5HW2LxqZH8V8siSDL9HTT
2026-07-29 16:17:29 +02:00
.gitignore Asana desktop for Linux: repack the official macOS app at nix build time 2026-07-29 16:17:29 +02:00
flake.lock Asana desktop for Linux: repack the official macOS app at nix build time 2026-07-29 16:17:29 +02:00
flake.nix Asana desktop for Linux: repack the official macOS app at nix build time 2026-07-29 16:17:29 +02:00
README.md Asana desktop for Linux: repack the official macOS app at nix build time 2026-07-29 16:17:29 +02:00

Asana for Linux (unofficial)

Asana ships an Electron desktop app for macOS and Windows but not Linux. Their app has no native modules and no app.asar.unpacked — it's pure JS (they even carry @electron-forge/maker-deb and maker-rpm in their devDependencies; they just never ship the result). So the official macOS app.asar runs unmodified on a Linux Electron of the same major version.

This flake does the whole repack at build time. The official Asana.dmg is a locked flake input (the URL always points at the latest release; flake.lock pins the exact file), and the build extracts the asar out of it, applies two data-level patches, and repacks:

  1. Icon files. On non-macOS the app resolves icon paths to .ico files (assets/asana_prod.ico, assets/asanaTrayTemplate.ico — the latter was never shipped at all), and Linux Electron's nativeImage can't decode real ICO. It sniffs content rather than extension, so PNG bytes (pulled from asana_prod.icns) at the .ico-named paths work fine.
  2. User agent. The app identifies as AsanaDesktopOfficial ${process.platform}_${arch}/<version>, and app.asana.com rejects the login token exchange (/-/desktop_start_session?error=failed_start_session, shown as "something went wrong") when the platform isn't one it knows. One string in the UA template is changed so it reports darwin_<arch> instead of linux_<arch>.

No JavaScript logic is modified.

Run / install

nix run .                      # one-off
nix profile install .          # install; desktop entry + icon included

Login flow / asanadesktop:// scheme

The desktop login flow hands the session from your browser back to the app via asanadesktop:// URLs. The desktop entry advertises MimeType=x-scheme-handler/asanadesktop, and the app forwards URLs from second launches to the running instance via its single-instance lock — but the scheme's default handler registration is per-user state. After installing, run once:

xdg-mime default asana.desktop x-scheme-handler/asanadesktop

(The wrapper also sets CHROME_DESKTOP=asana.desktop, so the app's own setAsDefaultProtocolClient("asanadesktop") call — which shells out to xdg-settings on Linux — can register the right desktop file by itself, but the explicit xdg-mime line doesn't depend on xdg-settings working under your compositor.)

Updating

nix flake update asana-dmg
nix build .

Then bump version in flake.nix to whatever the build tells you it found — the build fails on a mismatch so the flake can't silently drift, and it also fails if Asana's Electron major no longer matches nixpkgs' electron (pin a matching electron_NN in the flake if that happens).

Notes

  • Because it runs under a bare electron binary, app.isPackaged is false and the app considers itself a dev build: profile lives in ~/.config/Asana Dev/, release channel reports "beta", the Debug menu is enabled, and the auto-updater never initializes (it's gated on dev mode before any platform check). Updates happen via nix flake update instead; nothing self-updates.
  • The server can still age old clients out: app.asana.com has a "DesktopForceUpdatePage" flow that walls clients it considers too old, which on Linux can't self-resolve. If that ever appears, update the flake input.
  • Asana version at time of writing: 2.7.2 (Electron 41.1.0; nixpkgs Electron 41.9.1).