Workstation setup
Install the Core set for everything, then the sections for the apps you will work on.
Core (everyone)
| Tool | Version | Why |
|---|---|---|
| Git | current | all repos |
| Node.js via nvm | 26.8.2 (team standard; every repo needs 20+, CI uses 24) | all React apps, this site |
| Tailscale | current | dev database and SSH |
| An editor | VS Code or similar | |
GitHub CLI (gh) | optional | pull requests and issues from the terminal |
Windows
# elevated PowerShell
choco install git nvm tailscale vscode gh
nvm install 26.8.2
nvm use 26.8.2
macOS
brew install git nvm tailscale gh
nvm install 26.8.2 && nvm use 26.8.2
Sign in to Tailscale and confirm tailscale status shows you connected before you try to reach anything in Azure.
Backend (emaw-django-app)
| Tool | Version | Why |
|---|---|---|
| Python | 3.12 (matches the python:3.12-slim image) | running manage.py and tests on the host |
| Docker Desktop | current, WSL2 backend on Windows | the compose stack: Django, Celery, Redis, Qdrant, tunnel |
| WSL2 (Windows) | wsl --install, reboot | required by Docker Desktop |
| ffmpeg | optional | only for the audio code (pydub); already in the image |
choco install python312 docker-desktop
brew install python@3.12 --cask docker
Then follow Backend local development.
Web apps (emaw-website, emaw-web-app, emaw-crm-app, emaw-documentation)
Nothing beyond Core. Each repo is npm install then npm run dev (or npm start here). Install Wrangler only if you will deploy by hand; the repos invoke it with npx wrangler@4, so a global install is unnecessary.
Ports the apps expect, so they can run side by side against the same backend:
| App | Port |
|---|---|
| Website | 5173 (npm run dev), 8788 (npm run dev:pages) |
| Web app | 5174 |
| Admin CRM | 5173 (do not run with the website at the same time, or pass --port) |
| Docs | 3000 |
The backend's development CORS list allows localhost on 5173, 5174, 3000, 5000 and 8788.
Mobile (emaw-mobile-app)
The app uses native modules (Google sign-in, SQLite, secure store, audio), so Expo Go does not work; you run a development build on an emulator, simulator or device.
| Tool | Version | Why |
|---|---|---|
| Node (Core) | 26 | |
| EAS CLI | 13.2.0 or newer (eas.json) | cloud builds, submissions, updates |
| Android Studio | current | Android SDK (compile 37 / target 36 / min 24), emulator |
| Android NDK | 27.1.12297006 | required by React Native 0.88 |
| CMake | from the SDK manager | native build |
| JDK | 17 or newer (Android Studio's bundled JBR 21 works) | Gradle |
| Xcode + CocoaPods (macOS only) | current | iOS simulator builds |
| Apple Developer / Google Play Console roles | only if you submit builds |
npm install -g eas-cli
choco install androidstudio
npm install -g eas-cli
brew install --cask android-studio
sudo gem install cocoapods # or brew install cocoapods
Gradle needs a 4 GB heap; the repo's withGradleJvmArgs config plugin sets it for you on prebuild. Full detail, including the Google OAuth client IDs the app expects in .env, is in Mobile workstation setup.
Optional but useful
- Stripe CLI to forward webhooks to a local backend and trigger test events:
choco install stripe-cli/brew install stripe/stripe-cli/stripe. - Postman or Bruno for exercising
/rest/endpoints with a bearer token. - DBeaver or psql to look at the dev database over Tailscale (read carefully; it is shared).
- actionlint to validate GitHub workflow files before pushing.