DroughtWatch — Project Writeup


Inspiration

The number that stopped us was 80%. Nearly 80% of rainfed wheat crops in parts of Afghanistan have failed this season due to drought — and the farmers growing that wheat had no warning before it happened. According to the UN's Global Food Crises 2026 report released this week, 17.4 million Afghans are currently facing acute food insecurity, with 4.7 million in emergency or famine-like conditions. Afghanistan is now in its fifth consecutive year of drought.

The frustrating part is that this is not unknowable. NASA satellites are passing over these farms every three days. The soil moisture data exists. The rainfall anomaly data exists. The vegetation health data exists. It just isn't reaching the people who need it, in a form they can act on, fast enough to matter.

We built DroughtWatch because early warning only works if it's early.


What it does

DroughtWatch is a field tool for NGO workers operating in drought-affected agricultural regions. A field worker opens the app, drops a pin on a map at a farmer's location, selects the crop type, and within 20 seconds receives a plain-language drought alert — Normal, Watch, or Act Now — along with a specific set of recommended actions the farmer should take right now.

Under the hood, the alert is built from three real satellite data signals pulled for that exact location:

  • Soil moisture from NASA's SMAP satellite, updated every three days
  • Rainfall anomaly from CHIRPS, comparing current precipitation to the historical norm for that location and time of year
  • Vegetation health from eMODIS NDVI, showing whether crops and pasture are greener or drier than expected seasonally

Each signal is scored against a five-year historical baseline for that coordinate. The combined score produces the overall alert level. The explanation and recommended actions are generated in both English and Dari, so field workers can relay them directly to farmers without translation friction.


How we built it

The backend is built in Python using FastAPI. All three satellite datasets are accessed through a single Python package called ClimateSERV, which is maintained by NASA's SERVIR program and wraps SMAP, CHIRPS, and eMODIS into one consistent API. This was the key architectural decision — instead of integrating three separate data sources with different authentication systems and data formats, we hit one endpoint for all three signals.

The scoring logic is entirely deterministic Python. We compute the percentage of normal for each signal against a five-year historical baseline, classify each signal individually, and combine them into an overall alert level using a set of fixed thresholds. No guesswork — if soil moisture is at 67% of normal, it is in Watch territory, full stop.

The plain-language explanation and recommended actions are generated using the Claude API. We pass it the raw signal scores and crop type, and it returns a two-sentence explanation and three specific actions in both English and Dari. The AI only touches the human-readable output — the alert classification is always driven by the deterministic scoring model.

The frontend is built in React with Vite and Tailwind. A field worker drops a pin on a Leaflet map, selects their crop, and the dashboard displays the three signal gauges, the overall alert banner, the actions panel, and a language toggle between English and Dari. The whole interface is mobile-first, because field workers use phones.


Challenges we ran into

Data latency. ClimateSERV is a powerful tool but it is not fast. Requests regularly take 15 to 20 seconds to resolve, especially when fetching historical baseline data across multiple years. We had to build a skeleton loading state into the dashboard so the wait felt intentional rather than broken, and add a timeout handler so a slow response didn't silently hang the app.

Historical baseline construction. Knowing that soil moisture is 0.18 m³/m³ means nothing without context. Building the five-year seasonal baseline — fetching the same 90-day calendar window for each of the past five years and computing the mean — required more API calls than we initially planned for, and coordinating that across three signals added real complexity.

Dari rendering. Right-to-left text in a left-to-right interface requires careful handling. Getting the Dari output from the language toggle to render correctly without breaking the surrounding layout took longer than expected.

Scoping under time pressure. We had a long list of things we wanted to build — push notifications, multi-farm tracking, offline PWA support, SMS delivery for feature phones. Deciding what to cut and what to protect was the hardest ongoing decision of the build.


Accomplishments that we're proud of

Every number in our demo is real. The soil moisture reading for the Kabul region farmland we used in our demo came from an actual NASA satellite pass within the last three days. The rainfall anomaly reflects what has actually fallen — or not fallen — in that location this season relative to the past five years. We did not hardcode a single data point in the alert output.

We are also proud of the Dari support. It would have been easy to ship English only and call it a demo. But a tool for Afghan farmers that only works in English is not actually a tool for Afghan farmers. Getting the translation pipeline working and the RTL rendering correct felt like the right call to hold firm on.


What we learned

The gap between data existing and data being useful is enormous. NASA has been collecting soil moisture readings over Afghanistan for years. CHIRPS has rainfall anomaly data going back decades. None of it was reaching a subsistence wheat farmer in Faryab province with three days notice before his planting window closed. The engineering problem we solved was not collecting new data — it was making existing data legible and actionable at the right moment.

We also learned that deterministic scoring and language generation are better kept strictly separate. Early in the build we considered having the language model interpret the raw satellite values directly. We pulled back from that because it introduced variability into the alert classification — the same soil moisture reading would sometimes get called Watch and sometimes Normal depending on how the model reasoned about it. Separating the scoring logic entirely from the language layer made the system trustworthy in a way that matters when the output is telling a farmer whether to abandon a planting cycle.


What's next for DroughtWatch

Broader regional coverage. The current build covers Afghanistan and Central Asia using the eMODIS NDVI dataset. Expanding to the Sahel — Mali, Niger, Chad, Burkina Faso — requires switching to the eMODIS West Africa dataset, which ClimateSERV also supports. That is a configuration change, not a rebuild.

SMS delivery. Most subsistence farmers do not have smartphones. A version of the alert that an NGO field worker can forward as a plain text SMS — in Dari or local language — would dramatically extend the reach of the tool without requiring any infrastructure change at the farmer level.

Offline mode. Field workers in remote areas often have intermittent connectivity. A cached version of the most recent alert for a saved set of farm locations, viewable without a network connection, would make the tool usable in the places that need it most.

Integration with WFP and FEWS NET aid programs. The Act Now alert currently links to general aid program pages. A direct referral path — pre-filled with the location and alert context — into WFP's registration system would close the loop between early warning and emergency response.

Built With

Share this project:

Updates