trilium/scripts/utils.mts
Elian Doran cbb1d53f25
fix(desktop): make start-prod launch Electron correctly on NixOS
The `start-prod`/`start-prod-no-dir` scripts invoked the npm prebuilt
Electron binary directly (`electron dist`), which fails to load on NixOS
because it's dynamically linked against FHS system libraries that don't
exist there (libcups.so.2, libgtk-3, libnss3, ...). The dev launcher
already handles this via electron-start.mts, but prod never did.

Add scripts/electron-run-prod.mts, a build-free launcher that reuses the
same NixOS-aware getElectronPath() (preferring the Nix/nix-develop
Electron over the prebuilt binary) and sets LD_LIBRARY_PATH plus
--no-sandbox on NixOS. On all other platforms it's a transparent
`electron <args>` wrapper, so behaviour is unchanged.

Also extract the shared getNixLdLibraryPath() helper so the dev and prod
launchers stay DRY.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-18 13:29:30 +03:00

62 lines
2.0 KiB
TypeScript

import { execSync } from "child_process";
import { existsSync, readFileSync } from "fs";
import { platform } from "os";
export function isNixOS() {
if (platform() !== "linux") return false;
const osReleasePath = "/etc/os-release";
if (existsSync(osReleasePath)) {
const osReleaseFile = readFileSync(osReleasePath, "utf-8");
return osReleaseFile.includes("ID=nixos");
} else {
return !!process.env.NIX_STORE;
}
}
function resetPath() {
// On Unix-like systems, PATH is usually inherited from login shell
// but npm prepends node_modules/.bin. Let's remove it:
const origPath = process.env.PATH || "";
// npm usually adds something like ".../node_modules/.bin"
process.env.PATH = origPath
.split(":")
.filter(p => !p.includes("node_modules/.bin"))
.join(":");
}
export function getElectronPath() {
if (isNixOS()) {
resetPath();
try {
const path = execSync("which electron").toString("utf-8").trimEnd();
return path;
} catch (e) {
// Nothing to do, since we have a fallback below.
}
console.log("No Electron in PATH, using 'nix develop' to get it...");
try {
const path = execSync("nix develop -c which electron", { stdio: ["pipe", "pipe", "pipe"] }).toString("utf-8").trimEnd();
return path;
} catch (e) {
console.error("\nFailed to get Electron from 'nix develop'.");
console.error("Please ensure you have a valid flake.nix with electron in devShells.default.");
process.exit(1);
}
} else {
return "electron";
}
}
/**
* On NixOS the Nix-provided Electron is dynamically linked against libstdc++
* from gcc.cc.lib. Resolve that store path so callers can add it to
* LD_LIBRARY_PATH before launching Electron.
*/
export function getNixLdLibraryPath() {
return execSync("nix eval --raw nixpkgs#gcc.cc.lib").toString("utf-8").trimEnd() + "/lib";
}