Skip to content

About

Fail-closed allergen checks for recipes and packaged foods (EU 14 + US Big 9). Never says 'safe'.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

36 Commits

Folders and files

Repository files navigation

allergen-guard

A fail-closed allergen checker for recipes and packaged foods. Zero dependencies.

It answers with one of three verdicts, and none of them is "safe":

  • unsafe: contains a listed allergen, or "may contain" it
  • cannot_confirm: the data is missing or ambiguous, or an ingredient often hides the allergen (sauce, stock, chocolate, lecithin…)
  • no_listed_allergens: nothing found; the caller still has to check the label

Why

Allergen lists in open data are claims, not facts: in Open Food Facts, real records omit allergens that their own ingredient list contains, and most records hold too little to check against (72.3% of the 4,784,317 records in the snapshot measured in bench/ list no allergens, no "may contain" and no ingredients). So the engine reads the allergen tags, the traces and the ingredient text together, and never trusts one of them alone. Where the data is missing or ambiguous it does not guess: the three verdicts are UNSAFE, CANNOT CONFIRM and NO LISTED ALLERGENS, and "safe" is not one of them.

import { checkIngredients, checkProduct, resolveAllergies, suggestSwaps } from "allergen-guard";

const maya = { name: "Maya", allergies: resolveAllergies(["peanuts", "tree nuts"]).ids };
const leo = { name: "Leo", allergies: resolveAllergies(["dairy", "celery"]).ids };
const household = [maya, leo];
const people = [leo]; // who is eating

const r = checkIngredients(["1 stick celery", "400ml creme fraiche", "basil"], people);
r.overall;  // "unsafe"
r.speech;   // "Leo should avoid this: it contains celery and milk, in the celery and creme fraiche."
suggestSwaps(r.lines, people, household); // swaps for the people checked; options also avoid everyone in household (default: people)

checkProduct(openFoodFactsProduct, household); // a record from the Open Food Facts API; reads tags AND ingredient text; missing data → cannot_confirm

Covers the EU's 14 regulated allergens and the US Big 9, with wheat kept separate from gluten. Product checks read Open Food Facts records and don't trust the allergen tags alone, because real records omit allergens their own ingredient list contains.

Install from GitHub (npm install github:Quillrun/allergen-guard; the install step compiles src/ to dist/ with TypeScript) or run the TypeScript source directly on Node 22.6 or newer. npm test runs the suite. It includes a list of dangerous ingredients that must never come back as "nothing listed", and look-alikes that must not be flagged (butter beans, coconut milk, nutmeg).

Not medical advice. Always check the label.

MIT licensed. The bench data is not: it is Open Food Facts data under the Open Database License (ODbL) 1.0, as set out under "Data licence" in bench/README.md.

This repository is the published copy of the engine. It is developed inside the Allergy Crosscheck application, under packages/allergen-guard, and synced here, so the commit hashes in bench/README.md refer to the application repository (https://github.com/Quillrun/allergy-crosscheck).

It is the engine behind Allergy Crosscheck, an Alexa+ add-on built for the Build, Ship, Shape: Amazon Developer Hackathon (October 2026). The bench/ folder holds the Open Food Facts measurement and its hand checks.

About

Fail-closed allergen checks for recipes and packaged foods (EU 14 + US Big 9). Never says 'safe'.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages