Inspiration
Ingredient lists on skincare and food are written for chemists, not for the person holding the bottle in a shop aisle. Most "clean beauty" apps answer that with a vague traffic light and no explanation. We wanted the opposite: scan the barcode, see exactly which ingredients are restricted or banned, and see the actual regulation behind every flag so you can decide for yourself.
Then we kept noticing that skin doesn't only react to what you put on it. Diet, sleep and where you are in your cycle move the needle just as much. So Luminelle grew into one app for what goes on your skin and what goes in your body.
What it does
- Skincare barcode scan. Ingredients are checked against the EU Cosmetics Regulation annexes (CosIng) and California's lists. Every flag links to the citation, and the score is tiered by product type, so a rinse-off shampoo isn't judged like a leave-on serum.
- Food barcode scan. Same idea for packaged food: additives and restricted ingredients, with the source.
- Plate photo → calories and macros. Snap a meal and it gets logged, no manual entry.
- Skin analysis. A selfie scan maps regions of the face and tracks how they change over time.
- Cycle tracking. Phase-aware guidance and food suggestions, with a flexible model that handles late or irregular periods.
- Patterns. The part that ties it together: Luminelle correlates your food logs, products and cycle with your skin over time and surfaces the signals, including early ones before they're statistically strong.
- Missing product? Add it. Users can submit a product that isn't in the database; it's verified and served to everyone.
- Share cards. Any product or ingredient can be shared as an image card with a web landing page behind it.
How we built it
- App: Expo / React Native with Expo Router, Reanimated 4, Skia and Lottie for the animated UI, VisionCamera for scanning,
expo-ai-kitfor on-device vision. - Backend: Hono + TypeScript on Cloudflare Workers, Postgres on Supabase, with a separate notifications worker. Azure OpenAI for meal recognition and skin analysis.
- Monetisation: RevenueCat handles the Pro subscription on both iOS and Android. We use RevenueCat Paywalls (remote paywall shown dismissibly during onboarding), the CustomerInfo listener plus a server-side subscription sync for entitlement state, and RevenueCat webhooks to trigger invoicing. Paid events also generate a legally required e-invoice in Romania automatically, which we built on top of the webhook.
- Growth & ops: OneSignal for daily ritual reminders, PostHog for analytics and session replay, a Next.js site with Open Graph cards for shared products.
Challenges we ran into
- App Review rejection. Our first submission was rejected under privacy guidelines 5.1.1 for pre-permission screens and face data handling. We removed the pre-permission screens entirely, moved AI consent enforcement server-side, and dropped storing any face vectors. Approved on the next round.
- Entitlement state that lags. RevenueCat's webhook is great for the backend, but you can't make the app wait on it. Pro state now comes from a client-triggered sync right after purchase plus the CustomerInfo listener, and the webhook is only for server-side side effects.
- Scoring that's honest. A naive "count the flagged ingredients" score punished perfectly safe products. We reworked it into a tiered model: finding vs scrutiny vs unscored, product-type leniency, and a concentration threshold, so a trace ingredient no longer tanks a score.
- Ingredient data gaps. Regulatory lists are messy; natural essences and hair-dye-only restrictions produced false flags. We added a curated cosmetic ingredient layer on top of the raw source data.
- Android port. Bringing the app to Google Play surfaced native build issues (dependency hoisting, min SDK requirements for on-device ML) that the iOS build had never hit.
What we learned
- Users care far more about why something is flagged than the flag itself. The citation is the feature.
- Show the value before asking for anything: our onboarding now reveals a personalised blueprint before sign-up and before the paywall, and conversion went up.
- Every subscription state should be derivable from RevenueCat as the source of truth. The moment we tried to keep our own copy, it drifted.
What's next
Household sharing for Pro, home screen widgets, and jurisdiction-specific views so a scan in the US and a scan in the EU each show the rules that apply to you.
Built With
- azure-openai
- cloudflare-workers
- expo.io
- hono
- lottie
- next.js
- onesignal
- postgresql
- posthog
- react-native
- reanimated
- revenuecat
- skia
- supabase
- tailwindcss
- typescript
- vision-camera