grok-bot-flake
August 14, 2026 · View on GitHub
Nix flake for Grok Bot, xAI's desktop
agent, on Linux. It repackages the official amd64 .deb — there is no source
build.
Note
Grok Bot is proprietary (meta.license = unfree). This flake is not
affiliated with xAI or Cursor.
Quick start
Run it once, without installing:
nix run github:jordangarrison/grok-bot-flake
This works, but sand:// login-redirect links will not route back to the app
until the package is properly installed — see
Getting sand:// links to work.
Add it to your Nix config
Flake input
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
grok-bot = {
url = "github:jordangarrison/grok-bot-flake";
inputs.nixpkgs.follows = "nixpkgs";
};
};
}
NixOS
{ inputs, pkgs, ... }:
{
environment.systemPackages = [
inputs.grok-bot.packages.${pkgs.system}.default
];
}
Home Manager
{ inputs, pkgs, ... }:
{
home.packages = [
inputs.grok-bot.packages.${pkgs.system}.default
];
}
Overlay (if you prefer pkgs.grok-bot)
nixpkgs.overlays = [ inputs.grok-bot.overlays.default ];
environment.systemPackages = [ pkgs.grok-bot ];
The flake's own packages output already allows unfree for you. The overlay
deliberately does not — it uses your nixpkgs config, so you need allowUnfree
(or an allowUnfreePredicate matching grok-bot) when consuming it that way.
Imperative install
nix profile install github:jordangarrison/grok-bot-flake
What you get
grok-bot— the app, wrapped for NixOS (patchelf'd, GApps-wrapped, Wayland-aware).sand— a compatibility alias for the same binary. Older upstream releases used that executable name, and the app still registers thesand://URL scheme used by existing login flows.share/applications/grok-bot.desktop+ icon, so launchers and URL-scheme routing can find the app.
Wayland is opt-in through the usual NixOS variable: with NIXOS_OZONE_WL=1
set (and a Wayland session), the wrapper adds --ozone-platform-hint=auto and
Wayland window decorations. Otherwise it runs under XWayland/X11.
Getting sand:// links to work
Login redirects open sand://... URLs. For your desktop environment to route
those to Grok Bot, two things must hold:
-
grok-bot.desktopmust be onXDG_DATA_DIRS— true automatically once the package is installed via NixOS, Home Manager, ornix profile install. A barenix rundoes not do this. -
The scheme must map to the app. The app registers itself on first launch (the wrapper sets
CHROME_DESKTOP=grok-bot.desktopso Electron registers the right desktop id). To set it manually:xdg-mime default grok-bot.desktop x-scheme-handler/sand
Verify with:
xdg-mime query default x-scheme-handler/sand # → grok-bot.desktop
Empty output means the desktop file isn't visible (see 1). The desktop id
stays grok-bot.desktop across rebuilds even though the store path in Exec=
changes, so the association survives upgrades.
Packaging notes
Upstream ships its own Electron 42 build, and the bundled native modules
(better-sqlite3, tree-sitter, and others) are compiled against it. This
flake keeps that Electron instead of swapping in pkgs.electron_42 — no ABI
risk, and the result matches what upstream tests.
The build unpacks the .deb, runs autoPatchelfHook over the binaries and
.node modules, and wraps the launcher with wrapGAppsHook3.
Differences from the .deb:
-
chrome-sandboxis removed. It only works setuid root, which the Nix store cannot express. Chromium falls back to the user-namespace sandbox, which NixOS enables by default. If your kernel disables unprivileged user namespaces, the app will not start — re-enable them rather than running with--no-sandbox. -
--no-sandboxis added. Upstream's custom Electron build crash-loops everysandbox: truerenderer — notably the<webview>that shows your agent's box screen — withFATAL:platform_shared_memory_region_posix.cc(/dev/shm ... No such process). Traced with strace: the renderer is forked from the sandboxed zygote (chroot'd into a dead/proc/<tid>/fdinfo, which is where the oddESRCHcomes from) and then tries to create/dev/shmshared memory directly. Stock Chromium brokers that allocation through the browser process; upstream's build never installs the broker hooks for webview renderers, so the crash is environment-independent — the same signature is reported for.deb-class Electron apps on stock Ubuntu (electron#30758, open-webui/desktop#157). A stock nixpkgselectron_42runs the identical sandboxed renderer fine.The flag costs nothing that works today: upstream already launches its main renderer with
--no-sandbox --no-zygote, its GPU process with--no-sandbox, and every utility process with--service-sandbox-type=none. The webview was the only process that got a real sandbox, and it only ever crashed. The flag will be removed when upstream fixes their sandboxed-renderer shared-memory path. -
The AppArmor profile is not installed. It is Ubuntu-specific and refers to
/optpaths that do not exist here.
Updating
./update.sh
Reads the current stable version from upstream's update feed and rewrites the
download namespace, version, buildId, and hash in package.nix. It also
checks that the downloaded artifact is the expected sand/grok-bot amd64
package and that its embedded version matches the feed before changing
anything.
One wrinkle: upstream's Linux update feed is empty — linux-x64 answers HTTP
204 for every version, and the in-app updater has no Linux branch at all (it
falls through to darwin-arm64). The download namespace and build id are
shared across platforms, so the script reads them from the darwin-arm64 feed,
rebuilds the conventional Linux .deb URL, downloads it, and validates its
metadata. If upstream changes that Linux URL convention, the update fails
safely instead of committing an unverified package. This also means in-app
self-update does not work on Linux — re-run ./update.sh and rebuild instead.
A daily GitHub Actions workflow runs the updater, refreshes flake.lock, builds
the package, and commits verified changes to main. The workflow can also be
run manually from the Actions tab.
To pin an exact build, pass its URL:
./update.sh https://downloads.cursor.com/<product>/stable/<buildId>/linux/x64/Grok_Bot_<version>.deb
Provenance
The .deb is served from downloads.cursor.com, and its control file lists
SpaceXAI <hi@cursor.com> as vendor with Homepage: https://cursor.com.
Upstream renamed the Debian package from sand to grok-bot in 0.19.0 while
retaining sand as a provided compatibility name. The app is built on Cursor's
release infrastructure. That is expected, not a mis-download.