NutriLens is an AI-assisted nutrition tracking MVP built with Expo React Native and Supabase. Users can log meals from photos, barcodes, nutrition labels, text input, recipes, or reusable templates. The app estimates calories and macros, lets the user correct everything before saving, and tracks daily totals, progress, streaks, and historical logs.
This repository is an MVP and is not a production medical or nutrition product.
- Email registration and login with Supabase Auth.
- Onboarding with height, weight, age, biological sex, goal, activity level, and weekly weight-change target.
- Mifflin-St Jeor based calorie calculation.
- Daily targets for calories, protein, carbs, and fat.
- Dashboard with today's totals.
- Meal logging by:
- photo analysis through Gemini via Supabase Edge Functions;
- barcode lookup through a Belgian-prioritized product flow;
- nutrition-label photo analysis;
- manual product entry;
- text meal input;
- recipes;
- reusable meal templates.
- Meal editing, portion scaling, meal components, swipe-to-delete, copy-to-date, and future meal planning.
- Day history with previous and future dates.
- Logging streaks.
- Progress tab with weight entries, trend graph, and weekly report.
- Light/dark/system theme preference.
- Multi-language preference UI.
- Optional local reminders.
- Privacy screen with AI-photo consent, JSON export, and account deletion.
- Offline queue for meals, weight entries, and daily targets.
- Expo SDK 54
- React Native
- TypeScript
- Expo Router
- Supabase Auth
- Supabase Postgres with RLS
- Supabase Edge Functions
- Google Gemini for vision analysis
- Open Food Facts for barcode/product lookup
- AsyncStorage for local fallback/offline state
src/
app/ Expo Router screens
components/ shared UI components
context/ app state and preferences
lib/ Supabase client
services/ AI, storage, products, notifications
types/ domain types
utils/ nutrition and navigation helpers
supabase/
functions/ Edge Functions for Gemini analysis and account deletion
migrations/ database tables, RLS policies, and RPC functions
setup.sql complete setup script for a fresh Supabase project
Requirements:
- Node.js 20+
- npm
- Expo CLI through
npx
Install and run:
cd C:\Websites\apps\NutriLens
npm install
copy .env.example .env
npm run webFor native development:
npm startThen open the project with a compatible Expo client or a custom development build.
Notes for iOS:
- A real iOS development build through EAS normally requires an Apple Developer Program membership.
- Without paying for Apple Developer, use the web build on iPhone/Safari while validating the product flow.
- This is acceptable for MVP validation, but not a replacement for a final native App Store release.
.env.example contains the public client-side values:
EXPO_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=your-anon-or-publishable-key
EXPO_PUBLIC_AI_MODE=supabaseImportant:
- Do not commit
.env. - Do not put
sb_secret..., service-role keys, Gemini keys, or OpenAI keys in Expo public environment variables. EXPO_PUBLIC_SUPABASE_ANON_KEYshould be the Supabase anon/publishable key, not the service-role key.
If EXPO_PUBLIC_AI_MODE is not set to supabase, meal photo analysis falls back to local mock data.
For a fresh Supabase project, run this file in the Supabase SQL Editor:
supabase/setup.sql
If you already ran the earlier schema, run the migrations in order:
supabase/migrations/202606220001_initial_schema.sql
supabase/migrations/202606220002_email_auth_profiles.sql
supabase/migrations/202606220003_daily_targets.sql
supabase/migrations/202606230001_meal_analysis_quota.sql
supabase/migrations/202606230002_product_catalog.sql
supabase/migrations/202606230003_profile_calorie_plan.sql
supabase/migrations/202606230004_weights_favorites.sql
supabase/migrations/202606230005_meal_portions.sql
supabase/migrations/202606230006_recipes.sql
supabase/migrations/202606230007_meal_templates.sql
The database includes:
profilesmealsdaily_targetsmeal_analysis_usageproductsweight_entriesfavorite_mealsrecipesmeal_templates
RLS policies are included so users can only access their own private nutrition data. Shared product rows are readable by authenticated users.
The app sends images to Supabase Edge Functions first. The Gemini API key is stored as a Supabase secret and is never exposed to the mobile/web client.
Configure:
npx supabase login
npx supabase link --project-ref YOUR_PROJECT_REF
npx supabase secrets set GEMINI_API_KEY=YOUR_GEMINI_KEY
npx supabase secrets set GEMINI_MODEL=gemini-2.5-flash-liteDeploy functions:
npx supabase functions deploy analyze-meal
npx supabase functions deploy analyze-nutrition-label
npx supabase functions deploy delete-accountCurrent quota behavior:
- maximum 10 AI analyses per user per calendar day;
- shared between meal-photo analysis and nutrition-label analysis;
- barcode lookup, manual entry, recipes, templates, and text meals do not consume Gemini requests.
Photo analysis is intentionally treated as an estimate. The app requires a correction/review step before saving a meal.
npm start # Expo dev server
npm run web # Expo web
npm run android # Android target
npm run ios # iOS target, requires macOS for local simulator
npm run typecheck # TypeScript check
npm run lint # Expo ESLintIf Expo lint reports a stale parser/cache issue, run:
npx expo lint -- --no-cacheThis MVP is not production-ready without more work:
- AI estimates can be wrong, especially for portion sizes, oils, sauces, and hidden ingredients.
- Gemini free-tier limits are not suitable for uncontrolled public usage.
- Nutrition data needs moderation and verification.
- Account deletion, privacy policy, terms, support, analytics consent, and abuse controls need legal/product review.
- Native iOS release requires Apple Developer Program, TestFlight validation, and App Store review.
- Payment/subscription logic is intentionally not included.
This project currently uses the license in LICENSE.