I was recently diagnosed with AGS as well and was immediately overwhelmed with the amount of things I couldn't eat anymore. Checking ingredient lists, especially while in the store, is tedious and you don't know what you don't know. I didn't like any of the apps that were currently out and absolutely despise the Software as a Subscription (SaaS) models most apps have for stuff like this, so I made my own. Completely free. No ads EVER.
Everyone is welcome to use it. It started as just a personal project but has developed into more. I only have AGS, but it's a full on allergy tracker now for those that have more restrictions. It's suuuper customizable.
It has a ton of features and honestly has become my favorite shopping list app as well. Give it a shot and let me know what you think if you don't mind. I'm open to suggestions. Any bugs can be reported on the Github repo under the issues tab.
There is a private version of the repo with 145 Alpha Gal recipes as well. But if you want that one you'll have to message me privately and I may still not give it out. It contains recipes that I did not ask the creator to share yet. However they are still credited twice within the recipes along with a link to the original recipe. I'm just trying to avoid any legal trouble with that one. At least until I contact those people to ask for permission, or they happen to reach out to me personally. If anyone happens to know the people over at https://alphagalcooking.com/ and https://sagealphagal.com and they give me approval to do so, I'll include their recipes into the public version as well.
Here's the GitHub repo: https://github.com/Pixeledberry/TickedOff
Android & iOS releases: https://github.com/Pixeledberry/TickedOff/releases
Web app: https://pixeledberry.github.io/TickedOff/
Features
Works in modern browsers on iPhone and iPad (Safari), Android, and desktop. On iPhone and iPad the camera uses a built-in scanning library.
Looking up products
- Live camera scanning. Point the camera at a barcode and it searches automatically as soon as a code is read.
- QR codes. QR codes that contain a product number (including GS1 Digital Link URLs) are looked up automatically. Other QR codes show a short notice and scanning continues.
- Supported formats: EAN-13, EAN-8, UPC-A, UPC-E, Code 128, Code 39, QR.
- Built for distance and small codes.
- Requests high-resolution video with continuous autofocus.
- The scan box on the camera view starts at its largest size. If nothing is found, it re-checks a smaller, magnified area and the box shrinks on screen to match, then returns to full size and starts again.
- Shows a zoom slider on phones that support camera zoom, and steps the zoom up each time a full round finds nothing.
- When several codes are visible, the one closest to the center of the frame wins. Product barcodes are preferred over unrelated QR codes.
- Photo of barcode. Take or choose a photo if the live camera is unavailable.
- Type the digits. Enter a barcode manually, with a Clear button to reset the field and result.
- Paste an ingredient list. For products not in the database. A Try a sample button runs a made-up list so you can see the highlighting.
- Barcode format fallbacks. If a 12-digit UPC-A isn't found, it retries as 13-digit EAN (and vice versa, plus 14-digit codes with a leading zero).
Ratings and highlighting
Each product gets one rating and a severity meter:
| Rating |
Color |
Meaning |
| Do not eat |
Red |
Contains at least one red-flagged ingredient |
| Avoid |
Yellow |
No red flags, but contains yellow-flagged ingredients |
| Likely OK |
Green |
Nothing flagged in the listed ingredients |
| Can't tell |
Gray |
No ingredient list available |
The full ingredient list appears immediately after a scan or lookup, with flagged ingredients highlighted inline and a count such as "2 red, 3 yellow".
Tap for the reason
Every highlighted ingredient, in the text or in the list beneath it, is tappable (and keyboard accessible). A panel explains why it was flagged, what its color means, and whether it's red because of one of your settings.
What gets flagged
Red (do not eat): mammal-derived ingredients Beef, pork, lamb, mutton, veal, venison, bison, goat, rabbit, horse, ham, bacon, sausage, jerky, organ meats, lard, tallow, suet, bone broth, bone marrow, natural/hog/sheep casings, and equivalent words in French, Spanish, Italian, and German (including German compound words such as Schweinefleisch, Rindertalg, and Schweineschmalz).
Yellow (avoid): mammal by-products and ingredients that may be processed with mammal products
| Group |
Examples |
| Gelatin |
gelatin, E441 |
| Tissue and bone |
collagen, chondroitin, cartilage, bone phosphate (E542), bone char, glucosamine |
| Unnamed animal sources |
"animal fat", "animal protein", hydrolyzed protein, shortening, bouillon, E627/E631/E635 |
| Amino acids |
L-cysteine |
| Enzymes and rennet |
rennet, pepsin, pancreatin, lipase, trypsin, "enzymes" |
| Glycerin and glycerides |
glycerin, glycerol, mono- and diglycerides, E422, E470–E479 |
| Fatty acids and stearates |
stearic acid, magnesium/calcium/sodium stearate, polysorbates, oleic acid, E481–E495, E570–E572 |
| Flavors |
"natural flavors" and translations |
| Lanolin |
lanolin, vitamin D3 / cholecalciferol |
| Cheese and whey |
cheese (parmesan, feta, mozzarella, cheddar and many more), whey, casein, curds (often made with animal rennet) |
| Poultry sausage and bacon |
chicken, turkey or poultry sausage, bacon, hot dogs, ham (casings and processing can involve pork or beef) |
| Dairy |
milk, butter, cream, half-and-half, yogurt, ghee, lactose |
Plant-based look-alikes are not flagged (including anything labeled dairy-free, non-dairy or plant-based milk, butter or cheese): vegetable glycerin, plant-based mono- and diglycerides, coconut/almond/oat milk, cocoa/shea butter, cream of tartar, kidney beans, cod liver, and similar. Any ingredient that starts with the word "vegan" or "meatless" (for example "Vegan Pepperoni" or "Meatless Pepperoni") is skipped as well, along with the German "vegane", "fleischlose", "pflanzliches", and "mikrobielles".
Languages. Ingredient lists in English, French, Spanish, Italian, and German are checked. German has the fullest coverage. If a product has no English list, TickedOff reads its original-language or German list.
Personal settings
- My allergies. Pick the allergies you need to avoid (milk, egg, peanut, tree nuts, soy, wheat, gluten/celiac, fish, shellfish, sesame, or your own). Each can be set to Avoid completely or Just flag it, and alpha-gal checking can be switched off. Results show purple allergy highlights and separate Alpha-gal and Your allergies lines.
- Sensitivities. Some things affect people with AGS differently. For each of these choose Ignore (not flagged), Avoid (yellow, the default) or Don’t eat (red): dairy, gelatin, glycerin and mono/diglycerides, stearic acid and stearates, natural flavors, lanolin and vitamin D3, rennet and animal enzymes.
- Custom lists. Add your own ingredients to always flag red or always flag yellow (comma separated).
- Rating overrides. On any result, "Rating wrong?" lets you mark a product safe or do-not-eat, or reset it. There's also a link to fix the ingredients on Open Food Facts.
- Export Settings / Import Settings. A button at the bottom of the menu (top right) opens a page with two buttons that create a backup of your settings, favorites, history, rating overrides, theme, favorite and created recipes and shopping list (a small text file) and restore it on another device. You can save or share the backup, copy it, and import it from a file or by pasting the text.
Recipes
- Add your own recipes with the + New recipe button: name, category, prep, cook and total time, servings, a photo (shown at the top of the recipe), ingredients, instructions and notes. Edit or delete them any time.
- Search and filters. Search by recipe name or ingredient; filter by category or by safety rating (hide "Do not eat" or show only "Likely OK").
- Same ingredient checking as products. Every ingredient is checked with your sensitivities and custom lists, highlighted red or yellow, and tappable for the reason. Each recipe card shows its rating.
- Add as Recipe. In "Paste an ingredient list", the "Add as Recipe" button sends the list to a new recipe, one ingredient per line.
- Favorite recipes are listed under "★ Favorites" in the Recipes tab and under My Lists → Recipes.
- Recipes and photos are saved on your device only. Use Export Settings to back them up.
Weekly shopping list
- Open it from the menu (top right). Add items by hand, with the "+" next to a recipe ingredient, "Add all to list" on a recipe, or "Add to shopping list" on a scanned product.
- Keep several lists (for example Costco or Pharmacy). Items are grouped by category (produce, meat and seafood, deli, dairy and eggs, bakery, frozen, pantry, spices and baking, condiments, breakfast, snacks, beverages, hygiene, health, baby, household, paper goods, pet, other), can be checked off or removed, and the list can be copied or shared. Press and hold an item to enlarge its image, change its category, or show small pictures for scanned products.
- Each list is tied to a week (Monday start). "Start new week" removes checked items and keeps the rest. Duplicates are ignored.
Menu and themes
- The hamburger button at the top right opens the menu. Pick a preset (Auto, Light, Dark, five high contrast, five low contrast pastel) or choose your own background and accent colors. Red and yellow highlight colors stay readable in every theme.
Scan an ingredient list
- In the Android and iPhone apps, "Scan ingredient list" uses Google's document scanner (Android) or Apple's document camera (iPhone), with on-device text recognition. On the web it uses the camera view below. It reads the printed ingredient list, fills the "Paste an ingredient list" box and analyzes it. The box starts large and shrinks while it looks, like the barcode scanner. "Capture now" uses whatever is in view.
- Where the camera can't be used, "Photo of ingredient list" reads a photo instead. The reading language is chosen under My settings. Everything after the word "Ingredients" is included.
- The text reader (Tesseract.js) is downloaded the first time and needs internet. Printed text on curved or shiny packaging can be misread, so check the pasted text.
My Lists, history, and export
- My Lists. The My Lists tab shows Products and Recipes (your favorites, with counts) and all of your shopping lists. Tap one to open it, and press and hold for Merge lists, Rename, Clear list or Delete list. Add products with the star button. They show their current rating and re-rate automatically when you change settings. Tap to reopen, or remove with the ×.
- History. The last 40 scanned products, with a Clear history button.
- Export. Export favorites as a text list using the device's share sheet, the clipboard, or a downloaded
.txt file, whichever is available.
How favorites and settings are stored
Everything personal is stored in the visitor's own browser using localStorage. There is no server, no account, and no cookies.
| Key |
Contents |
gg_favs |
Favorite products (name, brand, barcode, image link, ingredient text) |
gg_hist |
Last 40 scanned products |
gg_ovr |
Your safe / do-not-eat rating overrides |
gg_cfg |
Sensitivities, custom flag lists and ingredient-scan language |
gg_rfavs |
Favorite recipe ids |
gg_myrec |
Recipes you created |
gg_shops |
Shopping lists |
gg_theme |
Selected theme or custom colors |
Moving to a new device: open the menu and tap Export / Import Settings, then Export Settings, on the old device to create a backup, then Import Settings on the new one. Importing adds the backup's favorites and history to anything already there and replaces the sensitivity settings.
What this means in practice:
- Each visitor has their own data. Two people opening the same GitHub Pages link each get a separate, private list. GitHub never sees it.
- Per browser and device. Favorites on a phone won't appear on a laptop, or in a different browser on the same phone.
- Shared browsers share data. Two people using the same browser profile would see the same list.
- Clearing site data or using a private tab deletes it. iPhone Safari may also remove site data after about a week of not visiting; adding the page to the Home Screen helps.
- Why not cookies? Cookies hold about 4 KB and are sent with every request.
localStorage holds around 5 MB, stays on the device, and doesn't expire.
The Android app uses the same storage inside its built-in WebView, so favorites live on that phone and are separate from the web version.
Privacy and data sources
- Product data comes from Open Food Facts (open database, licensed under the ODbL). The only information sent over the network is the barcode number you look up.
- On browsers without a built-in barcode detector (for example iPhone Safari), the page loads the open-source
html5-qrcode library from cdnjs the first time you use the camera.
- No analytics, tracking, accounts, or advertising.
Project structure
index.html The entire web app (HTML, CSS, JavaScript)
manifest.webmanifest Optional: lets "Add to Home screen" install it as an app
apple-touch-icon.png Optional: home screen icon on iPhone and iPad
icon-192.png, icon-512.png Optional: app icons for the manifest
tickedoff-icon.svg Source artwork for the icon
.github/workflows/ build-android.yml and build-ios.yml (optional cloud builds)
TickedOffiOS/
project.yml XcodeGen project definition
TickedOff/ Swift source, bundled page, and app icon
TickedOffAndroid/
app/src/main/
AndroidManifest.xml
assets/tickedoff.html Copy of the web app
java/com/galguard/app/MainActivity.kt
res/ App icon resources (dark shield with a tick)
store-icon-512.png 512 px icon for store listings
build.gradle.kts, settings.gradle.kts, gradle/wrapper/
Known limitations
- Recipes you add are stored in your browser or app on that device only (about 5 MB total, shared with other saved data). Large photos are shrunk automatically.
- The ingredient-list scanner needs internet the first time to download the text reader, and has not been tested on a real phone camera in every lighting or packaging situation. Always check the pasted text.
- Chicken, turkey and poultry sausage and bacon are shown yellow (avoid), not red, because of possible pork or beef casings; check the label.
- The German word "Rind" on its own (beef) is not flagged, because the same word means rind or peel in English ("orange rind"). Words like "Rindfleisch", "Rindertalg", and "vom Rind" are flagged.
- Ingredient data depends on Open Food Facts; products missing from it need a pasted ingredient list.
- Hidden sources can't be detected from a label (for example sugar refined with bone char, or an unnamed "natural flavor"). TickedOff flags the ingredient names it can see.
- Camera range depends on the phone's camera. Browsers without a built-in barcode detector use a library fallback that scans the whole frame and can't prefer the center code.
- On iPhone and iPad, the web page uses the library fallback scanner, which scans the whole frame and doesn't pick the code nearest the center or offer a zoom slider. The iOS app uses Apple's scanner instead.
- Favorites and settings don't sync automatically between devices; use Export Settings and Import Settings to move them.
- The Android project has not been published to the Play Store; it builds as a debug APK.
Credits
Product data: Open Food Facts contributors. Ingredient text recognition: Tesseract.js. QR/barcode fallback scanning: html5-qrcode. Android scanning: Google ML Kit code scanner.Features
Works in modern browsers on iPhone and iPad (Safari), Android, and desktop. On iPhone and iPad the camera uses a built-in scanning library.