Development Setup
This guide gets all three parts of the monorepo running locally: the phone app, the web app, and this documentation site.
Prerequisites
- Node.js 20 or newer (
node --version) - npm 10 or newer (bundled with Node)
- For the phone app only:
- JDK 17 or newer
- Android SDK (via Android Studio), with
ANDROID_HOMEset and a device or emulator available
The web app and the docs site need only Node.
Clone
git clone https://github.com/raiz-toff/Comma.git
cd CommaEach app installs its own dependencies from its own directory, described below.
Phone app
Install from the repository root:
npm installThen set up the Google OAuth client id used for Drive sign-in:
cp .env.example .env
# edit .env and set GOOGLE_WEB_CLIENT_IDSee Environment Variables for how to obtain it.
Run a development build
The GPS feature depends on the native comma-tracker module, and there is no working Expo Go path for it — Expo Go cannot load a custom native module, so GPS, the foreground service, and Google Sign-In will not work there. Build and run a development build instead:
npx expo run:androidThis compiles a native development binary and attaches the Metro bundler, so you get the native module plus fast refresh. Use this, not expo start against Expo Go, whenever you touch tracking.
iOS is not a shipping target — releases are Android APKs and AABs (see Releasing) — but a macOS machine with Xcode can run
npx expo run:iosfor UI work.
Build an installable APK
./build.shbuild.sh produces a signed APK or AAB. It needs the Android SDK path in android/local.properties (sdk.dir=/path/to/android-sdk) and the release keystore for a publishable build; see Releasing.
Inspect the database
adb shell
run-as app.comma.tracker
cd databases
sqlite3 comma.dbWeb app
The web app is a dependency-light PWA built with esbuild. It has its own package.json under web/:
cd web
npm install
npm run dev # esbuild dev build + local serveFor a production build:
npm run build # writes web/dist/
npm run preview # serve the built outputThe web app stores its data in the browser (IndexedDB), so nothing else is required to run it.
Docs site
These pages are authored as Markdown in docs/ and rendered by a Fumadocs (Next.js) app in docs-site/. The content is generated from docs/ by scripts/sync-content.mjs, which runs automatically before dev and build.
cd docs-site
npm install
npm run dev # runs the content sync, then next devTo edit a page, change the Markdown under docs/ and re-run (or keep dev running); the sync step copies it into the site. npm run build produces the production site.
Quality gates (phone app)
Run from the repository root:
npx tsc --noEmit # TypeScript, strict mode — no `any`
npm run lint # ESLint
npm test # JestDemo mode
To explore either app without entering real data, load demo mode from the welcome gate ("try the demo") or from Settings. It seeds sample shifts, expenses, vehicles, and goals so analytics and reports have something to show. Sync is disabled while demo data is loaded, so nothing sample ever reaches a real Drive.
Troubleshooting
Metro won't start — delete .expo/ and node_modules/.cache/, then npm install again.
Android build fails — check the SDK path in android/local.properties and that ANDROID_HOME is set.
GPS does nothing in an emulator — emulators have no real GPS. Feed coordinates from the emulator's Location panel, or test on a physical device.
Google Sign-In crashes — confirm GOOGLE_WEB_CLIENT_ID matches the OAuth client, and that your debug keystore's SHA-1 is registered in Google Cloud Console.
"Module not found" after adding a package — use npx expo install <package> for phone dependencies so you get an Expo-compatible version; rebuild the native binary if the package has native code.
GPS Engine
Comma reconstructs a shift's route from GPS: on the phone through a native Kotlin foreground service driven by a JavaScript hook, and on the web through a foreground, tab-open geolocation tracker.
Project Structure
An annotated map of the Comma monorepo: the Android/Expo phone app at the root, the web PWA under `web/`, these docs under `docs/`, and the docs site under `docs-site/`.