DEV Community

Cover image for How I built Foody Tracker: A local-first, zero-subscription AI nutrition app with React Native, Expo, and Gemini API
<A.BONFIGLIO/>
<A.BONFIGLIO/>

Posted on AI-assisted

How I built Foody Tracker: A local-first, zero-subscription AI nutrition app with React Native, Expo, and Gemini API

I recently published my first Android app to the Google Play Store: Foody Tracker.

Like many developers trying to keep an eye on their daily calories and macronutrients, I found myself frustrated by the current state of nutrition apps:

  • Aggressive paywalls: Basic features like scanning a plate or asking an AI nutrition question are locked behind recurring subscriptions ($10–$15/month).
  • Privacy trade-offs: Cloud accounts are mandatory, storing daily habits, photos, and health data on third-party servers.
  • Bloated UIs: Cluttered dashboards filled with ads, community feed bloat, and slow loading times.

I set out to build an alternative following a radically different philosophy: zero recurring fees, local-first data storage, and direct client-to-API communication using a Bring Your Own Key (BYOK) model.

Here is a breakdown of how it works under the hood, the architectural choices, and the lessons learned.


1. The Architecture: Bring Your Own Key (BYOK)

Running multimodal AI (processing plate photos, transcribing voice, running contextual chat) on cloud backends incurs continuous operational costs. For indie developers, this usually necessitates subscription tiers.

To avoid middleman infrastructure and provide 100% free usage:

  • Direct Client Calls: The mobile client communicates directly with Google's Gemini API endpoints using the user's personal API key.
  • Storage: The API key is stored securely in the device's persistent storage.
  • Zero Backend Overhead: No backend server or proxy sits between the user and Google. If you want to log meals via photo or voice, you simply generate a free key from Google AI Studio and paste it into the app's settings.

2. Local-First & Privacy by Default

Health data should remain under the user's control. Foody Tracker runs entirely offline-first:

  • SQLite for Persistence: All meal records, daily nutrition summaries, workout logs, and calculated metrics are stored in a local SQLite database.
  • Instant Load Times: Since the app doesn't wait for server synchronization to render the dashboard, UI navigation between days and history charts is instantaneous.
  • No Account Required: Users open the app and start tracking immediately—no sign-up forms, email verifications, or tracking SDKs.


3. The Tech Stack

  • Mobile App: React Native with Expo and TypeScript.
  • Navigation: File-based routing via expo-router.
  • Design System: Strict Flat Design (solid color palettes, clean borders, zero heavy drop-shadows or 3D skeuomorphism) with full Light and Dark mode support.
  • Landing Page: Vue 3 + Vite + TypeScript (hosted on Vercel).

4. Handling Multimodal Input (Snap, Speak, or Type)

One of the main development challenges was providing a fast meal-logging experience without friction:

  1. Snap: Snapping a picture of a meal sends the image buffer to Gemini with a structured schema prompt, extracting dishes, portion estimates, calories, and macronutrient breakdowns (protein, carbs, fat).
  2. Speak & Type: Users can type or speak casual phrases (e.g., "150g salmon with brown rice and a side salad"), and the model parses the components into structured records.
  3. AI Nutrition Coach: A conversational interface reads the current day's progress and calorie budget from local SQLite context to answer nutrition questions or suggest adjustments for remaining meals.

5. Key Takeaways & Current Roadmap

Building this project highlighted two major product lessons:

  • Onboarding Friction in BYOK Apps: Requiring users to generate an API key before trying the app is a conversion hurdle. I'm currently working on a "sample/demo sandbox" so new users can explore the interface before configuring their own key.
  • Data Portability: In local-first setups, an offline database export/import tool (JSON/CSV) is essential for users upgrading or switching devices.

Try it out & Feedback

If you'd like to check out the app or explore the UI/UX:

I would love to hear feedback on the architecture, local-first data flows, or ideas for future iterations in the comments!

Top comments (0)