Running it yourself
This is the half of how it works that is about the machinery rather than about the food. Nothing here is needed to use the site.
The whole thing is a static Jekyll site plus a handful of Cloudflare Pages Functions, and it runs inside the free tier. Every key is optional and every missing key degrades one feature rather than breaking the site: with no keys at all you still get a working calculator on a built-in food table and a rule-based parser.
The public API
The USDA mirror this site keeps is
also a public API. /api/convert?food=plain+flour returns the
food’s per-100 g nutrients and the gram weight of a cup, a tablespoon, a
teaspoon, a slice and an item — every measure USDA weighed for that food — plus
measured, which names the ones that came straight off FDC rather than out of
arithmetic. Add &amount=2&unit=cup and it converts that amount and scales the
nutrients to it. A whole ingredient list goes in one POST.
It never estimates. The browser will fall back to a category default and badge
the row est. weight, because a rough number a reader can see is caveated
beats a blank; JSON has no badge, and a guess served over HTTP ends up in
somebody’s spreadsheet as a fact. Where a weight cannot be computed honestly
the endpoint returns null and says why.
You can see the state of the
mirror — how many foods, how many are stale, what share of lookups avoided a
USDA call — at /api/stats. It is not linked, because robots.txt disallows
/api/, and a link from here would ask a crawler to fetch what the site has
just told it not to.
Configuring it yourself
Three secrets, all optional and all independently degradable:
| Secret | Without it |
|---|---|
FDC_API_KEY |
Falls back to the built-in table of ~140 ingredients |
ANTHROPIC_API_KEY |
Falls back to the rule-based parser; photographing a recipe and scanning a label are unavailable |
ADMIN_KEY |
Only the manual refresh sweep is disabled |
- Get a free FoodData Central key at fdc.nal.usda.gov/api-key-signup.html — instant, email only.
- Get an Anthropic API key at console.anthropic.com.
- Set them on the deployment:
npx wrangler pages secret put FDC_API_KEY, and the same for the others.
Keys live on the server and are never sent to a browser.
What it costs to run
Parsing uses Claude Sonnet 5 at $3 per million input tokens and $15 per million output. A typical recipe is about 1,200 input and 700 output tokens — roughly 1.4 cents — and because results are cached by recipe hash, the amortised cost falls toward zero as the same recipes recur. USDA lookups are free and, after the mirror warms, mostly don’t happen at all.
The model and its per-token price are written down together, once, in
functions/_lib/model.js, and the daily spend ceiling multiplies tokens by
that price. Changing one without the other does not raise an error — it moves
the ceiling by the ratio between the two tiers, and the first sign of it is
the invoice.
Rate limits, and what happens when one trips
The model endpoints are capped three ways: 20 parses per caller per hour, 60 per caller per day, and a global daily spend ceiling in dollars. The first two bound one visitor; the third bounds a distributed attempt that per-caller limits would miss, and it is the one that actually protects the bill.
When any of them trips, nothing breaks and nothing is refused outright — the site falls back to its rule-based parser, which is the same code path a deployment with no Anthropic key uses. That is worth knowing because it is invisible from the outside: the numbers keep coming, and the ingredient matching just gets a little blunter on awkward lines.
The source
The whole repository is public, including the tests that hold the invariants on this page in place — the lookup order, the spend ceiling, the rule that a weight is never guessed silently.