TrueLabel
Scan any barcode and read the nutrition label in plain language, checked by the community. Free, open source, and built for the products on Indian shelves.

Why it exists
“I started TrueLabel because the two apps on my phone could tell me about a Kansas granola bar and nothing about the bhujia in my hand.”
Indian products barely exist in the big food databases. The data isn’t wrong; it’s missing. And labels are written to be skimmed past: serving sizes that don’t match the pack, claims that mean nothing, numbers that never become a decision.
How it’s built
- iOS (SwiftUI)
- Barcode scanning on DataScannerViewController, label OCR on-device with Apple Vision, history and preferences in SwiftData, the device token in the Keychain.
- Android (Kotlin)
- Jetpack Compose, CameraX with ML Kit barcode scanning and text recognition, Room and Retrofit.
- API (Rust, Axum on Tokio)
- Behind nginx with TLS. PostgreSQL through SQLx with migrations at boot, Redis for caching and rate limits, Open Food Facts upstream.
- Web (Turborepo)
- A Next.js marketing site, developer docs on Fumadocs and an internal admin dashboard.
- Infrastructure
- DigitalOcean Kubernetes with ingress-nginx and cert-manager: four subdomains routed to four deployments, Neon Postgres and Upstash Redis in production, deployed by GitHub Actions on every push to main.
What it does
- No image ever leaves the phone: OCR runs on-device and only the extracted text is sent.
- Look-ups resolve Redis → Postgres → Open Food Facts, and anything fetched upstream is written to Postgres before it is returned.
- Contributions are checked server-side: submitted ingredients are compared with the OCR text and flagged for low confidence or an allergen mismatch.
- Three peer verifications mark a product verified.
- No accounts: a device bearer token, stored only as a SHA-256 hash, and the device id never appears in a URL.
- Search ranks by trigram similarity, then popularity, and tops up from Open Food Facts when fewer than five local rows match.
- Security headers on every response and CORS closed by default; hourly rate limits in Redis that fail open if Redis is unreachable.
Screens




Where it sits
Rust · Axum · Tokio · SQLx · PostgreSQL · Redis · SwiftUI · SwiftData · Kotlin · Jetpack Compose · Next.js · Kubernetes · Terraform
By the numbers
- Verified after
- 3 peer confirmations
- Rate limits per hour
- 600 look-ups, 200 searches, 60 confirmations, 20 new products
- Global backstop
- 3,000 requests per hour per address
- Timeouts
- 25 s per request; 10 s for Open Food Facts
- Payload caps
- 256 KB per request; 20,000 characters of OCR text
- Nutrition record
- Always the same 13 keys, per 100 g
