fomo.nyc is a free, community-built interactive map of upcoming events in the NYC area.
It works by visiting the websites of parks, museums, music venues, etc., identifying any upcoming events, and displaying them on a map. My hope is that this becomes a useful resource for people to find events they are interested in and to engage with their local communities.
The codebase is city-agnostic — NYC is just the default deployment. Every city/region/branding specific (map view, timezone, geography, prompt wording, site name, per-platform crawl behavior) lives in config/<FOMO_CITY>.yaml (default config/nyc.yaml) and gitignored pipeline/sources/ plugins, so you can fork it for your own city by editing config rather than engine code.
/src/ Website source files
src/js/JavaScript modules (IIFE pattern, loaded in order)src/css/CSS modules (imported viaindex.css)src/data/Event and location JSON data (generated by pipeline)src/api/PHP API endpointssrc/admin/PHP admin dashboardsrc/images/SVG assetssrc/fonts/Self-hosted MapLibre glyph fonts
/dist/ Build output (not committed)
- Generated by
npm run build(prod) ornpm run dev(dev) - Contains everything needed for the server's
public_html/directory - Uploaded to production via
python scripts/upload_public_html.py
/pipeline/ Python scripts for data processing pipeline
main.pyMain entry point - orchestrates the complete workflowcrawler.pyCrawls websites using Crawl4AI, stores content in databaseextractor.pyUses Gemini AI to extract structured event data- Requires
GEMINI_API_KEYenvironment variable (set in.envfile)
- Requires
processor.pyParses extracted data, enriches with location coordinatesmerger.pyDeduplicates events into final events tableexporter.pyGenerates JSON files for the website (src/data/)uploader.pyUploads data files to FTP serverdb.pyDatabase operations (CRUD for crawl runs, results, events)
/database/ Database schema and setup scripts
schema.sqlComplete database schemasetup.pyCreates empty database tablesmigrate_schema.pyApplies schema changes to existing database/database/backups/Database backup files
The frontend is built with esbuild:
npm run dev # Dev build + watch (unminified, symlinks, stable filenames)
npm run build # Prod build (minified, content-hashed, full asset copies)- JS modules are concatenated in load order and minified (not bundled — they use the IIFE pattern with globals)
- CSS
@importchain is resolved and minified - Flatpickr is installed via npm and bundled into the output
build.jsreadsconfig/<FOMO_CITY>.yamland injects the city config: awindow.__CITY__global (map/timezone) prepended to the JS bundle, plus{{TOKEN}}branding replacement inindex.htmldist/contains the complete deployable output: HTML, JS/CSS bundles, plus copies ofdata/,images/,fonts/,api/,admin/
All data flows through the database (crawl_runs → crawl_results → crawl_events → events):
- Crawl → Query
websitestable for due sites, crawl and store incrawl_results.crawled_content - Extract → Use Gemini AI to extract structured tables, store in
crawl_results.extracted_content - Process → Parse tables, enrich with location data from
locations, store incrawl_events - Detail crawl → Visit individual event URLs to fill in missing descriptions/tags/emoji on
crawl_events - Merge → Deduplicate
crawl_eventsinto finaleventstable - Export → Generate
src/data/*.jsonfromeventstable - Upload → Push JSON files to FTP server
The day-to-day entry point is the /run-pipeline workflow (.claude/commands/run-pipeline.md), which wraps pipeline/main.py with review and fix steps.
npm run build # Build to dist/
python scripts/upload_public_html.py # Upload dist/ to server-
📢 Share with your friends
-
📍 Add events and places you know
-
🫱🏾🫲🏼 Stay in touch
- This website is in active development, so keep visiting for regular updates!
- You can reach out by email or join the Discord server
The project uses a MariaDB/MySQL database to store locations, websites, and crawl data.
New developers should restore from a database backup rather than starting with an empty database:
# 1. Create the database
mysql -u root -e "CREATE DATABASE fomo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"
# 2. Restore from backup
mysql -u root fomo < database/backups/fomo_backup_YYYYMMDD.sql# Windows (XAMPP)
"C:/xampp/mysql/bin/mysqldump.exe" -u root fomo > database/backups/fomo_backup_YYYYMMDD.sql
# Linux/Mac
mysqldump -u root fomo > database/backups/fomo_backup_YYYYMMDD.sqlIf the schema has changed since your backup, run migrations:
python database/migrate_schema.py- 🧭 Map library: MapLibre GL JS
- 🗺️ Map tiles: © Protomaps, © OpenStreetMap contributors
- 📅 Date picker: Flatpickr
- 🔠 Fonts: Inter, Noto Color Emoji
- 🚀 This project uses Crawl4AI for web data extraction
- 🤖 Gemini and Claude for data processing and vibe coding
- 💖 All the amazing, creative, hard-working people who make the city shine with their light! 🗽