Technology research¶
Status: desk research, October 2026. Nothing here is validated by running code yet. Decisions live in the ADRs; this page records the reasoning and the evidence still needed.
Constraints that drive the stack¶
- Target devices: low-to-mid Android phones (2–4 GB RAM), patchy connectivity, expensive data. iOS is secondary at first.
- Funding: the app is free forever — hosting and inference must be cheap. Every watt and megabyte matters.
- Contributors: an open-source project of volunteers and students; the stack must be learnable and the toolchain approachable.
- AI/ML: Python ecosystem is unavoidable for model work; mobile inference needs a compact runtime.
- Trust: memory-safe, auditable core for a system that holds sensitive community data.
- Longevity: this is meant to last decades; prefer boring, well-supported foundations for the data layer.
Mobile client¶
| Option | For | Against |
|---|---|---|
| Flutter (Dart) | Single codebase Android/iOS/(web/desktop); own renderer gives consistent UI; strong plugin ecosystem for camera, audio, SQLite, TFLite/LiteRT; large community | Self-rendered UI adds binary size/memory (no measured data for low-end phones); Dart is a niche language outside Flutter |
| React Native (TypeScript) | Huge JS/TS contributor pool; native components; share code with the Next.js web app | Bridge/JS overhead on weak devices (improved by the new architecture); native-module churn |
| Kotlin Multiplatform + Compose | Native performance, shared logic, first-class Android; good fit for on-device ML | Smaller community; iOS UI maturity; fewer volunteers know it |
| Native Android only | Best performance and size | Excludes iOS; halves contributor leverage |
| PWA | Zero install, instant updates | Weak offline/camera/background capabilities; poor discoverability on Play Store |
Directional sources: KMP 2026 overview, React Native vs Flutter 2026, framework survey. These are vendor-flavoured; none tested budget Android or South African conditions.
Working choice: Flutter, conditional on a benchmark spike (cold start, RAM, APK size, camera + on-device inference latency) on at least two Android Go–class devices vs a minimal Kotlin baseline. If Flutter fails the spike, fall back to Kotlin Multiplatform. → ADR-0004
Backend core¶
| Option | Notes |
|---|---|
| Rust (axum + sqlx) | Small memory footprint and high throughput → cheap hosting; memory safety for sensitive data; excellent type system for modelling consent rules. Steeper learning curve, smaller contributor pool. |
| Go | Simple, fast, easy to learn, great ops story. Weaker type-level modelling. |
| TypeScript (Node/Bun) | Largest pool; share types with web. Higher memory, weaker guarantees. |
| Python (FastAPI) | Fastest to prototype; shares language with ML. Slower, heavier. |
Working choice: Rust for the API/sync core, with the explicit trade-off of a smaller contributor pool. Mitigated by keeping the core small, well documented, and by letting contributors work in Python, TypeScript and Dart for most features. → ADR-0005
Intelligence layer¶
- Python for agents, retrieval, evaluation, speech and vision pipelines.
- Provider-agnostic model gateway: frontier hosted models for hard reasoning where records permit; open-weight models for low-resource-language tasks and privacy-sensitive paths; tiny on-device models for the camera.
- Retrieval-augmented generation over the consented knowledge base with mandatory citations; no free-form generation of cultural claims.
- Evaluation harness as a first-class component.
→ ADR-0006
Data layer¶
- PostgreSQL (+ PostGIS for locations and range/blurring, + pgvector for semantic search). One boring, reliable database beats a zoo.
- SQLite on device, synced to the server (offline-first). → ADR-0007
- S3-compatible object storage for images and audio (with signed URLs, tiered access).
- Append-only provenance/audit log so every change is attributable and reversible.
Web¶
- TypeScript + Next.js for public discovery pages (SEO matters: people search for "umhlonyane uses"), curator dashboards and admin. → ADR-0003
Shared contracts¶
- OpenAPI for the REST API, JSON Schema for the knowledge model, code-generated clients for Dart, TypeScript and Python. One schema, three languages, zero drift.
Infra and ops¶
- Containers (Docker) and a simple deploy target first; avoid premature Kubernetes.
- Infrastructure as code (OpenTofu) once more than one environment exists.
- Observability: OpenTelemetry from day one.
- Host in or near South Africa for latency and data-residency comfort (POPIA considerations). Provider TBD.
Spikes required before Phase 1 begins¶
- Mobile benchmark — Flutter vs Kotlin baseline on low-end Android.
- Plant-ID accuracy — candidate APIs and models against a South African test set.
- On-device model — smallest acceptable model size/latency/accuracy.
- Sync prototype — two devices, intermittent connectivity, conflict scenarios.
- Speech baseline — ASR quality for at least isiZulu and Tshivenda.
Each spike gets an issue and a short write-up in docs/research/spikes/.