Discover Dishes, Not Restaurants.
MenuFirst flips the food delivery search experience — search for a specific dish and find every restaurant nearby that serves it, instead of browsing restaurant-first.
- Dish-first search — type "pad thai" or "birria tacos" and see every option near you
- Smart filters — dietary tags (Vegan, Vegetarian, Gluten-Free, Spicy, Keto), price buckets, cuisine type
- Sort options — Best Match, Lowest/Highest Price, Highest Rated, Fastest Delivery
- Interactive map — browse restaurant locations with pins and a sidebar
- Dish comparison — compare up to 3 dishes side-by-side (price, delivery time, rating, ingredients)
- Cart — add items from multiple restaurants, grouped by restaurant with delivery fees
- Food identifier — upload or take a photo of any dish to identify it and search for it nearby
- Geolocation — use your current location or search by city/zip
| Layer | Tech |
|---|---|
| Frontend | React 18 + Vite |
| Styling | Tailwind CSS 3 |
| Maps | Leaflet + react-leaflet (OpenStreetMap) |
| Backend | Express.js (Node.js ESM) |
| Restaurant data | Yelp Business Search API |
| Menu data | OpenMenu API |
| Food ID | Google Gemini 2.5 Flash (vision) |
- Node.js 18+
- API keys for Yelp, OpenMenu, and Google Gemini
git clone https://github.com/735meis/MenuFirst.git
cd MenuFirst
npm installCreate a .env file in the root:
YELP_API_KEY=your_yelp_key
OPENMENU_API_KEY=your_openmenu_key
GEMINI_API_KEY=your_gemini_key
PORT=3001
npm run devOpens at http://localhost:5173. The Vite dev server proxies /api/* to the Express backend on port 3001.
npm run build
npm run startMenuFirst/
├── src/
│ ├── App.jsx # Main app component (~2000 lines)
│ ├── fallbackData.js # Offline menu data + cuisine config
│ ├── main.jsx # React entry point
│ └── index.css # Global styles + Tailwind directives
├── server.js # Express API server
├── index.html
├── vite.config.js
└── tailwind.config.js
| Method | Path | Description |
|---|---|---|
| GET | /api/restaurants |
Search nearby restaurants via Yelp |
| GET | /api/openmenu/search |
Find restaurants with menu data |
| GET | /api/openmenu/menu/:uid |
Fetch full menu for a restaurant |
| POST | /api/identify-food |
Identify a dish from an image (Gemini) |
| GET | /api/geocode/autocomplete |
Location search autocomplete |
MIT