mirror of
https://github.com/EthanShoeDev/fressh.git
synced 2026-01-11 14:22:51 +00:00
230 lines
5.6 KiB
Markdown
230 lines
5.6 KiB
Markdown
# Development with Nix (Android/Expo)
|
||
|
||
This repo ships a Nix **flake** that provides reproducible dev shells for React
|
||
Native + Expo and Android workflows. You don’t need global installs of
|
||
Node/Watchman/Android SDK—the shell provides everything.
|
||
|
||
## Prereqs
|
||
|
||
- Nix with flakes enabled (`nix --version` should work)
|
||
- (Optional, recommended) [`direnv`](https://direnv.net/) +
|
||
[`nix-direnv`](https://github.com/nix-community/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)
|
||
|
||
```bash
|
||
# 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
|
||
```
|
||
|
||
### B) Auto-enter with direnv (recommended)
|
||
|
||
Create `.envrc` at the project root:
|
||
|
||
```bash
|
||
# choose one:
|
||
use flake .#android-local
|
||
# use flake .#android-remote
|
||
# use flake .#default
|
||
```
|
||
|
||
Then:
|
||
|
||
```bash
|
||
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 don’t
|
||
> “install packages” via Android Studio; the flake lists exactly which
|
||
> components are present.
|
||
|
||
## Local emulator workflow (`android-local`)
|
||
|
||
1. Enter the shell:
|
||
|
||
```bash
|
||
nix develop .#android-local
|
||
```
|
||
|
||
2. (First time) Create an AVD for API 36 (Google Play, x86_64):
|
||
|
||
```bash
|
||
avdmanager create avd -n a36-play-x86_64 \
|
||
-k "system-images;android-36;google_apis_playstore;x86_64"
|
||
```
|
||
|
||
3. Run the emulator:
|
||
|
||
```bash
|
||
# 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
|
||
```
|
||
|
||
4. Verify `adb` sees it:
|
||
|
||
```bash
|
||
adb devices
|
||
```
|
||
|
||
5. 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, that’s 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:
|
||
|
||
```bash
|
||
nix develop .#android-remote
|
||
```
|
||
|
||
2. SSH-tunnel the **remote adb server** back to your machine:
|
||
|
||
```bash
|
||
ssh -N -L 5037:127.0.0.1:5037 user@remote-host
|
||
```
|
||
|
||
3. Point `adb` at the forwarded server and verify:
|
||
|
||
```bash
|
||
adb -H 127.0.0.1 -P 5037 devices
|
||
```
|
||
|
||
4. Mirror/control the remote emulator window locally:
|
||
|
||
```bash
|
||
scrcpy
|
||
```
|
||
|
||
That’s it—everything flows through SSH, and you don’t need any extra ports.
|
||
|
||
## Common tasks
|
||
|
||
- Check versions:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
avdmanager delete avd -n a36-play-x86_64
|
||
```
|
||
|
||
## Troubleshooting
|
||
|
||
- **Emulator is very slow / won’t 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` doesn’t see the emulator**: Kill any stray local adb server and retry:
|
||
|
||
```bash
|
||
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 can’t 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:
|
||
|
||
```bash
|
||
nix develop --command bash -lc 'pnpm install && pnpm test'
|
||
```
|
||
|
||
or pick a specific shell:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
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:
|
||
|
||
```bash
|
||
nix develop .#android-local
|
||
```
|
||
|
||
without passing any extra flags.
|