Inspiration
I have hundreds of NYC places saved across TikTok and Google Maps. The other day a friend looked at my saved list and asked, "Eva, how many of these have you actually been to?" When I thought about it, the honest answer was: not many.
I realized two things were stopping me. The first is decision fatigue. When friends ask for a recommendation, or I suddenly have a free afternoon, I open a messy, disorganized saved folder and freeze. The second is that planning an efficient day in NYC is hard. I'm a spontaneous person, and a free afternoon can easily get eaten up just figuring out a route that fits my time and where I already am. Every New Yorker knows the pain of going uptown, then downtown, then back again.
RoamNYC takes the deciding off your plate. It also pushes you toward places you never would have thought to go.
What it does
You tell RoamNYC how you're feeling and how much time you have, and it hands you a ready-to-go plan:
- Mood, time, budget, and group: pick Chill, Adventurous, Social, or Creative; set your hours; choose Free, $, or $$; and say whether you're solo, on a date, with friends, or with kids
- Step-free option: plans only include wheelchair-accessible stops and stations with elevators
- Starts where you are: uses your location (with permission) so you're not crossing the city for no reason
- Reads the weather: drizzle means cozy indoor spots; a nice day means parks and views
- Finds what's happening today: searches the live web for real events and weaves them into your plan with links
- Checks that places are still open: every stop is verified against the live web, and closed places are swapped out for open backups
- Map and stop cards: numbered stops, a walking route, times, reasons, and one-tap transit directions
- Take me off route: adds a surprise hidden gem near your plan, also fact-checked before you see it
How I built it
- Backend: Python and Flask
- AI planning: Google Gemini API, returning structured JSON plans, with automatic fallback across four Gemini models when one is overloaded or rate-limited
- Live web data: Tavily for today's events, hidden-gem research, and checking whether each suggested place is still open (run in parallel so it stays fast)
- Weather: Open-Meteo
- Map: Leaflet with OpenStreetMap
- Frontend: hand-built HTML, CSS, and JavaScript, designed from a Figma AI mockup
- Deployment: DigitalOcean App Platform, auto-deploying from GitHub
- Read my plan aloud with ElevenLabs
Coming from a cybersecurity background, I built security in from the start:
- API keys live in environment variables and never touch the repo
- User choices are checked against allowlists before reaching the AI prompt, so no one can inject their own instructions
- AI-generated text is escaped before it's shown on the page, blocking XSS that could come from a poisoned web search result
- Location is rounded to about a city block before leaving the browser, only used if it's inside NYC, and never stored
- External links open with
noopener noreferrer
Challenges I ran into
- Pivoting at 3 PM. I started the day on a different project and switched to this idea mid-afternoon, so everything here was built in under a day.
- AI that's confidently wrong. Gemini recommended a museum that was closed for the evening, then a place that had closed permanently. Prompt tweaks couldn't fix outdated knowledge, so I added live fact-checking with Tavily and backup stops.
- Model availability. My first model was retired for new users, then its replacement kept returning "high demand" errors. I built a fallback chain that automatically moves to the next model.
- Free-tier rate limits during rapid testing, which the same fallback system now absorbs.
Accomplishments that I'm proud of
- Going from a blank repo to a live, deployed app in one evening
- Plans that respond to five live signals at once: mood, location, weather, today's events, and whether places are actually open
- A design that feels like a real product, on both phone and desktop
- Accessibility and budget options that make "things to do in NYC" work for more people (especially students like myself)
What I learned
- How to ground an AI's suggestions in live data instead of trusting it blindly
- How to build resilient apps around external APIs that can fail at any moment
- That good loading states make a few seconds of waiting feel intentional
- Practical, end-to-end deployment with secrets handled properly
What's next for RoamNYC
- Your saved places, finally used: import Google Maps saved lists (via Google Takeout) so plans pull from places you already want to visit, parsed in your browser for privacy
- TikTok and Instagram: paste a link to a saved post and RoamNYC pulls out the place
- NYC bingo card of neighborhood challenges
- Swap a single stop you're not feeling
- More precise pins by geocoding each place's real address
Built With
- css3
- digitalocean
- figma
- flask
- gemini
- github
- google-gemini-api
- gunicorn
- html5
- javascript
- leaflet.js
- open-meteo
- openstreetmap
- python
- tavily
Log in or sign up for Devpost to join the conversation.