Case study 07Ingredient scannerCroatiaLaunching soon
Haircode
Reads a hair product's ingredient list and explains it in Croatian.


Haircode reads the ingredient (INCI) list on a hair product and gives Croatian-language guidance for that kind of product. Built for its product owner, it will be published under ByteNest's store accounts.
The brief
Someone else's engine, in people's hands.
The product owner has a scanner engine that analyses ingredient lists. Haircode puts it in people's hands: photograph or paste the list, get guidance for that product's category (shampoo, mask, leave-in and more), and keep a care calendar. We built the Flutter app, the photo reader on Supabase and the integration that runs the engine on the phone.
System map
How it fits together
- 1A photo or a pasted listPeople photograph the ingredient list on the label, or paste it in
- 2Read in the cloud, analysed on the phoneAn edge function reads photos; the engine runs inside the app
- 3Guidance, kept on the deviceCategory guidance and a care calendar, local-first, in Croatian
- 4Three hard partsSomeone else's engine, our app
Three hard parts
Someone else's engine, our app
A black box, kept black
The engine belongs to the product owner. We embed it unchanged through QuickJS, and every new version must pass a parity check with zero mismatches before it ships.
Offline by design
Analysis should not depend on a good signal. Ingredient analysis needs no network: the engine and its data ship inside the app, and everything else is stored local-first.
No keys in the app
Anything shipped in an app can be pulled out of it. The photo reader runs on a Supabase edge function, so the API key never ships to phones.
On screen
A care routine, wash by wash


Stack
- Flutter
- Supabase
- Edge functions
- QuickJS
- Local-first storage
Our role: app, integration and backend.