Files
fressh/CONTRIBUTING.md
EthanShoeDev 7eda9b1295 Add flake
2025-09-12 14:14:52 -04:00

5.6 KiB
Raw Blame History

Development with Nix (Android/Expo)

This repo ships a Nix flake that provides reproducible dev shells for React Native + Expo and Android workflows. You dont need global installs of Node/Watchman/Android SDK—the shell provides everything.

Prereqs

  • Nix with flakes enabled (nix --version should work)
  • (Optional, recommended) direnv + nix-direnv to auto-enter shells

Shell variants

We publish three dev shells:

  • default minimal JS toolchain you always want (Node, pnpm, watchman, git, jq, just)
  • android-local adds a full Android SDK + Emulator + API 36 Google Play x86_64 system image Good when you run the emulator on your machine.
  • android-remote no emulator/image; adds adb + scrcpy Good when you run an emulator on a remote server and mirror/control it locally.

Pick one per your setup.

Quick start

A) One-off use (no direnv)

# Minimal JS shell
nix develop .#default

# Local emulator workflow (SDK + emulator + API 36 image)
nix develop .#android-local

# Remote emulator workflow (adb + scrcpy only)
nix develop .#android-remote

Create .envrc at the project root:

# choose one:
use flake .#android-local
# use flake .#android-remote
# use flake .#default

Then:

direnv allow

Any new shell in this folder will enter the selected dev shell automatically.

What the shell sets up

  • Node/PNPM/Watchman/Git/JQ/Just (all shells)
  • ANDROID_SDK_ROOT / ANDROID_HOME (in android-local; points to the immutable SDK built by Nix)
  • adb / emulator / sdkmanager / avdmanager (in android-local)
  • adb / scrcpy (in android-remote)

Tip: we keep the Android SDK fully immutable (declarative). You dont “install packages” via Android Studio; the flake lists exactly which components are present.

Local emulator workflow (android-local)

  1. Enter the shell:
nix develop .#android-local
  1. (First time) Create an AVD for API 36 (Google Play, x86_64):
avdmanager create avd -n a36-play-x86_64 \
  -k "system-images;android-36;google_apis_playstore;x86_64"
  1. Run the emulator:
# GUI window (desktop)
emulator @a36-play-x86_64

# Headless (CI/servers):
emulator @a36-play-x86_64 -no-window -no-audio
# If no KVM: add -gpu swiftshader_indirect
  1. Verify adb sees it:
adb devices
  1. Run your typical Expo/RN commands (Metro, build, etc.) inside the shell.

macOS users: You can still build Android in this shell. The android-local shell provides platform-tools + SDK commands; the GUI Android Studio app is optional. If you prefer to use the macOS GUI emulator instead of the Nix one, thats fine—use default or android-remote and keep your local Android Studio install.

Remote emulator workflow (android-remote)

Use this when your emulator runs on a remote Linux box (often headless/KVM).

  1. Enter the shell:
nix develop .#android-remote
  1. SSH-tunnel the remote adb server back to your machine:
ssh -N -L 5037:127.0.0.1:5037 user@remote-host
  1. Point adb at the forwarded server and verify:
adb -H 127.0.0.1 -P 5037 devices
  1. Mirror/control the remote emulator window locally:
scrcpy

Thats it—everything flows through SSH, and you dont need any extra ports.

Common tasks

  • Check versions:

    adb version
    sdkmanager --version
    avdmanager --help
    
  • Upgrade/change Android components Edit the system image or build-tools/platforms listed in flake.nix under the androidSdk36 definition, then re-enter the shell.

  • Clean emulators/AVDs AVDs live in ~/.android/avd by default. You can remove an AVD with:

    avdmanager delete avd -n a36-play-x86_64
    

Troubleshooting

  • Emulator is very slow / wont start (Linux): Ensure /dev/kvm exists and your user has permission (kvm group). Headless servers without KVM can still run, but add -gpu swiftshader_indirect and expect reduced performance.

  • adb doesnt see the emulator: Kill any stray local adb server and retry:

    adb kill-server
    adb start-server
    adb devices
    
  • Gradle/Java mismatch: If your Android Gradle Plugin complains about Java, pin the JDK you need in the dev shell and set JAVA_HOME. (You can add a JDK to defaultPkgs in the flake if your project requires a specific version.)

  • Expo/Metro cant find Android SDK: Confirm echo $ANDROID_SDK_ROOT prints a path in the android-local shell.

CI usage

You can build/test in CI with:

nix develop --command bash -lc 'pnpm install && pnpm test'

or pick a specific shell:

nix develop .#android-local --command bash -lc 'just android-build'

If you want, I can add a tiny Justfile with just avd-create, just avd-run, and just adb-tunnel-remote helpers so the common commands are one-liners.

Enable Nix flakes globally

If you see errors like:

error: experimental Nix feature 'nix-command' is disabled; add '--extra-experimental-features nix-command' to enable it

…it means flakes are not enabled in your Nix configuration yet.

You can enable them permanently with a one-liner:

sudo mkdir -p /etc/nix && echo 'experimental-features = nix-command flakes' | sudo tee /etc/nix/nix.conf

Then restart your shell (or nix-daemon on macOS), and the error goes away.

From now on you can just run:

nix develop .#android-local

without passing any extra flags.