Inspiration

I grew up in a city where the night sky was just… orangeish. I'd seen photos of the Milky Way and assumed they were taken somewhere unreachable until I realized the problem wasn't distance, it was information. Millions of people live within an hour of genuinely dark skies and never know it, because nobody tells them where or when. That's the gap I wanted to close. Not "learn about nature" but get people outside, looking up with one tap. DarkSpot was born from a simple question: "Where can I actually see the stars tonight?"

What it does

How I Built It

I built the whole thing solo: Vite + React 19 + TypeScript with Tailwind, shadcn/ui, and Leaflet for the dark map, and Convex as the backend which lets every third-party call run server-side, so no API keys ever touch the browser. Each spot gets a score from three live factors darkness, clouds, and moon: $$S = 100 - \sum_{i \in A} \frac{w_i}{W_A} \cdot p_i, \qquad W_A = \sum_{i \in A} w_i$$ where $A$ is the set of available factors, $w_i$ are the base weights (darkness 50%, clouds 30%, moon 20%), $W_A$ is their renormalized sum when a factor is missing, and $p_i$ is each factor's penalty (skyglow estimate, cloud cover %, and moon illumination). I also wrote a population-based darkness model that estimates skyglow from surrounding settlements via Overpass no paid light-pollution data needed. And the streak system has a weather shield: if tonight's forecast is over 70% clouds, the streak pauses instead of breaking, because it's not fair to punish users for weather they can't control.

Challenges i ran into

API rate limits -I cached results, scored only the top 5 spots, and used dummy data during dev so hot-reloads didn't burn the free tier Overpass timeouts & 429s -Tight radius, short timeouts, fallback spots, graceful error messages The light-pollution data rabbit hole -Raw satellite rasters are gigabytes I built my own settlement-based skyglow estimate instead Location permission denied -I added full city search (Nominatim) so the app works for anyone Making the map accessible -I enabled Leaflet keyboard navigation, focus rings, and screen-reader announcements

Accomplishments that i'm proud of

Shipped a complete full-stack app, solo, in under 36 hours from a blank page to a live URL that works on any phone, anywhere on Earth. No team, no starter template, no shortcuts on scope. Integrated four live APIs with graceful failure handling Overpass, OpenWeather, USNO, and Nominatim and made the app still work when any one of them goes down. Resilience was a design goal, not an afterthought. Designed an original scoring engine with weight renormalization if a data source is missing, the remaining weights rebalance so every spot still gets a fair score. That's a real algorithmic decision, not a hardcoded number. Built a population-based darkness model from scratch instead of paying for light-pollution data or wrestling gigabyte satellite rasters, I estimated skyglow from surrounding settlements via Overpass. A creative solution to a classic hackathon rabbit hole. Invented the weather-shielded streak a streak mechanic that pauses when tonight's forecast is over 70% clouds. As far as I know, no other streak app can do this, because it requires live per-location weather data. Made it genuinely global the same app scores Nairobi, Tokyo, or Portland, and works in day mode (forecast + countdown) and night mode (live scores). Most demo apps break the moment you leave one city. Prioritized accessibility without being asked keyboard navigation, focus-visible rings, aria-live regions, screen-reader labels, and an alternative city-search flow for users who deny location. Accessibility was part of the product, not a checkbox. Kept it focused I resisted adding accounts, leaderboards, and a dozen features, because the product is one button, one map, one answer. Designing what not to build was as hard as building.

What i learned

This was my first time building a full-stack app with real-world APIs, and I learned more in one weekend than in months of tutorials most of it by failing: Integrating live data is harder than it looks. Four APIs (Overpass, OpenWeather, USNO, Nominatim) each have their own quirks, limits, and failure modes and I had to make all of them fail gracefully. Accessibility is a feature, not a bonus. I added keyboard focus rings, aria-live regions, and screen-reader-friendly labels and learned that good design is accessibility. Renormalization is a lifesaver. When an API is down, a naive score breaks. Weight renormalization keeps every spot fair.

What's next for DARKSPORT FINDER

The engine answers one question how good is the sky at a place, at a moment. Tonight it's stars, next it can score sunrises, auroras, meteor showers, and perfect hiking days. Same spots, same weather data just a different question

Built With

Share this project:

Updates

Submission history