Skip to content

Repository files navigation

Menu Scanner

A web app that analyzes photos of restaurant menus to identify which dishes are safe or risky based on a user's dietary restrictions and allergies.

Status: Proof of concept Last updated: 2026-07-28

Features

  • Upload or photograph a restaurant menu
  • Select dietary restrictions and allergies (saved in the browser between visits)
  • Get dish-by-dish analysis with three ratings: Likely safe, Ask server, Avoid
  • Expandable explanations for each flagged dish
  • Optional password gate, and a per-visitor daily usage limit

How it works

Analysis runs in two separate Claude calls in src/app/api/analyze/route.ts:

  1. Transcription — the menu image is read and the text extracted verbatim, with no interpretation.
  2. Analysis — the extracted text is classified against the selected restrictions and returned as JSON.

Splitting the two keeps dish names accurate, and means the image is never given to the step that makes judgments about it.

Setup

Prerequisites

Environment variables

Create a .env.local file in the project root:

ANTHROPIC_API_KEY=your_api_key_here
ACCESS_PASSWORD=your_password_here
NEXT_PUBLIC_AUTH_ENABLED=true
Variable Required Purpose
ANTHROPIC_API_KEY Yes Authenticates calls to Claude. Never commit this value.
ACCESS_PASSWORD Only when the gate is on Password for the login screen. Accepts several comma-separated passwords (alpha,bravo,charlie) so different people can be given different ones.
NEXT_PUBLIC_AUTH_ENABLED Yes true shows the password gate; any other value gives open access via a "Get Started" button.

Note that NEXT_PUBLIC_AUTH_ENABLED is baked into the browser bundle at build time, so changing it requires a rebuild or redeploy — not just a restart. ACCESS_PASSWORD and ANTHROPIC_API_KEY stay server-side and are never sent to the browser.

Install and run

npm install
npm run dev

Open http://localhost:3000 in a browser.

Deployment

Deploy to Vercel and add all three environment variables (ANTHROPIC_API_KEY, ACCESS_PASSWORD, NEXT_PUBLIC_AUTH_ENABLED) under project settings. Redeploy after changing any of them.

Configuration reference

Values worth knowing about, and where to change them:

Setting Value Location
Claude model claude-sonnet-5 MODEL in src/app/api/analyze/route.ts
Response size ceiling 8192 tokens MAX_TOKENS in src/app/api/analyze/route.ts
Daily analyses per visitor 20 DAILY_LIMIT in src/lib/rate-limit.ts
Accepted uploads JPEG, PNG, HEIC, WebP under 10MB ACCEPTED_TYPES / MAX_SIZE_MB in src/components/ImageUpload.tsx

Known limitations

  • Models get retired. Claude models are withdrawn on a published schedule, and requests to a retired model fail. If every upload starts erroring, check the model deprecation page and update MODEL. The app reports this case explicitly rather than showing a generic error.
  • The daily limit is not durable. Usage counts are held in server memory, so on Vercel they reset whenever a new serverless instance starts. The limit discourages casual overuse but will not stop a determined user.
  • Large uploads may fail. Uploads are accepted up to 10MB, but encoding for transport inflates them by roughly a third, which can exceed Vercel's 4.5MB request limit. Large photos taken at full resolution are the likely case.
  • HEIC is not converted. HEIC files are labelled as JPEG before being sent rather than actually converted, which Claude will reject. iPhones normally convert to JPEG on upload, so this mainly affects .heic files dragged in from a Mac.
  • This is not medical advice. Output depends on how completely a menu describes its dishes, and hidden ingredients and cross-contamination will not appear in the text. Treat results as a starting point for a conversation with restaurant staff.

About

Menu Scanner analyzes photos of restaurant menus to identify which dishes are safe or risky based on a user's dietary restrictions and allergies.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages