FlightDeck-style flight tracker monorepo (v1).
| Layer | Role |
|---|---|
Expo mobile (apps/mobile) |
Source of truth for live ADS-B / FR24 positions |
Convex (packages/backend) |
Correlated product data (ACARS, alerts, track list) |
@cockpit/fr24 |
Expo-safe FR24 client (no Node-only deps) |
@cockpit/shared |
Types, enums, correlation helpers, formatters |
- Node 24+
- pnpm (
npm i -g pnpm) - Convex account (hosted cloud)
- Expo Go or simulator
pnpm installClear any previous anonymous local backend, then log in and create a cloud dev deployment:
# One-time account login (opens browser)
pnpm convex:login
# Create/link a cloud project (interactive)
cd packages/backend
pnpm setup
# or: npx convex dev --once --configure=new --dev-deployment cloudCopy the deployment URL into the mobile app:
# from repo root
pnpm sync:convex-urlThis writes EXPO_PUBLIC_CONVEX_URL into apps/mobile/.env.
Seed demo ACARS/alerts:
pnpm convex:seed
# or: pnpm --filter @cockpit/backend seedOptional — AI ACARS explanations (tap a message in flight detail):
cd packages/backend
npx convex env set GROQ_API_KEY <your-groq-key>
# optional model override (default llama-3.1-8b-instant)
# npx convex env set ACARS_EXPLAIN_MODEL llama-3.1-8b-instantpnpm devRuns Convex (convex dev → hosted) and Expo in parallel.
When Metro says Waiting on http://localhost:8081, it is ready — Turbo often hides the QR UI. Connect with:
- Expo Go → Enter URL →
exp://<your-lan-ip>:8081(printed at mobile startup; prefer Wi‑Fi IP, not VPN) - Emulator: run mobile in an interactive terminal:
pnpm dev:mobile, then pressa/i - Web browser: http://localhost:8081
- Mobile alone (interactive QR when not under Turbo):
pnpm dev:mobile - Backend alone:
pnpm dev:backend
Expo defaults to online so manifest assets (app icons, splash) and icon fonts resolve. If Expo’s version API is slow/unreachable and startup hangs, use offline mode:
pnpm --filter @cockpit/mobile dev:offlineNote: first offline start without a schema cache may warn
Unable to resolve manifest assets. Icons and fonts might not work.
Run once online to populate ~/.expo cache, then offline works cleanly.
- Device fetches FR24 feed/detail/search via
@cockpit/fr24 - Live tab is a map of aircraft (react-native-maps); tap a symbol for a bottom flight sheet, then full detail
- Convex stores ACARS, alerts, tracked flights only (no live positions)
- Live ACARS is pulled server-side from the Airframes messages API (
acarsLive.refreshForFlight/acarsLive.search) — same feeder network as TBG search - Tap an ACARS message →
acarsExplain.requeststreams a Groq explanation intoacarsExplanations(requiresGROQ_API_KEYon Convex) - Correlation keys (prefer order):
fr24Id→icao24→callsign/flightNumber
| Goal | Command |
|---|---|
| Hosted personal dev | pnpm --filter @cockpit/backend use:cloud then pnpm dev:backend |
| Local anonymous/local | pnpm --filter @cockpit/backend use:local then pnpm dev:backend |
After switching, run pnpm sync:convex-url so Expo points at the same deployment.
Unofficial educational FR24 access. Commercial use requires business@fr24.com / official FR24 API.
MIT — see LICENSE for details.
- Fork the repo and open a PR against
master. - Run
pnpm install,pnpm typecheck, and test your changes locally. - Do not commit secrets — use Convex env vars (
GROQ_API_KEY, etc.) and local.envfiles (see.env.examplefiles). - Optional: install Convex agent skills with
npx convex ai-files install(not checked into the repo).
| Package | Scripts |
|---|---|
@cockpit/shared |
typecheck |
@cockpit/fr24 |
typecheck |
@cockpit/backend |
dev, setup, seed, use:cloud |
@cockpit/mobile |
dev (online Expo), dev:offline, typecheck |