How boikzdev/school-bus-tracker works
1. Repository shape
This is a pnpm TypeScript monorepo with clear separation between deployable apps and shared libraries. The root config (pnpm-workspace.yaml, tsconfig.base.json) is the main coordination layer for builds, type sharing, and dependency management.
2. Top-level runtime boundaries
There are three main application surfaces under artifacts/:
- api-server: an Express backend service
- bus-tracker: an Expo/React Native client for mobile and web
- mockup-sandbox: a Vite-based UI prototype environment
These are intentionally isolated so they can be deployed and evolved independently.
3. Contract-first API layer
The lib/api-spec package holds the OpenAPI source of truth. From that spec, the repo generates:
- lib/api-zod: runtime validation schemas
- lib/api-client-react: typed React Query client/hooks
This creates a strict boundary between backend and frontend: the API contract is defined once, then projected into both server validation and client consumption.
4. Backend service architecture
artifacts/api-server is a small Express app with a conventional split:
- src/index.ts boots the server
- src/app.ts wires middleware and routes
- src/routes/index.ts centralizes route registration
- src/routes/health.ts provides a liveness endpoint
The backend is designed as a REST layer over the domain, with /api-style routes and a build pipeline (build.ts) for production bundling.
5. Data persistence boundary
Shared database concerns live in lib/db, which is organized around Drizzle ORM and PostgreSQL schema definitions. This keeps schema and database access logic outside the deployable apps, so both the API server and any future services can reuse the same table definitions and connection conventions.
6. Mobile/web client architecture
artifacts/bus-tracker is an Expo app using file-based routing under app/. The key runtime entrypoints are:
- app/_layout.tsx for global composition
- app/(tabs)/_layout.tsx and app/(tabs)/index.tsx for the main tracking experience
- app/+not-found.tsx for routing fallback
This is the primary user-facing surface for live tracking.
7. Realtime location and UI state flow
The central client-side state boundary is context/BusContext.tsx. It appears to aggregate:
- Firebase Realtime Database bus updates
- selected bus state
- user geolocation
- derived values like distance and ETA
This context feeds the rest of the UI, so the app’s visual state is driven by a single realtime data layer rather than many disconnected fetches.
8. Client-side feature composition
The bus tracker UI is decomposed into focused components:
- BusSelector for route/bus selection
- DashboardCard for metrics like distance and ETA
- ArrivingAlert for threshold-based notifications
- ErrorBoundary / ErrorFallback for resilient rendering
That makes the screen architecture event-driven: live data arrives, context updates, the dashboard/map/alert react to it.
9. Platform-specific map boundary
Mapping is abstracted through MapWrapper.tsx plus MapWrapper.web.tsx. That is the key cross-platform seam:
- native iOS/Android can use native map rendering
- web uses a different implementation behind the same interface
This keeps the main screen logic platform-agnostic while allowing different map providers or rendering strategies.
10. External realtime services
Firebase is the most important external integration in the client. It is used for live bus location data, which enables the app’s “real-time” behavior without polling-heavy APIs. The README also indicates Google Maps support for map rendering, which is another major external dependency shaping the client architecture.
11. Prototype and design system sandbox
artifacts/mockup-sandbox is a separate Vite app used for interface exploration and component previewing. Its large components/ui set indicates a design-system-heavy workflow, likely for composing and validating screens before they are copied into the production app.
12. Shared tooling and build model
The repo also includes scripts/ for small TypeScript utilities and monorepo maintenance. Across the whole codebase, the main architectural constraint is consistency: TypeScript project references, generated API artifacts, and workspace-managed packages keep the server, client, and shared libs aligned.
13. How the pieces fit together
The clearest end-to-end flow is:
- bus location updates originate in Firebase
- bus-tracker subscribes through BusContext
- derived distance/ETA/arrival state drives map, dashboard, and alert UI
- backend REST APIs in api-server expose broader application operations
- shared OpenAPI/Zod/client packages keep the API boundary type-safe
In diagram terms, the repo is best modeled as a monorepo with one realtime client path, one REST backend path, and a shared contract/data layer between them.
Main entry points: pnpm-workspace.yaml pnpm workspace · BusContext.tsx Bus context · api-server API server · tsconfig.base.json TS base
Components 20
Workspace
Monorepo coordination and shared TypeScript configuration.
- pnpm workspace · Workspace package orchestration and dependency graph.
pnpm-workspace.yaml - TS base · Shared TypeScript compiler settings for all packages.
tsconfig.base.json
Apps
Deployable runtimes and user-facing surfaces.
- API server · Deployable REST backend for application operations.
artifacts/api-server - Server boot · Starts the Express process and wires the app.
artifacts/api-server/src/index.ts - App wiring · Registers middleware and mounts routes.
artifacts/api-server/src/app.ts - Routes · Central route registration for the backend API.
artifacts/api-server/src/routes/index.ts - Health · Simple readiness and health check route.
artifacts/api-server/src/routes/health.ts - Bus tracker · Primary mobile/web client for live tracking.
artifacts/bus-tracker - App layout · Global composition for the Expo router tree.
artifacts/bus-tracker/app/_layout.tsx - Main tabs · Tabbed tracking experience and its screen shell.
artifacts/bus-tracker/app/(tabs)/index.tsx - Bus context · Aggregates Firebase updates, selection, geolocation, and derived ETA state.
artifacts/bus-tracker/context/BusContext.tsx - Map wrapper · Cross-platform seam for native and web map rendering.
artifacts/bus-tracker/components/MapWrapper.tsx - Firebase · External live location data source for bus tracking.
artifacts/bus-tracker/config/firebase.ts - Sandbox · Separate UI prototype and component preview environment.
artifacts/mockup-sandbox - UI kit · Large reusable component set for mockup and design exploration.
artifacts/mockup-sandbox/src/components/ui
Shared libs
Contract, client, and database packages reused across apps.
- API spec · Contract source of truth for backend and generated clients.
lib/api-spec/openapi.yaml - Zod API · Runtime validation schemas generated from the API contract.
lib/api-zod/src/generated/api.ts - React client · Typed React Query client and hooks generated from the API contract.
lib/api-client-react/src/generated/api.ts - DB lib · Shared database schema and connection conventions.
lib/db/src/schema/index.ts
Tooling
Repo-level scripts and maintenance utilities.
- Scripts · Small maintenance and helper scripts for the monorepo.
scripts/src/hello.ts
Connections 25
- pnpm workspace → API server: manages · Workspace includes the API server package.
- pnpm workspace → Bus tracker: manages · Workspace includes the Expo client package.
- pnpm workspace → Sandbox: manages · Workspace includes the prototype app package.
- pnpm workspace → API spec: manages · Workspace includes shared contract packages.
- pnpm workspace → Zod API: manages · Workspace includes generated schema package.
- pnpm workspace → React client: manages · Workspace includes generated client package.
- pnpm workspace → DB lib: manages · Workspace includes shared database package.
- TS base → API server: configures · Shared compiler settings apply to the backend.
- TS base → Bus tracker: configures · Shared compiler settings apply to the client.
- TS base → Sandbox: configures · Shared compiler settings apply to the sandbox.
- API server → Server boot: boots · Server runtime starts from the entrypoint.
- Server boot → App wiring: initializes · Entrypoint constructs the Express app.
- App wiring → Routes: mounts · Application wiring attaches the route registry.
- Routes → Health: includes · Route registry includes the health endpoint.
- Bus tracker → App layout: routes · Expo app composition begins at the root layout.
- App layout → Main tabs: hosts · Layout contains the main tabbed experience.
- Main tabs → Bus context: consumes · Main screen is driven by shared realtime state.
- Bus context → Firebase: subscribes · Context pulls live bus updates from Firebase.
- Bus context → Map wrapper: feeds · Derived state drives the map layer.
- Bus context → React client: may use · Client can consume typed backend operations through generated hooks.
- API spec → Zod API: generates · OpenAPI source generates runtime validation schemas.
- API spec → React client: generates · OpenAPI source generates the typed React client.
- DB lib → API server: shared by · Backend can reuse the shared database schema layer.
- Sandbox → UI kit: composes · Sandbox renders from a large reusable UI component set.
- Scripts → pnpm workspace: supports · Repository utilities operate within the workspace model.