Satellite Field Mapping App
A React Native app I built from scratch for field officers to map farm boundaries from satellite imagery and record them on the Cardano blockchain. Used by 300+ officers in the field.

I built this React Native (Expo) app from scratch for a precision agriculture company. Field officers use it to walk a farm, trace its boundary on a live map, pull AI-detected boundaries from satellite data, score the land's sustainability, and write the final record to the Cardano blockchain. It has to run on low-end Android phones over patchy rural networks. The codebase is about 12,000 lines of TypeScript, and more than 300 officers use it, with over 1,000 records written on-chain during the pilot.
Client state lives in Zustand and server state in TanStack Query, so farmer lists and other data stay cached and usable when the signal drops.
Highlights
Keeping the map fast. Drawing a 5 km radius of satellite polygons froze the JavaScript thread on mid-range phones. I used Turf.js to check whether the camera had panned outside the area already loaded, and only refetched when it had, this time with a tighter 1-2 km radius. That kept the map smooth and memory low.
// Only refetch satellite boundaries once the camera leaves the loaded area,
// then use a tighter 2km radius to keep the JS thread responsive.
const alreadyCovered = isInsideBBox(
{ latitude: mapRegion.latitude, longitude: mapRegion.longitude },
dfConfig.center,
dfGeoJSON?.metadata?.side_km ?? 5,
);
if (!alreadyCovered) {
setDfConfig({ center: mapRegion, sideKm: 2, ready: true });
}
Recording to the blockchain. When a boundary is final, the app runs a short flow (save, mint, anchor, confirm) and polls the backend until the transaction is confirmed on-chain, then reads back the IPFS hash and the transaction id.
Cross-app login. Officers sign in through a company portal that hands the app a one-time code over a deep link. I handle that at the root of the app behind a guard flag, so a cold start, a background resume, and a new login never race each other.
Working offline. A banner appears when the network drops, queries are cached, and logout cancels in-flight requests first, so a cleared token never sets off a wave of 401s.
Sustainability scoring. A custom animated gauge shows the satellite-derived sustainability index for a boundary once it's scored, with nullable-safe parsing and a graceful fallback when the index isn't available yet.
Onboarding on shared devices. A multi-slide first-launch tour walks new officers through the app. Since several officers can share one device in the field, "seen" state is tracked per user rather than per install, so the tour doesn't replay for someone who's already seen it.
Reach. Separate Expo build profiles let staging and production installs sit on one phone, and the app is translated into English, Hindi, and Marathi.
What I took from it
The hard part of a field app is the edge: weak networks, slow phones, and dirty data. Caching and sizing the work to the situation mattered more than any single feature. I also learned to keep keys and blockchain complexity on the server, and let the app drive the workflow and show progress. As the app grew, I moved the codebase to a feature-based modular structure so it stayed easy to work in solo, and shipped it through several milestone releases (v1.0 through a stable v1.3.5 to v1.4.0) without ever having a second mobile developer to hand work off to.