This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle
What I Built
If you sell banana bread at a farmers' market, the law already has opinions about your sticker.
In the EU and UK, the 14 major allergens must be emphasised in the ingredient list, usually in bold. In the US, the 9 major allergens need a "Contains:" line. Big brands have food technologists for this. Someone baking on a Saturday morning has a recipe card, a label printer and a nagging feeling that the pesto might have nuts in it. (It does. Pine nuts, and cheese too.)
BoldPrint turns a pasted recipe into a printable allergen label. It reads the recipe in any language, works out what each ingredient is made of, and prints:
Ingredients: strong white bread flour (gluten), warm water, yeast, olive oil, tahini (sesame), basil pesto (milk, nuts), sea salt.
Then it does the part every market baker dreads doing by hand: a nutrition table worked out from the amounts in the recipe (EU/UK "Nutrition declaration", US "Nutrition Facts" or Indonesian "Informasi Nilai Gizi"), a calculated Nutri-Score for EU sellers, and an ingredient list sorted heaviest first, the way the rules want it. One label, three toggles, saved as a PNG or a 90 mm PDF for sticker paper.
The hard part is the hidden allergens: ingredients whose names don't say what's in them. Tahini is sesame. Ghee is milk. Worcestershire sauce contains anchovies. Pinoli is Italian for pine nuts. Biscoff contains wheat and soy. A Snickers bar is peanuts, milk, soy and egg.
Who would pay: home and cottage-food bakers, market stall cooks and small Etsy food sellers. Getting a label wrong can mean a recall, a fine or, much worse, a customer in hospital. A few dollars a month for "paste recipe, print sticker, and it catches the tahini" is an easy sell to someone who currently does this by hand.
Demo
https://boldprint.onrender.com
Code
BoldPrint
Paste a recipe, get a food label: allergens in bold, a nutrition table and a Nutri-Score. Save it as PNG or PDF.
Built for the DEV × Hacktoberfest 2026 Open-Source AI Challenge, week 2: Side Hustle.
Live demo: boldprint.onrender.com (the free server naps when idle, so the first label can take up to a minute)
Who it's for
Home bakers, market stalls and small online food sellers. EU/UK rules want the 14 allergens emphasised in the ingredient list, the US wants a "Contains:" line and Indonesia wants "Mengandung alergen". Getting it wrong can mean a recall or a customer in hospital. BoldPrint does it in one paste:
- Finds hidden allergens in any language: tahini → sesame, Worcestershire → fish, pinoli → nuts, Biscoff → wheat and soy.
- Lists ingredients heaviest first, as the rules expect, using the amounts in your recipe.
- Works out nutrition from those amounts…
How I Built It
Why not just a dictionary? That was my first idea too, so I built one and measured it. The Open Food Facts ingredient taxonomy is a fantastic open dataset: thousands of ingredients in dozens of languages, linked to the allergens they contain. I turned it into a 32,000-entry lexicon. On 32 realistic recipes I wrote and labelled by hand, the lexicon alone missed 11% of the allergens, and 9 of the 32 labels had at least one miss. It didn't know that "Dijon" is mustard or that a Snickers bar is peanuts and egg, it missed the shrimp paste hiding in green curry paste, and a typo like "tahinni" or "worchestershire" sank it. Every one of those misses is the dangerous kind: the label would have looked complete.
That lexicon is still the most valuable thing in the project. It just became the teacher and the safety net instead of the product.
1. Trustworthy training data, no LLM guessing. I generated 3,000 synthetic recipes in 10 languages, with messy quantities, bullets, typos, titles and method steps. Every allergen label comes from the lexicon plus a hand-curated override list (miso: [soy], worcestershire sauce: [fish], oats count as gluten under EU rules…), not from another model's opinion. 20% of the long-tail ingredients are held out of training entirely, so the test set measures generalisation rather than memory.
2. SFT on Tinker. I fine-tuned Qwen3-8B (Apache-2.0) with a LoRA adapter on Tinker, so it returns one strict JSON object per recipe: each ingredient and its allergens.
3. RL with a reward that knows what matters. This is the part I'm proudest of, and it's the reason I used Tinker. In allergen labelling the errors aren't symmetric: an extra "may contain nuts" costs you a word on a sticker, while a missed one can cost someone an EpiPen. So the reward is:
-10 per allergen the model missed
-1 per extra allergen it flagged
-10 per true allergen, -5 more, if the output isn't valid JSON
+1 if the "contains" list is exactly right
Tinker gives you the training loop itself (sample, score with your own Python, forward_backward, optim_step), so a domain-specific reward is ~40 lines instead of a research project. Over 20 RL steps, missed allergens per label on the training batches fell from about 0.05 to under 0.02, and the average reward roughly tripled (0.22 → 0.66).
4. Results.
On 32 real-world recipes I wrote and labelled by hand (brands, typos, several languages):
| Missed allergens ↓ | Labels with a miss ↓ | |
|---|---|---|
| Qwen3-8B, untrained | 74.0% | 25 / 32 |
| Dictionary only (Open Food Facts lexicon) | 11.0% | 9 / 32 |
| Fine-tuned model (SFT + RL) | 6.0% | 5 / 32 |
| BoldPrint as shipped (model + lexicon cross-check) | 3.0% | 2 / 32 |
On 300 held-out synthetic recipes the fine-tuned model misses 1.6% of allergens, against 29.8% for the untrained model. The full table is in eval/out/table.md, and python eval/benchmark.py reproduces the "as shipped" row for free from the saved outputs.
In short: the untrained model missed three allergens in four, the dictionary missed one in nine, and BoldPrint as shipped misses three in a hundred, for about $0.12 per thousand labels.
5. Belt and braces in the app. Every model answer is cross-checked against the lexicon. If the lexicon finds an allergen the model didn't, the label doesn't quietly pick one. It adds a âš Check line so a human looks. If Tinker is unreachable, the app falls back to lexicon-only mode and says so in a banner.
6. Nutrition without a lab. The model's ingredient list is also the backbone of the nutrition table. Each recipe line is turned into grams (cups, "2 EL", "1 c. Ã soupe", "juice of 1 lemon", "1 can"), matched to a food in CALNUT, the French food agency's open nutrient table, through ~130 hand-mapped staples and the Open Food Facts taxonomy's links, then summed and divided by the finished weight. The rules are boring on purpose: EU and US rounding tables, the 2023 Nutri-Score algorithm, and a label line that says "Calculated from ingredient data, not a laboratory analysis." Anything the app had to guess (a cup of pesto, "a can of chickpeas", an ingredient it couldn't match) shows up in a Check nutrition panel where you can type the grams or pick another food, and the label redraws without another model call.
7. The label is a picture, not a web page. The preview, the PNG and the PDF are drawn by the same small canvas renderer, so what you see is exactly what prints. No screenshotting of HTML, no PDF library to load: the PDF is about 40 lines of JavaScript wrapping one JPEG.
Stack: Qwen3-8B · Tinker (LoRA SFT + RL, OpenAI-compatible inference) · Open Food Facts taxonomy · CALNUT (ANSES) · FastAPI · canvas · Render (free web service) · 250+ pytest tests and a Playwright check.
Total training spend: about $2.30 of Tinker credit, including the evaluation runs.
Why Does Open Innovation Matter?
Three reasons, all specific to this project:
- Open data made trustworthy labels possible. The training labels come from Open Food Facts, maintained by volunteers, multilingual, and licensed so I can build on it. With only a closed model I would have been grading one AI's guesses with another AI's guesses.
- Open weights let me change what the model cares about. A closed API lets you prompt it to "be careful". It doesn't let you put a −10 on a missed allergen and train against it. With Qwen3-8B and Tinker I own the adapter, I chose the reward, and I can download the weights and run them elsewhere if I ever need to.
- Small and cheap is the business model. A side hustle can't carry a big per-label API bill. An 8B model specialised for one job costs about $0.12 per 1,000 labels, which leaves room to charge a baker a few dollars a month and still make money.
Prize Categories
- Best Use of Tinker: SFT then RL with a custom asymmetric safety reward; baseline comparison above.
-
Best Use of Render: the live demo runs on a Render free web service (FastAPI, auto-deploys from
main,/healthzhealth check, spend caps set through environment variables).




Top comments (0)