A modern Singapore and Jakarta map explorer with intelligent landmark search, cross-border navigation, real-time bicycle parking, and rainfall visualization.
π Hackathon Submission (Cutoff: Oct 19, 2025 9:00 AM SGT)
- Live Demo - Production deployment at cutoff time
- Source Code - GitHub repository snapshot at cutoff time
Built at Cursor Hackathon SG 2025 - A 24-hour hackathon with 500+ builders, sponsored by Cursor, OpenAI, DeepMind, Anthropic, Groq, ElevenLabs, Supabase, Convex, Exa, and more.
- Next.js 15 - React framework with App Router and Turbopack
- React 19 - Modern UI library with latest features
- Effect-TS - Functional programming library for TypeScript
- PostgreSQL via
@effect/sql-pg- Persistence behind Effect repository ports - TypeScript - Type-safe development
- Mapbox GL JS - Interactive map rendering with 3D support
- Exa AI - Semantic search API for landmark discovery
- LTA DataMall - Singapore bicycle parking & rainfall data
- Tailwind CSS v4 - Utility-first styling
- Radix UI - Accessible UI components
- Lucide React - Beautiful icon library
- next-themes - Theme management
- Sonner - Toast notifications
- Biome - Fast linter and formatter
- Vitest - Unit testing framework
- Playwright - E2E testing across browsers
- Husky - Git hooks for quality checks
- Cross-Border Navigation - Seamless travel between Singapore and Jakarta with intelligent city detection, smooth flyTo animations (6.5s cross-border, 2.5s local), and URL updates without page reloads
- City Toggle - Quick toggle between Singapore and Jakarta with plane animation during transition, maintaining map state and supporting browser back/forward navigation
- Smart Landmark Search - AI-powered search with Exa API, saved locations persisted in PostgreSQL
- Interactive Map Explorer - Multiple map styles (satellite, streets, dark, light) with smooth flyTo animations and 3D buildings toggle
- Real-time Bicycle Parking - Live data from LTA DataMall showing nearby bicycle parking with shelter indicators, save favorites locally
- Real-time Rainfall Overlay - 2-hour rainfall nowcast with heat map visualization showing rain intensity across Singapore (live + mock modes)
- Location Discovery - GPS location finder, random coordinates generator, saved locations cycling, and manual search
- Theme Support - Dark/light mode with persistent theme preference across the app
- Node.js 18+ and pnpm
- Mapbox Access Token
- Docker Desktop (local PostgreSQL)
- Exa API Key
- LTA DataMall Account Key
-
Clone and install dependencies:
pnpm install
-
Set up environment variables:
cp .env.example .env.local
Add your keys to
.env.local:MAPBOX_ACCESS_TOKEN=pk.your_mapbox_token NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN=pk.your_mapbox_token EXA_API_KEY=your_exa_api_key LTA_ACCOUNT_KEY=your_lta_account_key
-
Start PostgreSQL, run migrations, and start Next.js:
pnpm run dev:all
See
docs/POSTGRES_SETUP.mdfor details. -
Start Next.js development server:
pnpm dev
-
Open your browser:
http://localhost:3000
pnpm dev # Start development server
pnpm build # Build for production
pnpm start # Start production server
pnpm lint # Run Biome linter (check only)
pnpm format # Format code with Biome
pnpm fix # Auto-fix linting issues with Biome
pnpm type-check # Run TypeScript type checking
pnpm test # Run unit tests (Vitest)
pnpm test:watch # Run tests in watch mode
pnpm test:e2e # Run end-to-end tests (Playwright)
pnpm check-all # Run all checks (fix + type-check + test + build)Pre-push Hook: Husky automatically runs check-all before every push. Skip with git push --no-verify if needed.
The project uses Effect-TS with a ManagedRuntime architecture for optimal performance:
- Single Runtime Instances: One server runtime, one client runtime (not per-request)
- Layered Architecture: BaseLayer (shared) + ServerLayer (server-only) + ClientLayer (client-only)
- Lifecycle Management: Initialized via Next.js instrumentation hooks
- Resource Efficiency: Service reuse, connection pooling, reduced GC pressure
- Error Handling: Type-safe error handling with
Effect.catchAll - Configuration: Environment variables managed through Effect Config
BaseLayer (Shared)
ββ ConfigService: Environment variables
ββ ToastService: Logging & notifications
ServerLayer (Server-only) = BaseLayer +
ββ MapboxService: Geocoding API
ββ RainfallService: NEA rainfall data
ββ BicycleParkingService: LTA bike parking
ββ ExaSearchService: Semantic search
ClientLayer (Client-only) = BaseLayer +
ββ GeolocationService: Browser GPS
ββ MapReadinessService: Map state
ββ MapNavigationService: Map flyTo animations
ββ CrossBorderNavigationService: City detection & navigation
ββ ThemeSyncService: Theme managementBenefits:
- π 9% faster responses (no layer construction overhead)
- πΎ Lower memory usage (services instantiated once)
- π HTTP connection pooling (reused across requests)
- π Better fiber management (shared pool)
See docs/RUNTIME_ARCHITECTURE.md for details.
15 Effect-TS Services: ExaSearchService, DatabaseSearchService, CapturedImageService, MapboxService, BicycleParkingService, RainfallService, SearchStateService, GeolocationService, RandomCoordinatesService, ToastService, ThemeSyncService, MapReadinessService, ConfigService, MapNavigationService, CrossBorderNavigationService
PostgreSQL Schema: 5 tables (locations, rainfall_readings, bicycle_parking_cache, captured_images, image_blobs) behind repository ports
src/
βββ app/ # Next.js App Router pages
βββ components/ # React components
β βββ ui/ # Reusable UI components
βββ hooks/ # Custom React hooks
βββ lib/ # Core application logic
β βββ actions/ # Next.js Server Actions
β βββ services/ # Effect-TS services
β βββ schema/ # Effect.Schema definitions
src/lib/repositories/ # Repository ports and PostgreSQL adapters
tests/ # Playwright e2e tests
- Unit Tests: Vitest for testing Effect-TS services (63 tests in ~1s)
- E2E Tests: Playwright for browser testing across Chromium, Firefox, WebKit (21 tests in ~40s)
- Quality Checks: Pre-push hook runs full test suite automatically
Percy integration for visual regression testing catches UI changes automatically:
# Run visual tests (requires PERCY_TOKEN)
pnpm test:visual
# Run visual tests with browser visible (local development)
pnpm test:visual:local- Sign up at percy.io (free for open source)
- Create a project and get your
PERCY_TOKEN - Add to your environment:
export PERCY_TOKEN=your_token_here # or add to .env file
- Run tests - Percy will capture baselines on first run
- Map Loading: Initial map render and controls
- Search Panel: Search interface and results display
- Database Integration: Database result badges and UI state
- Cost: ~4 snapshots/run Γ ~40 runs/month = ~160 snapshots/month (3% of 5000 limit)
- Browser: Chromium only (1280px desktop viewport)
- When to run: Before releases or when UI changes are made
- Baselines: Approve changes via Percy dashboard to update baselines
Additional documentation in the docs/ directory:
POSTGRES_SETUP.md- PostgreSQL persistence and repository portsDEPLOYMENT.md- Vercel deployment instructionsDEV_VS_PROD.md- Development vs production environment setup
SEARCH_INTEGRATION.md- Search architecture overviewSCHEMA_INTEGRATION.md- Schema design patternsBICYCLE_PARKING_FEATURE.md- Bicycle parking implementationTHEME_SYNC_SERVICE.md- Theme synchronization service
SECURITY_FIX.md- Server-side API key security3D_BUILDINGS_FIX.md- Mapbox 3D buildings implementationMAPBOX_LAYER_PERSISTENCE.md- Map layer state managementPARALLEL_SEARCH_FIX.md- Concurrent search optimizationEXA_QUERY_IMPROVEMENTS.md- Exa API query enhancementsTIMEOUT_FIX.md- Request timeout handlingBADGE_FIX.md- UI badge component fixes
AGENTS.md- AI agent capabilities and guidelinesQUALITY_FEATURES.md- Code quality standardsPRODUCTION_TROUBLESHOOTING.md- Production debugging guide
- Air Quality & UV Index - Smog levels and UV radiation data from National Environment Agency
- Weather Forecasts - 4-day weather forecasts and temperature trends
- Lightning Alerts - Real-time lightning strike warnings from NEA
- LTA Dynamic Data - Real-time bus arrivals, taxi availability, and traffic speed from LTA DataMall
- Traffic Closures - Live road closure alerts from LTA OneMotoring
- ERP Rates - Electronic Road Pricing rates and timing information
- Carpark Availability - Real-time carpark occupancy data
- Route Planning - Multi-modal route suggestions combining walking, cycling, and public transport
- Weather-Aware Recommendations - Smart suggestions based on current weather, air quality, and rainfall
- Community Reports - Crowdsourced updates for parking availability and facility conditions
- Historical Analytics - Parking usage patterns, weather trends, and traffic patterns over time
- Offline Mode - Cached map tiles and saved locations for offline use
This project was built during the Cursor Hackathon Singapore 2025, Cursor's first official 24-hour hackathon in Singapore with 500+ builders.
- 24 hours of intense building with Cursor
- $100,000+ in cash and credits for winners
- $200,000+ in total perks for all participants
- Sponsored by Cursor, OpenAI, DeepMind, Anthropic, Groq, ElevenLabs, Supabase, Convex, Exa, and more
Special thanks to the sponsors whose APIs and services power this application:
- Convex - Original hackathon backend, since replaced by PostgreSQL
- Exa - Semantic search API
- Mapbox - Interactive map rendering
MIT