AI calorie tracker like Cal AI, MyFitnessPal and Lose It!
Snap a meal, get calories and macros from a real vision model, and hit a daily target built at onboarding. Seeded with six weeks of meals and weigh-ins.
- Free template
- Expo and Supabase
- iOS, Android, web
- Your own copy of the code








Screens built and filled with data




Workflows end to end
- Get a plan
- Snap a meal
- Log from the database
- Scan a barcode
Tables already designed
Access rules on every table
Every row is its owner's alone (meals, items, weigh-ins, profile); items can only be attached to the user's own meals (owns_meal); the food catalogue and sample photos are read-only; restrictive storage policies keep each user in their own photo folder.
Supabase row-level security
Sample rows so no screen starts empty
- weight_logs52
- foods50
- meals6
- sample_photos3
- profiles2
Features
Everything the app does, on day one
AI meal scan
Take or pick a photo and get the dish, every item with its portion, calories, protein, carbs, fat and a health score, from a real vision model.

Editable breakdown
Fix any item, add or remove items, change servings and the meal type before logging, and edit or delete it later.
Daily target from onboarding
Goal, sex, birth year, height, weight, activity and pace become a calorie target and macros (Mifflin-St Jeor), with a goal date.
Calorie and macro rings
Calories left and protein, carbs and fat left for any day of the week, turning red when you go over.
Food database and barcode
Search 50 foods or scan a packaged product (simulated scanner), pick the quantity and log it.
Manual entry
Log anything by name with its calories and macros, with an optional photo.
Weight progress
Log weigh-ins, see the trend chart, your BMI and how far you are toward your goal weight.
Calorie history
Daily calories against your target over 7 or 30 days, and your average macros.
Streaks
A day streak, your best streak and a calendar of every logged day.
Customize with prompts
Make it yours in one sentence
Pick what to change first. Your copy opens in the editor and the AI starts right away, changing this app in place.

Make it yours
You get your own copy of AI calorie tracker. Tell the AI what to change first.
Themes and icons
Your look, before the first prompt
Pick a theme and an app icon. Your copy is made in them: no prompt, no credits.


Theme
App icon
Your copy starts in this look. It is one theme file, so every screen changes together, and you can keep adjusting it with prompts.
One prompt later
“Call it Nourish, make the brand colour emerald green, and add a water tracker card on Home with a daily goal of 8 glasses”
A real run on this template. One turn renamed the app, recoloured every screen and added the field to the database.


Workflows
What people can already do in it
Pick one to walk through its steps on the screen it happens on.






Calorie and macro rings
Under the hood
A real full-stack app, not a mockup
For the technical side: how it is built, the database, the code itself and the stack.
The editor writes a real app. The app talks to its own Supabase backend, and the same code runs on phones and the web.
RapidNative editor
The AI writes the code, schema and sample data
Your app
Expo SDK 57, React Native, 17 screens
Supabase backend
Supabase: Postgres (6 tables, 26 access rules), auth, storage, API routes
Runs on
iOS, Android and the web
6 tables, linked the way the app works. Every row is its owner's alone (meals, items, weigh-ins, profile); items can only be attached to the user's own meals (owns_meal); the food catalogue and sample photos are read-only; restrictive storage policies keep each user in their own photo folder.
profiles
2 sample rows
foods
50 sample rows
meals
6 sample rows
weight_logs
52 sample rows
sample_photos
3 sample rows
meal_items
empty
Slices of this template's own files. Your copy is a standard Expo project: change it in the editor, by prompt or by hand, or, on a paid plan, download it and keep going in your own editor.
51export default function HomeScreen() {
52 const { user } = useAuth();
53 const params = useLocalSearchParams<{ day?: string }>();
54 const uid = user?.id ?? '';
55
56 const { data: profile, isLoading: profileLoading } = useMyProfile();
57 const { data: loggedDays } = useLoggedDays();
58
59 const today = startOfLocalDay(new Date());
60 const todayKey = dayKey(today);
61 const initialDay = params.day && /^\d{4}-\d{2}-\d{2}$/.test(params.day) ? startOfLocalDay(new Date(params.day + 'T00:00:00')) : today;
62
63 const [selectedDate, setSelectedDate] = useState(initialDay);
64 const [weekOffset, setWeekOffset] = useState(0); // 0 = current week
65
66 // Keep selected day in sync when a logging flow navigates back with a `day` param.
67 useEffect(() => {
68 if (params.day && /^\d{4}-\d{2}-\d{2}$/.test(params.day)) {
69 const d = startOfLocalDay(new Date(params.day + 'T00:00:00'));
70 setSelectedDate(d);
71 setWeekOffset(weekOffsetFor(d, today));
72 }
73 }, [params.day]);
74 const [sheetOpen, setSheetOpen] = useState(false);
75 const [refreshing, setRefreshing] = useState(false);
76
77 const selectedKey = dayKey(selectedDate);
78
79 // Week navigation: start of the displayed week (Mon), clamped to never past current week
80 const currentWeekStart = startOfWeek(today);
81 const weekStart = new Date(currentWeekStart);
82 weekStart.setDate(weekStart.getDate() - weekOffset * 7);
83
84 const weekDays = useMemo(() => {8export function useThemeColor(token: `--${string}`, { alpha = 1, shade = 0 } = {}): string {
9 const { colorScheme } = nativewind.useColorScheme();
10 const native = useNativeVariable(token);
11 const vars = (colorScheme === 'dark' ? theme.darkTheme : theme.lightTheme) as Record<string, any>;
12 const raw = String((Platform.OS === 'web' ? (vars.__cssVars ?? vars)[token] : native) ?? '');
13 const rgb = raw.trim().split(/\s+/).map(Number);
14 if (rgb.length !== 3 || rgb.some(Number.isNaN)) return `rgba(127,127,127,${alpha})`;
15 const to = shade < 0 ? 0 : 255;
16 const [r, g, b] = rgb.map((c) => Math.round(c + (to - c) * Math.abs(shade)));
17 return `rgba(${r},${g},${b},${alpha})`;
18}7create policy meal_photos_own_folder_insert on storage.objects as restrictive
8 for insert to authenticated
9 with check (bucket_id <> 'meal-photos' or (storage.foldername(name))[1] = auth.uid()::text);
10
11drop policy if exists meal_photos_own_folder_update on storage.objects;
12create policy meal_photos_own_folder_update on storage.objects as restrictive
13 for update to authenticated
14 using (bucket_id <> 'meal-photos' or (storage.foldername(name))[1] = auth.uid()::text)
15 with check (bucket_id <> 'meal-photos' or (storage.foldername(name))[1] = auth.uid()::text);
16
17drop policy if exists meal_photos_own_folder_delete on storage.objects;
18create policy meal_photos_own_folder_delete on storage.objects as restrictive
19 for delete to authenticated
20 using (bucket_id <> 'meal-photos' or (storage.foldername(name))[1] = auth.uid()::text);13export const lightTheme = vars({
14 '--radius': '16',
15 '--background': '255 255 255',
16 '--foreground': '17 17 19',
17 '--card': '246 246 248',
18 '--card-foreground': '17 17 19',
19 '--popover': '255 255 255',
20 '--popover-foreground': '17 17 19',
21 '--primary': '17 17 19',
22 '--primary-foreground': '255 255 255',
23 '--secondary': '238 238 241',
24 '--secondary-foreground': '17 17 19',
25 '--muted': '241 241 244',
26 '--muted-foreground': '118 118 128',
27 '--accent': '255 99 51',
28 '--accent-foreground': '255 255 255',
29 '--destructive': '229 57 53',
30 '--destructive-foreground': '255 255 255',
31 '--border': '232 232 236',
32 '--input': '228 228 233',
33 '--ring': '17 17 19',
34 '--chart-1': '124 92 252',
35 '--chart-2': '56 160 245',
36 '--chart-3': '245 166 35',
37 '--chart-4': '34 197 94',
38 '--chart-5': '17 17 19',
39 ...themeFonts,
40});
41
42export const darkTheme = vars({
43 '--radius': '16',
44 '--background': '10 10 12',
45 '--foreground': '250 250 250',
46 '--card': '24 24 28',Sample data: Demo accounts (password rapidnative-demo): demo@rapidnative.com (Maya Brooks: onboarded nine weeks ago, 74.0 to 70.4 kg toward 65 kg, a 1,730 kcal target, 42 days of meals with photos and a 12-day streak) and sam@rapidnative.com (Sam Carter, a few meals and weigh-ins). 50 foods including 8 packaged products with barcodes, 153 meals with 575 items, 26 weigh-ins and 3 sample photos. Good to know: AI photo analysis is real: it runs on the platform's AI service through api/index.js. Portions are estimates, and the review screen says so. Barcode scanning is simulated: sample products and typed codes look up the seeded catalogue. A camera barcode scanner (expo-camera) plugs in on the barcode screen, and a nutrition database API in src/lib/queries.ts (useFoods, useFoodByBarcode). The food database is a seeded catalogue of 50 foods. No notifications or reminders are sent.
- Framework
- Expo SDK 57, React Native 0.86.3
- Navigation
- Expo Router 57.0.18, file-based routes
- Data
- TanStack Query 5.90.16
- Styling
- NativeWind 4.2.1, one theme file
- Database
- Supabase (Postgres), row-level security on every table
- Auth
- Email and password
- Server code
- API routes in api/, deployed with the app
- Language
- TypeScript 6.0.3, strict
- Platforms
- iOS, Android, web
- Ownership
- A standard Expo project; download the full source on the Starter plan and up
Screens
Every screen, built and filled with data
17 routes: /, /progress, /settings, /barcode, /food-search, /food/[id], /goals, /log-weight, /manual, /meal/[id], /onboarding, /profile, /scan, /streak, /weights, /login, /signup.






How it works
From template to the App Store
- Step 1
Use the template
You get your own copy in your account, running in the editor with its data.
- Step 2
Tell the AI what to change
Rename it, restyle it, add features. It edits this app; it does not start over.
- Step 3
Run it and ship it
Open it on your phone with a QR code, then publish to the App Store and Google Play.
Questions
Before you start
Is the template free?+
Do I own the code?+
Can I publish it to the App Store and Google Play?+
What is mocked?+
Can I use my own backend?+
Is this affiliated with Cal AI, MyFitnessPal or Lose It!?+
Your app, already started
Free to start. Your copy, your name, your brand, and the AI ready to change any of it.
Not affiliated with or endorsed by Cal AI, MyFitnessPal or Lose It!. Each is a trademark of its owner.











