Skip to content

Fud AI

A calorie and workout tracker for iOS and Android that runs on your own AI key: photograph a meal, say it out loud or type it, and the analysis is done by whichever of thirteen providers you picked — with an on-device model as the last resort when all of them fail.

Screenshot of Fud AI
Editor screenshot, 29 Sep 2026Fud AI ↗

What it is

A local-first food, weight and workout tracker for iOS and Android, written in Swift and Kotlin. You log a meal by photographing up to ten images at once, scanning a barcode, speaking it, typing it, or asking Siri; the analysis is routed to whichever AI provider you configured — thirteen are supported, including any OpenAI-compatible endpoint — with your key held in the platform keychain. The core tracker needs no account and has no analytics, and the one first-party sync in the product is an opt-in weekly challenge that shares aggregate scores rather than logs. Exercise illustrations are a hand-drawn library of 875 animated exercises for which only a manifest ships inside the app.

Who built itOne developer, who wrote 2,142 of the repository’s 2,361 commits and registered the project as a micro-enterprise in India on 9 September 2026 under Udyam number UDYAM-DL-06-0225072. The remaining commits come from an agent account with its own GitHub identity, a dependency bot, and about a dozen other people. The app is published on the App Store and Google Play, and the first subscription was submitted alongside version 7.1.2.

How it is put together

The parts · 6

Two native clients over one shared, deliberately oversized asset corpus, with every external intelligence behind a chain the user configures. The design decision that shapes the repository is where the illustration library lives: 7,000 frames are too large to ship, so the corpus stays in the repository as the canonical copy, a small manifest travels inside the app, and the app fetches and caches individual frames from a static CDN — which keeps both store binaries under their size limits and turns an art pipeline into a delivery problem with a contract. The AI side is chain-shaped rather than adapter-shaped: a request walks the user’s provider, then the user’s fallback, then in some cases a model on the device itself, so a failed vendor degrades the answer instead of the feature. Around both, the project treats irreversible actions as things to be gated off by default and reversible local data as the norm — no account, no analytics, and one opt-in sync that carries aggregate scores rather than logs.

ios/calorietracker
464 files: an @Observable profile and store layer for food, weight, water, workouts and chat; a services layer where GeminiService and ChatService each route across thirteen providers, a speech service routes remote transcription to five vendors, and a weight-analysis service holds the forecast maths; Keychain-backed key storage; and the views, from a fifteen-step onboarding flow to charts and the coach tab. Beside it sit a Watch app, two widget extensions, a share extension, and 47 test files.
android/
A Kotlin and Compose application at 725 files, sharing the same corpus and the same routing concept, with Health Connect instead of HealthKit and its own in-app language picker. android/release holds 42 packaged artefacts and 513 MB of them.
shared/workout-vectors
7,011 files and 1.21 GB: the canonical gender-aware animation corpus, the runtime manifest, and the README that states the naming contract, the animation semantics (setup, first action, transition or maximum range, mirrored or controlled return), the shared visual language for every sequence, and the honest gap that the Other profile uses the male artwork until an inclusive set is drawn.
artifacts/workout-visual-qa
7,835 files and 1.26 GB of repair evidence: alignment reports over whole sequences (one is 8.8 MB), reviewed before-and-after frames, per-frame hash-keyed records, the accepted-repair manifests, and the README that tracks what has been accepted, what is staged outside version control, and which findings still block acceptance.
scripts/ and workers/
48 scripts for the asset pipeline, store operations and release checks, including the background-repair runner and its promotion, matte-edge and alignment suites; workers/ holds numbered generation runs whose outputs are four-frame male and female sets per exercise alongside a result file.
store/, services/ and web/
store/ is the release machinery described in its own README: catalogue files for products and subscriptions, per-platform metadata folders that are still empty, and the gate variables. services/ holds the hosted-AI proxy documentation and a Discord bot whose four registration scripts create the /ask, bug and feature commands. web/ is the marketing site with its own workflow and tests, and local-models/ carries catalogues, a verifier and the third-party notices for the on-device speech and language models.

Choices, and what they beat

  • Bring your own key, on the device over a first-party proxy through the developer’s servers

    The README frames AI access as free and keyed by the user, with the key in the platform keychain and requests going directly to the chosen provider — and it records that the earlier first-party premium proxy was discontinued, which is the earlier version of the other choice.

  • The illustration corpus stays out of the store binaries over packaging 7,000 frames into the app

    Stated with the arithmetic: Google Play caps the base module at 200 MB and the iOS build would grow by roughly 1.3 GB. So only the manifest ships, this directory remains the single canonical copy, and frames arrive from a static CDN on first use and are cached — with the exercise icon shown when the CDN is unreachable.

  • On-device analysis as the last step of the chain over ending at the provider’s failure

    On supported iPhones, food-description analysis for text, transcribed voice and Siri logs can fall through to Apple Intelligence on the device after the configured provider and fallback have both been tried, and on iOS 27 the same applies to photos the user selects. It is a stated capability with a named precondition rather than a default.

  • Every store action is off until an operator turns it on over a tag that publishes

    The release README documents that an android-v* tag builds and creates a GitHub release but does not publish, that production rollout is disabled by default, and that iOS still uploads through Xcode Cloud. Listing, screenshots and review submission are wired but gated, so the default path cannot ship anything by accident.

  • A gate that is not implemented fails the build over leaving it silently unimplemented

    Turning on the RevenueCat sync variable makes the workflow fail, because the write path does not exist yet. The README says this is deliberate: the alternative is a switch that appears to work and does nothing.

  • Nothing about the tracker syncs unless the user opts in over an account-backed app with cloud history

    The core app requires no account, runs no analytics and keeps logs local; the single first-party sync is a weekly challenge that shares a pseudonymous display name and bounded aggregate scores, requires a participant credential, deletes the profile on leaving, and expires inactive ones after ninety days. Raw logs and photos never sync.

Read fromREADME.md (32,980 characters including its annotated iOS tree and privacy section), shared/workout-vectors/README.md, artifacts/workout-visual-qa/README.md, store/README.md, .github/workflows/quality.yml, and the complete 16,512-file tree with sizes.

Build log

6 stages
  1. 01

    A published app on two stores, from one person

    The repository was created on 2026-02-04 and reached 2,361 commits by 2026-09-28, with September alone accounting for 883 of them. It carries two release lines rather than one — ios-v* and android-v* — and the newest entries on each are version 7.1.2 for iOS and 7.1.1 for Android, published within hours of each other. The app is live on the App Store and on Google Play under the package com.apoorvdarshan.calorietracker, ships in eighteen languages on both platforms, and has 445 stars and 91 forks against 27 open issues, most of them feature requests written by users in a structured template. On 9 September 2026 the author registered it as a sole-proprietorship micro-enterprise in India, and version 7.1.2 went out alongside the first subscription submission. It is a solo project with a business registration number, which is a combination this archive has not recorded before.

  2. 02

    Two gigabytes in the tree, and the reason it never ships

    GitHub reports the repository at 2.43 GB across 16,512 files, and almost none of that is source. The two largest directories are both generated: artifacts/workout-visual-qa at 1.26 GB, and shared/workout-vectors at 1.21 GB. That second one is the project’s own illustration corpus — 875 exercises, each with four male and four female animation frames, 7,000 PNGs of about 175 KB each — described in its README as the canonical source for gender-aware exercise animation, with a naming contract of <exercise-id>_<gender>_<version>_<frame>.<format> and a runtime manifest that is the single source of truth for format, frame names, frame count and the representative still. What makes the size a design decision rather than an accident is the sentence that follows: the corpus is never packaged into a store binary, because Google Play caps the base module at 200 MB and the iOS build would grow by about 1.3 GB. Only the 0.75 MB manifest ships, and the frames are fetched on demand from a static asset CDN as a plain image request with no account or device identifier, cached on the device, with the exercise’s icon shown if the CDN cannot be reached. Alongside the corpus sit 513 MB of release builds and roughly 150 MB of marketing mockups under directory names that contain spaces.

  3. 03

    A root agent and three workers repairing 7,000 drawings

    The repair pass has a README of its own, and it reads like an operations log. The library was audited and the plan was to clean backgrounds and align frames — locally, with segmentation running on the author’s Mac, no workout image uploaded and no paid image API used. The accounting is exact: 5 of 875 exercises accepted and integrated, forty reviewed PNGs present in both platforms’ assets, five review manifests pinned in accepted-repairs.json, a post-copy SHA check and a full 875/7,000 sync check, and 48 passing safety tests across the cleanup, matte-edge, alignment and promotion suites — with the caveat that visual review is still required on top of them. The remaining 6,960 frames are staged in a directory deliberately gitignored, on the principle that unfinished candidates must not enter app assets or a release; progress lives in a run-state file and per-frame hash-keyed records, and the README warns to confirm the recorded process is still alive, because a stopped run leaves behind a state that says running. The work itself was split: three worker agents alongside the root, one improving queue scheduling and reviewing a muscle group, one finishing squats, one completing a recovered rollout, with the root aligning a curl and promoting only complete accepted sets. Frames flagged as suspect are processed first but nothing is dropped, an unflagged frame is explicitly not an accepted one, and the README states outright that finishing inference is not a promise of a repaired library: source cropping, perspective, foreground protection and frame-sequence review remain separate, and no total estimate is claimed.

  4. 04

    The agent is a contributor with its own account

    Of the 2,361 commits, 153 are committed by cursoragent at cursoragent@cursor.com — an agent with its own GitHub account rather than the author’s, appearing on the contributors list beside a dozen people. Cursor also appears as a co-author on 182 commits, and the largest single trailer name in the repository is the author’s own, on 231. Claude models appear on ten commits and Copilot on three. Review is likewise a mixture: the README carries a badge for code reviews by Qodo, GitHub Copilot and Greptile, and the project holds an OpenSSF Best Practices passing badge with a Scorecard. Twelve people have landed at least one change, several of them more than five. The overall picture is a solo product whose commit history is a collaboration between its author, a commercial coding agent, and a long tail of drive-by contributors.

  5. 05

    Thirteen providers, a fallback chain, and an on-device last resort

    The AI layer is built as a chain rather than an integration. On-device you pick a provider, a model, a fallback and the speech language; thirteen are supported, from Gemini, OpenAI, Claude and Grok to Groq, Hugging Face, Fireworks, DeepInfra, Mistral and any custom OpenAI-compatible endpoint, with the key stored in the iOS keychain or Android’s encrypted preferences and requests going straight to the provider. When a request hits a 503, 529 or 429 it retries with one, two and four second backoff across both food analysis and the coach chat, so short provider spikes resolve without a visible failure. And on supported iPhones the chain does not end at a vendor: Apple Intelligence on-device analysis is the final fallback after the bring-your-own-key attempts fail, on iOS 27 it can also read a food photo locally, and on-device speech is one of six transcription options. The README also records what was removed — an earlier first-party premium proxy for hosted AI was discontinued, and the app is back to a free bring-your-own-key model with an optional paid tier alongside it.

  6. 06

    Guardrails: store releases that cannot fire by accident, and CI that checks out 200 MB of a 2.4 GB repository

    Publishing is the part of a mobile project that cannot be undone, and it is the part this repository gates hardest. Tagging android-v* does not publish to Play — it builds the app and creates a GitHub release — and every step beyond that is behind a variable that is off by default, with a table in store/README.md listing exactly which of listing copy, screenshots, review submission, production rollout and catalogue sync is wired and which is still manual. One of the variables is documented as failing the workflow on purpose: STORE_SYNC_REVENUECAT=true is an error, because the write path is not implemented, and the README says so rather than leaving a gap that looks like a feature. The iOS binary is uploaded by Xcode Cloud while everything around it is prepared locally on each tag. The continuous integration is hardened in the same spirit: workflow actions are pinned to commit SHAs rather than tags, credentials are not persisted, each job checks out only the directories it needs — which is why a web lint does not pull two gigabytes of illustration frames — and the Android job runs Gradle’s own wrapper validation against the published checksums so that a tampered wrapper binary fails the build. Quality checks run on every branch push, every pull request, and once a day at 23:03.

Adjacent records

All records →