The Planet Writes You a Personal Letter Using Real Climate Data + Gemini AI
This is a submission for Weekend Challenge: Earth Day Edition
What I Built
Earth's Last Letter is an AI-powered web app where Earth β the planet itself, 4.5 billion years old β writes you a deeply personal, poetic letter based on the city you grew up in and the year you were born.
You enter two things: your city and your birth year.
Earth remembers the rest.
Every letter is completely unique. The app pulls real historical COβ data from NOAA's Mauna Loa Observatory measurements, your exact city coordinates via Open-Meteo's geocoding API, and feeds all of it into a carefully engineered Google Gemini prompt that generates a 400-word letter written from Earth's perspective β not as a scientist, not as an activist, but as a grieving mother writing to a child she loves.
The letter tells you:
- What your city's air smelled like the season you were born (COβ was measurably lower)
- What Earth remembers about your childhood years in that specific place
- One specific change happening near your city right now β not generic warming stats, but Mumbai's retreating monsoon patterns, London's disappearing frost days, Delhi's unprecedented heat islands
- What your city might feel like in 2050 if the trajectory holds
- One intimate, local action only someone from your city could take
It does not say "reduce your carbon footprint." It does not say "go green." It sounds like a letter left under a stone in a forest.
Here's a sample output for Mumbai, 1995:
Dear child of 1995,
You arrived in Mumbai during the first weeks of June, when the southwest monsoon was still two weeks away and the city held its breath in that particular amber heat only those who know her understand. The air carried 360 parts per million of carbon then β still too much, but enough that the Arabian Sea breeze coming off Marine Drive in the evenings felt clean in a way you may not remember but your lungs do...
...But I am still here. And so are you.
With all the time I have left,
Earth
The UI is built to match β dark navy background, aged parchment letter card, typewriter reveal animation, city postmark stamp, and rotating loading messages ("Earth is remembering your city...", "Searching through 4.5 billion years of memory...").
One click copies the letter. One click shares to X. Every interaction feels like touching something ancient.
Demo
π Live App β earths-last-letter.netlify.app
Try it with:
- Mumbai + 1995 β monsoon memories, Arabian Sea heat, coastal flooding
- London + 1988 β disappearing frost days, Thames flooding risk
- Delhi + 1990 β Yamuna river, unprecedented heat island, air quality history
- New York + 2000 β hurricane patterns, Hudson River, coastal erosion
π You'll need a free Gemini API key from aistudio.google.com β takes 30 seconds to get.
Code
π Earth's Last Letter
"The planet writes you a personal letter β from your birth year to 2050."
What Is This?
Earth's Last Letter is an AI-powered web app where Earth β the planet itself β writes you a deeply personal, poetic letter based on the year you were born and the city you grew up in.
Every letter is unique. Every letter is grounded in real climate data. Every letter is written as if Earth is an ailing parent writing to a child it loves but is slowly losing the strength to sustain.
You enter your city and birth year. Earth remembers the rest.
β¨ Features
- πΏ Hyper-personalized letters β Every output is unique to your exact city + birth year combination. No two letters are the same.
- π Real climate data β COβ levels at your birth year (Mauna Loa historical data), current COβ levels, temperature anomalyβ¦
The full repo includes:
- Complete React + Vite frontend
- Gemini API integration with structured prompt
- Open-Meteo geocoding and climate data
- Vercel deployment config
How I Built It
The Core Insight β Why This Approach
Every climate app I've seen shows you graphs. Numbers. Percentages. The problem isn't that people don't have information β it's that information doesn't move people. Stories do.
I wanted to build something that made climate data feel personal rather than abstract. The insight was simple: if you know exactly what the COβ level was the year someone was born, you can tell them something true and specific about how the air has changed in their own lifetime. That's not a statistic. That's their life.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React + Vite |
| Styling | Tailwind CSS |
| AI Generation | Google Gemini 2.0 Flash |
| Climate Data | Open-Meteo API (free) |
| COβ Data | NOAA Mauna Loa historical readings |
| Geocoding | Open-Meteo Geocoding API |
| Deployment | Vercel |
Step 1 β Getting Real Data
I pull two real data sources before touching Gemini at all:
City coordinates via Open-Meteo's free geocoding API:
const res = await fetch(
`https://geocoding-api.open-meteo.com/v1/search?name=${city}&count=1`
);
const data = await res.json();
const { latitude, longitude, name, country } = data.results[0];
Historical COβ levels from NOAA's Mauna Loa Observatory measurements, hardcoded from real published data:
const co2Map = {
1950:310, 1955:313, 1960:317, 1965:320, 1970:325,
1975:331, 1980:338, 1985:345, 1990:354, 1995:360,
2000:369, 2005:379, 2010:389, 2015:400, 2020:412,
2024:422, 2025:424
};
const birthCO2 = co2Map[Math.round(birthYear / 5) * 5];
const co2Rise = 424 - birthCO2;
For someone born in 1995 in Mumbai, the app now knows:
- COβ at birth: 360 ppm
- COβ today: 424 ppm
- Rise in their lifetime: +64 ppm
That's real data. That goes into the prompt.
Step 2 β The Gemini Prompt (the hard part)
This is where most of the work is. Getting Gemini to write something that sounds like literature rather than an AI response required a very specific prompt structure.
The key decisions I made:
1. Strict paragraph structure with word counts
Instead of asking for "a letter," I specify exactly 6 paragraphs with word counts for each (60, 70, 80, 70, 60, 40 words). This produces consistent, well-paced output every time.
2. Banned vocabulary list
The prompt explicitly forbids: "carbon footprint", "going green", "save the planet", "climate change" (as a phrase), "sustainability". These words have been so overused in environmental messaging that they've become invisible. Banning them forces Gemini to find fresh, sensory language.
3. City-specific climate instructions
The prompt tells Gemini to reference ONE specific local phenomenon based on the city type β glaciers if mountain, sea level if coastal, heat island if major metro, monsoon patterns if South Asian city. This makes every letter feel locally grounded.
4. Voice constraint β the most important one
YOUR VOICE: You are not angry. You are not lecturing.
You are a mother watching her child grow up while she grows sick.
Ancient patience, deep love, quiet grief.
This single voice instruction transforms the output from an environmental essay into something that reads like correspondence.
Here's the Gemini API call:
const response = await fetch(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${apiKey}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
contents: [{ parts: [{ text: prompt }] }]
})
}
);
const letter = data.candidates[0].content.parts[0].text;
Step 3 β The UI
The design is intentionally counter to modern app aesthetics. While everyone builds clean, minimal, light-mode dashboards, this app goes dark, ancient, and warm.
The parchment card uses a warm cream background (#f5f0e8), dark brown text (#2c1810), Georgia serif font at 1.9 line height, and subtle box-shadow to create a paper texture without any actual images.
The typewriter animation reveals the letter character by character. This was a deliberate choice β it forces users to read rather than skim, and creates the feeling that Earth is writing to you in real time.
Loading states rotate through 4 messages every 2 seconds:
- "Earth is remembering your city..."
- "Searching through 4.5 billion years of memory..."
- "Weaving real climate data into your letter..."
- "Almost ready β Earth writes slowly, carefully..."
These aren't just UX filler. They're part of the narrative.
What I Learned
The biggest lesson: prompt engineering is product design. The quality of the letter is entirely a function of how precisely I constrained Gemini's output. Every word count, every banned phrase, every voice instruction translates directly into a better user experience. The AI isn't doing creative work β it's executing a very specific creative brief.
The second lesson: real data beats fake data every time. Knowing that someone born in 1990 breathed air with 354 ppm COβ β and that we're at 424 ppm today β makes the letter hit differently than if I'd just prompted Gemini to "say something emotional about climate change." The specificity is what creates the emotional resonance.
Prize Categories
π Best Use of Google Gemini
Google Gemini 2.0 Flash is the core of this project β not as a chatbot, but as a structured narrative engine. The app feeds real API data (city coordinates, historical COβ levels, climate context) into a precisely engineered prompt that produces a consistently high-quality, emotionally grounded 400-word letter every single time.
The innovation isn't just using Gemini β it's the architecture around it: real data in β structured prompt β constrained creative output β literature-quality result. This is a meaningfully different use case than most AI integrations, which treat language models as question-answering systems. Here, Gemini is a writer following a very specific brief.
The prompt includes:
- Paragraph-level word count constraints
- Banned vocabulary list (forces fresh language)
- City-specific climate instruction rules
- Strict voice and tone specification
- Mandatory real data integration in every paragraph
The result is that the app produces output that users genuinely share, screenshot, and send to family members β which is the real test of whether an AI generation is working.
Built over one weekend for Earth Day 2026. Every letter is different. Every letter is true.
Try yours at https://earth-last-letter.netlify.app/
Top comments (0)