Architecture
Tech Stack
Full reference for every technology in the platform, with version and rationale. This document reflects the actual versions installed — verify against package.json files for patches.
Frontend#
| Layer | Technology | Version | Why |
|---|---|---|---|
| Framework | Next.js | 16.1.5 | App Router, React Server Components, file-based routing, edge middleware. |
| UI library | React | 19.2.0 | Function components, concurrent features, Server/Client composition. |
| Language | TypeScript | 5.9.2 | Strict mode throughout. Discriminated unions for domain concepts. |
| Styling | Tailwind CSS | 4.1.x | v4 with CSS @theme tokens. No separate config file — tokens live in globals.css. |
| Data fetching | SWR | 2.3.4 | Stale-while-revalidate pattern; shared config via @repo/swr-config. |
| Auth (client) | Clerk (@clerk/nextjs) | latest | Organizations = multi-tenancy. JWT session claims carry permissions for edge-side checks. |
| Animations | Motion | 12.x | Declarative animation for UI transitions. |
| Icons | Lucide React | 0.574.0 | Consistent, tree-shakeable icon set. |
| Validation (client) | Zod | 3.25.x | Runtime schema validation. Shared schemas between client and API via @repo/validation. |
Design system#
The design system lives entirely in shared/brand and shared/ui. All color tokens are defined as CSS variables in shared/brand/src/styles/globals.css via the Tailwind v4 @theme directive and automatically become Tailwind utilities. Key design tokens:
| Token | CSS variable | Value (light) |
|---|---|---|
| Primary green | --color-primary | #11d452 |
| Background | --color-background | #f8fafc |
| Surface | --color-surface | #ffffff |
| Text primary | --color-text-primary | #0f172a |
| Text secondary | --color-text-secondary | #475569 |
| Shell panel | --color-shell-panel | rgba(255 255 255 / 0.86) |
Utility class sets available from brand globals: card-base, card-interactive, glass-card, shell-panel, brand-container, btn-primary, and badge variants.
Backend#
| Layer | Technology | Version | Why |
|---|---|---|---|
| API framework | Hono.js | 4.11.9 | Built for edge runtimes (Cloudflare Workers). TypeScript-first, lightweight, Zod validator built in. |
| Runtime | Cloudflare Workers | V8 isolates | Serverless edge — zero cold start, 275+ global locations, $0 dev tier. |
| Database | Neon PostgreSQL | pg 16 | Serverless, HTTP-compatible, PostGIS for geospatial, branching per environment. |
| ORM | Drizzle ORM | 0.45.2 | Type-safe queries, schema-as-code, migration files checked into git. |
| Validation (API) | @hono/zod-validator | latest | Every route validated against a Zod schema; 422 on failure. |
| JWT | jose | 6.2.2 | Edge-compatible JWT verification (no Node.js crypto required). |
| File storage | Cloudflare R2 | S3-compatible | Evidence files, survey photos, farm map exports. No egress fees. |
Cost model#
| Phase | Monthly cost | Notes |
|---|---|---|
| Development | $0 | Wrangler local dev + Neon free tier (3 GB) + Cloudflare Pages free. |
| MVP | $0–15 | Workers 100k req/day free. Neon free → Pro at scale. |
| Production | ~$50 | Workers $5 + Neon Pro $19 + R2 $5 + Cloudflare Pro $20 + domain $1. |
| Enterprise | $100–200 | Higher compute, dedicated Neon, enterprise Cloudflare features. |
Build tooling#
| Tool | Version | Role |
|---|---|---|
| Turborepo | 2.7.3 | Monorepo task orchestration — parallel builds, remote caching. |
| npm workspaces | npm 11.x | Package linking and install hoisting. |
| Vitest | 3.2.4 | Unit and integration tests across all packages. |
| ESLint | 9.39.1 | v9 flat config via @repo/eslint-config. --max-warnings 0 enforced. |
| Prettier | 3.7.4 | Formatting. Run with npm run format. |
| Wrangler | 4.x | Cloudflare Workers local dev and deployment CLI. |
| tsup | latest | Bundler for shared/* packages. |
Mobile (Phase 1)#
The mobile app for field data capture (farmer enrollment, GPS polygon walk, offline surveys) is a separate Flutter project. It is not in this repository.
| Layer | Technology | Notes |
|---|---|---|
| Framework | Flutter 3.x | Single codebase for Android. |
| State | Riverpod | DI + reactive state. |
| Local DB | SQLite + Drift | Offline-first field storage. |
| Maps | flutter_map + OpenStreetMap | Free, no Mapbox license required. |
| Sync | Custom (batch, configurable interval) | Default 4-hour batch sync to Workers API. |
Geospatial processing#
All geospatial operations run in PostgreSQL via the PostGIS extension. No external geospatial service is used for polygon storage or area calculation.
-- Area in hectares
SELECT ST_Area(ST_Transform(polygon_geom, 3857)) / 10000 AS area_ha
FROM plots;
-- Deforestation check — polygon intersects forest boundary after cutoff
SELECT p.id, ST_Intersects(p.polygon_geom, fr.boundary)
FROM plots p, forest_reference fr
WHERE fr.recorded_after = '2020-12-31';
-- All coordinates stored as WGS84 (EPSG:4326)
SELECT ST_AsGeoJSON(polygon_geom) FROM plots LIMIT 1;ProviderAdapter interface in @repo/feature-deforestation-risk, making it swappable without changing the risk assessment service.