--- name: working-with-nix description: Use when working with Nix flakes, selecting devShells, debugging environment issues, or understanding Nix infrastructure - covers shell selection, environment detection, common commands, and project-specific constraints like pinned Rust versions --- # Working with Nix in libxmtp ## Quick Shell Selection | Task | Shell | Command | |------|-------|---------| | Focused Rust crates/bindings work | rust | `nix develop .#rust` | | Full local development (default) | local | `nix develop` | | Android builds/testing | android | `nix develop .#android` | | iOS builds/testing | ios | `nix develop .#ios` | | JavaScript/Node.js | js | `nix develop .#js` | | WebAssembly builds | wasm | `nix develop .#wasm` | ## Environment Detection ```bash echo $XMTP_NIX_ENV # "yes" if in any Rust-based Nix shell echo $XMTP_DEV_SHELL # "local", "android", "ios", or unset ``` ## Critical Constraints ### Rust Version is Pinned — Do Not Change Rust is pinned via `flake.nix` → `rust-manifest` (1.97.1 as of 2026-07; check with `nix develop .#rust -c rustc --version`). All shells use `xmtp.mkToolchain`. Never modify without project-wide coordination. ### Playwright Versions Must Match EXACTLY The `playwright` pin in `bindings/wasm/package.json` (`=X.Y.Z`) must equal nixpkgs' playwright version. The js shell provides browsers via `PLAYWRIGHT_BROWSERS_PATH` (`nix/js.nix`), and npm playwright looks them up by its own per-version browser revisions — any skew fails WASM tests with `browserType.launch: Executable doesn't exist at .../chromium_headless_shell-NNNN/...`. After every nixpkgs (flake.lock) bump: ```bash nix eval --raw .#devShells.x86_64-linux.js.PLAYWRIGHT_VERSION # If it differs from the package.json pin: update the pin, then # (cd bindings/wasm && yarn install) ``` ### iOS Shell is macOS Only The `.#ios` shell only works on Darwin. Requires Xcode 16+ for Swift 6.1. ### Untracked Files are Invisible to Flakes ```bash git add # Then rebuild — flakes only see git-tracked files ``` ### Cachix Verify the binary cache is active: `nix config show | grep substituters` — should include `https://xmtp.cachix.org`. ## Shell Architecture Shells are independent — they compose from shared building blocks, not from each other: ``` shell-common.nix → shared building blocks (rustBase, wasmEnv, tool groups) ├── rust.nix → focused Rust shell (crates/bindings, lint, test) ├── local.nix → full local dev (default) = all targets + debug + misc ├── android.nix → Android cross-compilation └── ios.nix → iOS cross-compilation (macOS only) js.nix → JavaScript/browser testing (no Rust) package/wasm.nix → WASM shell + package build ``` ## Essential Commands ```bash # Enter shells nix develop # Default shell nix develop .#rust # Focused Rust shell nix develop .#android # Android shell nix develop .#ios # iOS shell (macOS only) nix develop .#js # JavaScript shell nix develop .#wasm # WASM shell # Build packages nix build .#wasm-bindings # WASM compiled bindings nix build .#node-bindings-fast # Host-matching .node binary nix build .#node-bindings-js # Generated JS/TS bindings nix build .#node-bindings-linux-x64-gnu # Per-target .node (example) nix build .#android-libs # All Android targets nix build .#ios-libs # All iOS targets (macOS only) # Explore nix flake show # List all outputs nix flake metadata # Show inputs and versions # Debug nix develop --show-trace # Verbose error output ``` ## Platform Support | Platform | Shells Available | |----------|------------------| | macOS (aarch64-darwin) | rust, default, android, ios, js, wasm | | Linux (x86_64-linux) | rust, default, android, js, wasm | ## Key Files | File | Purpose | |------|---------| | `flake.nix` | DevShell + package definitions, input pinning, cachix | | `nix/lib/default.nix` | Overlay wiring — exposes `xmtp.*` to all Nix files | | `nix/lib/shell-common.nix` | Shared building blocks (rustBase, wasmEnv, tool groups) | | `nix/lib/mkToolchain.nix` | Rust version pinning logic | | `nix/lib/filesets.nix` | Source file filtering for hermetic builds | | `nix/lib/mobile-common.nix` | Shared mobile (iOS/Android) build args | | `nix/lib/android-env.nix` | Android SDK config, targets, emulator script | | `nix/lib/ios-env.nix` | iOS targets, dynamic Xcode resolution | | `nix/lib/node-env.nix` | Node targets, NAPI name mapping, cross-compilation | | `nix/shells/rust.nix` | Focused Rust dev shell | | `nix/shells/local.nix` | Full local dev shell (default) | | `nix/shells/android.nix` | Android dev shell | | `nix/shells/ios.nix` | iOS dev shell (macOS only) | | `nix/js.nix` | JavaScript shell | | `nix/package/wasm.nix` | WASM shell + package build | | `nix/package/node.nix` | Node.js per-target builds + JS/TS generation | | `nix/package/android.nix` | Android release build derivation | | `nix/package/ios.nix` | iOS release build derivation | | `dev/nix-up` | Installation script for Nix and direnv | ## Further Reference - [Shell: Default](shells/default.md) — Full local dev shell reference - [Shell: Rust](shells/rust.md) — Focused Rust shell reference - [Shell: Android](shells/android.md) — Android shell reference - [Shell: iOS](shells/ios.md) — iOS shell reference - [Shell: JavaScript](shells/js.md) — JavaScript shell reference - [Shell: WASM](shells/wasm.md) — WASM shell reference - [Nix Build Packages](packages.md) — All `nix build .#` outputs - [Troubleshooting](troubleshooting.md) — Common issues and solutions