Find the perfect coffee shop based on real-time busyness data
NearBrew is a full-stack web application that helps coffee lovers discover nearby cafes and check their live busyness levels before visiting. Built with a focus on performance optimization, intelligent caching strategies, and exceptional user experience.
π Live Demo
- Radius-based search with 30km (configurable) coverage area
- Real-time geolocation with HTML5 Geolocation API
- Interactive map visualization powered by Leaflet and OpenStreetMap
- Automatic user positioning with fallback handling
- Google Places Autocomplete integration for instant venue discovery
- On-demand live forecast queries that bypass cache for most accurate data
- Venue details including ratings, reviews, price level, and dwell time
- Opening hours with multi-timezone support
- Real-time crowd data from BestTime Radar API
- Live busyness percentages with intelligent thresholds (50-100% busy range)
- Historical trend analysis and predictive forecasting
- Peak hours and quiet window recommendations
- "Best time to meet" feature for planning coffee meetups
- Responsive design with mobile-first approach
- Custom coffee-themed UI with warm, inviting color palette
- Loading states, error boundaries, and graceful fallbacks
- Social sharing capabilities for meetup planning
BestTimeAPI has a limited number of api credits available for the free tier. To that end, I strove to follow the ABC Rules of Caching to save me some money π but also prioritize performance in a lightweight but robust manner
One of NearBrew's standout features is its multi-layered caching strategy that dramatically reduces API costs while maintaining data freshness. The implementation follows the ABC Rules of Caching:
// Client-side cache: 5-minute stale time
staleTime: 5 * 60 * 1000 // 300 seconds
maximumAge: 300000 Purpose: Eliminates redundant API calls during a user session
- Caches venue lists and user geolocation data
- Automatically serves cached data for repeated requests
- Logs cache hits/misses for debugging:
π’ CACHE HITvsπ΄ CACHE MISS
2οΈβ£ Server-Side Geographic Cache (Using Node Cache for simplicity https://www.npmjs.com/package/node-cache)
// Server cache: 10-minute TTL with spatial awareness
const cache = new NodeCache({ stdTTL: 600 });Purpose: Serves nearby requests without hitting external APIs
- Intelligent radius-based matching using Haversine formula
- Reuses cached data when new requests fall within a cached location's radius
- Example: Request at (40.06, -82.85) with 30km radius can serve a user at (40.07, -82.86)
// Geospatial cache hit detection
if (cachedEntry && isNearby(latNum, lngNum, cachedEntry.lat, cachedEntry.lng, cachedEntry.radius)) {
console.log(`Cache hit for lat: ${lat}, lng: ${lng}, radius: ${radius}`);
return cachedEntry. data;
}// Per-venue caching for quick lookups
cache.set(`venue:${venue.venue_id}`, venue);Longer cache periods (10 minutes) reduce API costs but can lead to stale busyness data on initial page load, especially for rapidly changing venues. In addition, BestTime radius endpoint is cached for an hour long duration by default as well
-
Cached Browse Experience: Initial page load shows venues from cache (may be up to 10 minutes old)
- β Pro: Instant loading, minimal API usage
β οΈ Con: Busyness data may be slightly outdated
-
Fresh Search Results: The search feature always bypasses cache via direct POST requests
- β Pro: Guaranteed fresh live data for user-selected venues
- β Pro: Users get real-time accuracy when it matters most
- π‘ Result: Best of both worldsβfast browsing + accurate search
// Search always hits the API for live data
POST /venues/live-forecast? venue_name=${name}&venue_address=${address}
// No caching applied to this endpoint!
Frontend
- React 18 with TypeScript for type-safe components
- Vite for lightning-fast development and optimized builds
- TanStack Query (React Query) for intelligent client-side caching
- React Router for seamless navigation
- Leaflet & React-Leaflet for interactive maps
- Google Places API for autocomplete search
- TailwindCSS for responsive styling
Backend (Microservices)
- Fastify for high-performance Node.js APIs
- NodeCache for server-side in-memory caching
- CORS configuration for secure cross-origin requests
- TypeScript for end-to-end type safety
External APIs
- BestTime Radar API - Live busyness and forecast data
- Google Places API - Venue search and autocomplete
- OpenStreetMap - Map tiles and geospatial data
Tooling
- Nx Monorepo for scalable workspace management
- ESLint & Prettier for code quality
- Docker for containerizing the backend
- GitHub Actions for CI/CD
- GitHub Pages for deployment
- NearBrewCard: Branded container with coffee-themed styling
- NearBrewAutoComplete: Google Places integration with custom styling
- VenueLocationMap: Interactive Leaflet map with custom coffee pin markers
- StickyBanner: Persistent branding with "Buy Me a Coffee" CTA
- Mobile-first approach with breakpoint-based layouts
- Touch-friendly interactions for map and search
- Optimized performance for low-bandwidth connections
- Semantic HTML structure
- ARIA labels for screen readers
- Keyboard navigation support
- Loading states and error messages
- Code Splitting: Dynamic imports for route-based code splitting
- Image Optimization: Lazy loading for map tiles
- Memoization:
useMemoanduseCallbackfor expensive computations - Bundle Size: Tree-shaking and minification via Vite
- API Efficiency: Strategic caching reduces external API calls by 70-80%
- Environment variables for sensitive API keys
- CORS configuration for allowed origins
- Input validation on all API endpoints
- Rate limiting considerations for production deployment
- Secure HTTPS deployment on GitHub Pages
- User authentication and saved favorites
- Push notifications for when favorite venues become less busy
- Social features: share venues with friends
- Historical trend charts with Chart.js
- Progressive Web App (PWA) support for offline access
- Backend deployment to cloud provider (AWS/Vercel)
- Redis integration for distributed caching
- BestTime API for busyness data
- Google Places API for venue search
- OpenStreetMap for map tiles
- Nx for monorepo tooling