{"slug": "installing-jcode-on-nix-nixos-a-practical-unofficial-guide", "title": "Installing jcode on nix/NixOS: A Practical Unofficial Guide", "summary": "Jcode, an open-source AI coding agent from GitHub user 1jehuang, can be installed on Nix/NixOS via its official Nix build, but users must manually download, verify, and place the binary because pure Nix environments lack system package managers. The guide details steps including verifying the sha256 digest (e.g., 2faea9dc9f560e6f9a73da360d57b3c1d32f4ccfa90bbea2352237ba43472bb3 for v0.66.0), handling 'Text file busy' errors during upgrades, and symlinking the binary into jcode's build directories to ensure proper operation.", "body_md": "# Installing jcode on nix/NixOS: A Practical Unofficial Guide\n\n[jcode](https://github.com/1jehuang/jcode?ref=grigio.org) is an open-source AI coding agent\n\nthat runs as a local server and drives your editor. It's distributed as a\n\nsingle self-contained executable, which sounds simple, [until you try to run itin a pure Nix environment](https://github.com/1jehuang/jcode/issues/115?ref=grigio.org): no system package manager, no Nix channels, no\n\n`/usr/bin/env`\n\n. This post walks through installing the official Nix build fromGitHub releases, the surprising gotchas you will hit, and how to fix them.\n\n## What you need\n\n- A machine where the Nix store is present and mounted: a\n`bwrap-nix`\n\nsandbox,\n\nNixOS, or any host with`nix`\n\ninstalled. The jcode binary is dynamically\n\nlinked against the glibc shipped in the store, so the store must be there at\n\nruntime. `curl`\n\nand`sha256sum`\n\nfor downloading and verifying the release.- A writable\n`~/.local/bin`\n\n(or any directory on your`PATH`\n\n).\n\n## Step 1: Find the release\n\njcode publishes Nix builds as GitHub releases tagged `nix-vX.Y.Z`\n\n, for example`nix-v0.66.0`\n\n. Each release carries one asset per platform:\n\n```\njcode-nix-linux-x86_64\n```\n\nThe release page shows the exact `sha256`\n\ndigest for every asset, so you can\n\nverify your download:\n\n```\ncurl -s https://api.github.com/repos/grigio/jcode/releases/tags/nix-v0.66.0 \\\n  | jq -r '.assets[] | .name + \"  \" + .digest'\n```\n\n## Step 2: Download and verify\n\n```\nmkdir -p ~/jcode-install && cd ~/jcode-install\ncurl -sSL -o jcode-nix-linux-x86_64 \\\n  https://github.com/grigio/jcode/releases/download/nix-v0.66.0/jcode-nix-linux-x86_64\nsha256sum jcode-nix-linux-x86_64\n```\n\nCompare the output against the digest published on the release page. For\n\nv0.66.0 it is:\n\n```\n2faea9dc9f560e6f9a73da360d57b3c1d32f4ccfa90bbea2352237ba43472bb3  jcode-nix-linux-x86_64\n```\n\nA checksum mismatch means a corrupted download or a tampered asset. Stop and\n\nre-download.\n\n## Step 3: Confirm it is a real executable\n\nThe Nix build is a genuine ELF binary, not a script. `file`\n\nshould show a\n\ndynamically linked PIE with a Nix store interpreter:\n\n```\nfile jcode-nix-linux-x86_64\n# ELF 64-bit LSB pie executable, x86-64, dynamically linked,\n# interpreter /nix/store/<hash>-glibc-<ver>/lib/ld-linux-x86-64.so.2\n```\n\nThen check the version:\n\n```\nchmod +x jcode-nix-linux-x86_64\n./jcode-nix-linux-x86_64 --version\n# jcode v0.66.0 (nix-build)\n```\n\n## Step 4: Install\n\nPut the binary on your `PATH`\n\n:\n\n```\nmkdir -p ~/.local/bin\ncp jcode-nix-linux-x86_64 ~/.local/bin/jcode\nchmod +x ~/.local/bin/jcode\n~/.local/bin/jcode --version\n```\n\n### Replacing a running jcode: \"Text file busy\"\n\nIf you are upgrading and a jcode server is currently running from that path, a\n\nplain `cp`\n\nfails with `Text file busy`\n\n. Linux refuses to truncate an executable\n\nthat is mapped by a live process. Copy to a temporary name and atomically\n\nrename it instead:\n\n```\ncp jcode-nix-linux-x86_64 ~/.local/bin/jcode.new\nchmod +x ~/.local/bin/jcode.new\nmv -f ~/.local/bin/jcode.new ~/.local/bin/jcode\n```\n\nThe old server keeps running from its in-memory image; the new version is used\n\nby the next server start.\n\n## Step 5: Understand jcode's layout\n\njcode manages its own builds under `~/.jcode/builds/`\n\n:\n\n```\n~/.jcode/builds/\n  shared-server/jcode     # what the server actually launches\n  stable/jcode            # the stable build\n  versions/<version>/     # per-version builds from self-update\n  shared-server-version   # version marker\n  stable-version          # version marker\n```\n\nAfter a manual Nix install, point the `shared-server`\n\nand `stable`\n\nsymlinks at\n\nthe real ELF in `~/.local/bin/jcode`\n\n:\n\n```\nln -sfn \"$HOME/.local/bin/jcode\" \"$HOME/.jcode/builds/shared-server/jcode\"\nln -sfn \"$HOME/.local/bin/jcode\" \"$HOME/.jcode/builds/stable/jcode\"\n```\n\nand keep the version markers in sync:\n\n```\necho 0.66.0 > ~/.jcode/builds/shared-server-version\necho 0.66.0 > ~/.jcode/builds/stable-version\n```\n\n## The Nix gotcha: self-update breaks the sandbox\n\njcode self-updates by downloading a new build into`~/.jcode/builds/versions/<version>/jcode`\n\nand pointing `shared-server/jcode`\n\nat it. That downloaded file is **not** the binary. It is a wrapper shell script\n\nwhose first line is:\n\n``` bash\n#!/usr/bin/env sh\n```\n\nIn a Nix-only environment `/usr/bin/env`\n\ndoes not exist (the `env`\n\nbinary lives\n\nin the store under `coreutils`\n\n), so `execve(2)`\n\nfails with `ENOENT`\n\nand the\n\nserver never starts. Verified with strace:\n\n```\nexecve(\".../.jcode/builds/shared-server/jcode\",\n       [\"...\", \"--provider\", \"auto\", \"serve\"], ...) = -1 ENOENT\n```\n\nTwo equivalent fixes. Do one of them.\n\n### Option A (recommended): point shared-server at the real binary\n\n```\nln -sfn \"$HOME/.local/bin/jcode\" \"$HOME/.jcode/builds/shared-server/jcode\"\n```\n\nNo wrapper, no interpreter, no breakage. This also pins the server to the\n\nbinary you installed instead of an untested self-update.\n\n### Option B: provide /usr/bin/env\n\nGive the shebang what it wants by symlinking the store `env`\n\ninto `/usr/bin`\n\n(only possible when `/usr/bin`\n\nis writable):\n\n```\nln -sf \"$(dirname \"$(readlink -f \"$HOME/.local/bin/env\")\")/env\" /usr/bin/env\n# e.g. /nix/store/<hash>-coreutils-9.10/bin/env\n```\n\n## Run the server\n\n```\n~/.jcode/builds/shared-server/jcode --provider auto serve\n```\n\nor directly:\n\n```\n~/.local/bin/jcode --provider auto serve\n```\n\nNotes:\n\n- Only\n**one** server instance may run per runtime dir. A second launch fails\n\nwith`Error: Another jcode server process is already running for runtime dir /tmp/<...>/jcode-<uid>`\n\n. To restart, kill the existing PID first, then start\n\nagain. - Verify the daemon is alive with\n`jcode --version`\n\nor by checking the runtime\n\ndir (`/tmp/<...>/jcode-<uid>/`\n\n) for`jcode.sock`\n\nand`jcode-debug.sock`\n\n.\n\n## Upgrading to a new release\n\nThe process is the same every time: download the new `jcode-nix-linux-x86_64`\n\nasset, verify its digest, `mv`\n\nit over `~/.local/bin/jcode`\n\n, re-run the\n\nsymlink command if anything changed, update the version markers, and restart\n\nthe server. The old binary can be kept as a rollback:\n\n```\ncp ~/.local/bin/jcode ~/.local/bin/jcode.v0.65.0.bak\n```\n\n## Checklist\n\n- [ ]\n`sha256sum`\n\nmatches the digest on the release page - [ ]\n`file`\n\nreports an ELF, not a shell script - [ ]\n`~/.local/bin/jcode --version`\n\nprints`jcode vX.Y.Z (nix-build)`\n\n- [ ]\n`shared-server/jcode`\n\nand`stable/jcode`\n\nare symlinks to the ELF - [ ] version markers match the installed version\n- [ ] the server starts and binds its socket\n\n## Conclusion\n\nInstalling jcode on Nix is straightforward once you know the rules: download\n\nthe Nix-built ELF, verify it, drop it on your `PATH`\n\n, and keep jcode's own\n\nsymlinks pointed at the real binary instead of a self-update wrapper. The`/usr/bin/env`\n\ntrap is the one thing that will bite you, and Option A above\n\nmakes it a non-issue forever.", "url": "https://wpnews.pro/news/installing-jcode-on-nix-nixos-a-practical-unofficial-guide", "canonical_source": "https://grigio.org/installing-jcode-on-nix-nixos-a-practical-unofficial-guide/", "published_at": "2026-08-03 14:16:03+00:00", "updated_at": "2026-08-03 14:31:40.411567+00:00", "lang": "en", "topics": ["developer-tools", "ai-tools", "ai-agents"], "entities": ["jcode", "1jehuang", "NixOS", "GitHub"], "alternates": {"html": "https://wpnews.pro/news/installing-jcode-on-nix-nixos-a-practical-unofficial-guide", "markdown": "https://wpnews.pro/news/installing-jcode-on-nix-nixos-a-practical-unofficial-guide.md", "text": "https://wpnews.pro/news/installing-jcode-on-nix-nixos-a-practical-unofficial-guide.txt", "jsonld": "https://wpnews.pro/news/installing-jcode-on-nix-nixos-a-practical-unofficial-guide.jsonld"}}