AWS Builder Center
🌬️ A Runner and a Park Bench Breathe the Same Air, But Not the Same Dose: How We Built AirSafe on AWS

🌬️ A Runner and a Park Bench Breathe the Same Air, But Not the Same Dose: How We Built AirSafe on AWS

Standard weather apps show one AQI for a whole city. AirSafe turns it into a personal exposure score based on what you’re doing and for how long. Here’s how we built it with Terraform, Docker, EC2 and ECR, and what went wrong along the way. 🚀

🌬️ A Runner and a Park Bench Breathe the Same Air, But Not the Same Dose

How our team built AirSafe for the WeMakeDevs × AWS Hackathon 🏆



😮‍💨 The Morning That Started It All

One morning I checked my phone before a run. The air quality app said 152.
And I just stood there. 🤔
Was that bad? Should I skip the run? Walk instead? Wait until evening? The app gave me a number but no decision, and that gap became AirSafe 💡



❌ The Problem: One Number for a Whole City

Weather apps show a single AQI for an entire city. But pollution doesn’t hurt you in the abstract. It hurts you in proportion to how much of it you breathe in.
Picture two people in the same park:
  • 🧘 One is sitting on a bench
  • 🏃 One is running past them
They’re in identical air. But the runner is moving about 3.5× more air through their lungs. A city-wide number can’t capture that, and no standard app tells you:
  • ⏰ When it’s safe to exercise
  • 🛣️ Which route has less pollution
  • 🏫 How schools should handle PE and recess
So we changed the question:

❝ Not “How bad is the air?” but “How much of this air will I actually breathe?” ❞




💡 Our Idea: Exposure as a Dose, Not a Reading

AirSafe pulls live pollutant data (PM2.5, PM10, O₃, NO₂, SO₂, CO) from the OpenWeather Air Pollution API, then does two things.

1️⃣ It calculates AQI the proper way 🧮

We implemented the US EPA piecewise linear interpolation formula for every pollutant. The overall AQI is the highest sub-index, so the dominant pollutant is always visible.

2️⃣ It multiplies by how you move 🏃‍♂️

Every activity gets a ventilation multiplier:
Activity
Multiplier
🧘 Resting
1.0×
🧹 Outdoor chores
1.5×
🚶 Walking / commuting
1.8×
🚴 Cycling
2.8×
⚽ Sports
3.0×
🏃 Running
3.5×
Duration matters too. Here’s the math that surprised even us:
🤯 A 20-minute run = 3.5 × (20 ÷ 60) ≈ 1.17 “bench-hours” of exposure. That’s more than sitting outside for a full hour!
The result is an Exposure Score from 0 to 100, with four tiers: 🟢 Low, 🟡 Moderate, 🟠 High and 🔴 Critical. Each tier comes with a plain-language recommendation.



✨ What AirSafe Can Do

  • 📊 Live Dashboard: real-time AQI, category, dominant pollutant and a full pollutant breakdown
  • 🧮 Exposure Calculator: pick an activity and duration (1–720 min) and get your personal score
  • 🕐 Clean Windows: scans 24-hour and 7-day forecasts to find the safest time to go outside
  • 🗺️ Route Comparison: a direct route vs a lower-exposure “Green Corridor” on an interactive map
  • 📈 Exposure History: track your outdoor hours and average exposure over time
  • 🏫 Campus Safe Mode: turns AQI into instructions for assembly, PE, recess and ventilation
  • 🚨 Emergency Simulation: spikes AQI past 275 and simulates AWS SNS alerts, so you can see the app in a worst-case moment



☁️ How We Built It on AWS

Frontend ⚛️ React 18 + Vite + Tailwind + Recharts + Leaflet Backend 🟢 Node.js + Express Database 🍃 MongoDB Atlas Auth 🔐 Google OAuth 2.0, with server-side token verification and HttpOnly session cookies
The AWS part is where we learned the most 👇

🏗️ Terraform Built Everything

No console clicking. One  terraform apply  provisions:
  • 📦 Amazon ECR repository
  • 🖥️ Amazon EC2 ( t3.micro )
  • 🔑 IAM roles and instance profile
  • 🛡️ Security groups
Everything is reproducible, which is a relief when you’re debugging at 2 AM. 😅

🐳 Docker + ECR + EC2

We built the backend as a multi-stage Docker image (Node 22 Alpine) and pushed it to ECR. The EC2 instance pulls that image and runs it.

🔧 Systems Manager Instead of SSH

We managed the instance through AWS Systems Manager, so no open SSH port was needed.

✅ CI with GitHub Actions

Every push runs the full test suites:
  • 🧪 179 backend tests (Jest + Supertest)
  • 🧪 45 frontend tests (Vitest)
The backend tests mock all network and database calls, so they run completely offline. ✈️



😅 What Went Wrong (The Honest Part)

🔥 CloudFront never happened

We uploaded our static bundle to S3, but the CloudFront distribution was stuck waiting on AWS account verification. With the demo deadline close, we deployed the frontend on Vercel and kept the backend on EC2. [Add one sentence on how that moment felt.]

🔥 Google OAuth needs HTTPS, and our EC2 had none

Cookie-based sessions don’t behave properly over plain HTTP. With limited time, we put a temporary Cloudflare Quick Tunnel in front of the API. It isn’t production-grade (and we say so in the README), but it made the full login flow work end to end. 🙌

🔥 The “Green Corridor” is simulated

We simulate waypoints and exposure differences between two points. Real turn-by-turn re-routing around live pollution hotspots is on the roadmap. We’d rather be upfront than oversell. 🤝



🔮 What’s Next

  • ⌚ Pull breathing rate from Apple HealthKit / Google Health Connect, so the multiplier is yours
  • 📱 Real mobile push alerts through AWS SNS
  • 🧭 True dynamic routing around pollution hotspots
  • 🌐 CloudFront + a proper domain, so the tunnel can retire



🎯 What I Took Away

The biggest lesson wasn’t a service or a framework. It was this:

💬 A number only becomes useful when it’s tied to a person and a decision.

“AQI 152” tells you nothing. 🤷 “Your 30-minute run is Moderate risk, and 7:30 AM tomorrow is cleaner” tells you what to do. ✅



🔗 Try It Yourself

🌍 Live Demo:  https://air-safe-nu.vercel.app  💻 GitHub:  https://github.com/nithing007/AirSafe  📜 License: MIT, so fork it, break it, improve it!
If you build on it or find a bug, open an issue. I’d love to hear from you. 💚
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article