VitaCircle is live on the App Store. https://apps.apple.com/us/app/vitacircle/id6801171678
Judges: the Family Plan has a 7-day free trial, and the code SHIPATON2026 gives 3 months free — redeem it in the app under Settings → Redeem a code. No account, no login, nothing to sign up for.
Free forever: scanning, reminders, refill and expiry warnings, the medicine cabinet and the daily check-in.
Everything in the video is real and captured live. The scan is a live Gemini call on a genuinely dim Spanish pharmacy label — the ~14-second wait is shown, not cut around. The prices and the 7-day trial are read from StoreKit/RevenueCat at runtime; the trial button only appears when the store actually returns an introductory offer. Nothing is mocked. The subscription ($1.99/month, $9.99/year) buys the written weekly summary and a medication list for the doctor — never anything that keeps someone safe.
Inspiration
"Did you take your tablets today?"
Millions of us ask that question down a phone line every evening and never get an answer we can trust. The person we're asking is often tired, sometimes embarrassed, and occasionally not sure themselves.
Every medication app I looked at answered a different question. They assume a healthy adult managing their own prescriptions, with the patience to type in a drug name, a strength, a frequency, and a set of times — per medicine. My mother's kitchen drawer has eleven boxes in it. Nobody is typing that in. And the person who most needs the reminders is the least likely to set them up.
So the app had to make one promise: a photograph is the only setup.
The second thing became obvious the first time I watched somebody use it. A pharmacy label says "twice daily". It does not say 9am. Every app I tried silently decided 9am — and for a person who wakes at 5:30 and is asleep by nine, that is simply the wrong schedule, delivered with total confidence.
What it does
Line the bottles up. Take one photo.
VitaCircle reads what's printed — the drug, the strength, the instruction line, the quantity, the dates, how it should be stored — and turns it into a daily schedule built around when that person actually wakes, eats and sleeps.
It refuses to guess. A tapering course, an alternating dose, an instruction it couldn't read clearly — these are handed back to a human rather than flattened into a daily pattern. As-needed medicines are never put on a clock; they're shown with the limit the label states.
It knows what runs out, and when. The label says QTY 60 and the dose is two a day, so the pack empties in 30 days. It says "runs out Thursday" — a weekday you can act on, not a countdown you have to translate into one. Running out of a blood-pressure tablet on a Sunday is how a week of doses gets missed, and no reminder in the world fixes an empty bottle.
It reads three different dates and keeps them apart. The manufacturer's expiry on the box — usually just a month and a year, so VitaCircle stores just a month and a year and never invents a day nobody printed. The beyond-use date the pharmacy wrote on, which for a reconstituted antibiotic or opened eye drops is what actually matters and is far sooner. And the run-out date it computes itself. When one passes it says so, and points at a pharmacist. It never tells anyone to stop taking a medicine, and it never removes the dose from the schedule — most drugs keep their potency well past the printed date, and a skipped heart tablet is the far more dangerous mistake.
It remembers where they are. Asked once, not per bottle. It exists for one phone call: "Mum, they're in the kitchen cupboard, above the kettle." And because the scanner also reads the storage line, it can say the thing everybody's house gets wrong — the label says keep this refrigerated, and it's in the bathroom cabinet.
Two people, two languages. A daughter in Toronto reading English; her mother in Madrid answering a spoken check-in in Spanish. Those are set separately, in-app, without touching either phone's language. A label printed in a language you don't read comes back with the medicine's common name and its instructions translated beside the printed text — never replacing it, because what's on the bottle is what's in the bottle.
How we built it
- SwiftUI, iOS 17+, one target, no storyboards. Local-first: reminders fire offline, on a plane, with no account. A missed blood-pressure pill can't depend on a network round-trip.
- Gemini 3.6 Flash reads the labels. It is instructed to transcribe, never to advise — and explicitly forbidden from producing clock times.
- RevenueCat from the first commit, not bolted on at the end. Views never touch a RevenueCat type; a
PaywallPlanabstraction means swapping billing touches exactly one file. - OneSignal for the relational messages, tagged behaviourally — no medication name, condition or diagnosis ever leaves the device.
- String Catalogs, 15 languages, generated and audited by script.
The architecture has one rule running through it: the model may read and phrase, never count and never decide. Adherence percentages, streaks, run-out dates, dose totals — all computed in Swift. A digest that hallucinates an adherence figure is worse than no digest at all.
Challenges we ran into
"Twice daily" is not a time. Rebuilding the schedule model around a person's routine instead of a hardcoded clock was the single biggest change, and it's what the product is actually about.
A month is not a day. Calendar is lenient by default — it will happily turn month 13 into next January and 31 February into 2 March, inventing a date nobody printed on the box. Caught by a test, fixed by refusing.
One badly-typed field killed an entire scan. A liquid medicine returns "100 ML" as a string where the decoder expected a number, and a type mismatch on one field fails the whole payload. Every syrup, suspension and eye drop was unscannable. Found with a generated test label.
In-app language switching is three bugs, not one. Text follows the SwiftUI environment locale; String(localized:) ignores it and follows the system; and its locale: parameter only formats numbers — the translation itself has to come from a resolved .lproj bundle. Then every date formatter needs the same locale, or you get a fully Spanish screen that says "Thursday".
Rejected by App Review, and rightly. Not for the medical framing we'd braced for — for a missing Terms of Use link. Fixing it surfaced something worse in our own copy: the paywall was advertising sibling sharing that hadn't shipped yet. We rewrote it to sell only what the subscription actually unlocks today.
Accomplishments that we're proud of
The refusals. An app that says "I couldn't read this clearly, you set it up" is harder to build and much easier to trust. Tapering courses are refused. As-needed medicines are never scheduled. A date the label didn't print is never estimated. There is a test that fails the build if the expiry copy ever contains "do not take" or "stop taking".
And the free tier is genuinely complete for one person. Scanning, reminders, refill and expiry warnings, the daily check-in, all 15 languages — none of it is paywalled. Safety doesn't sit behind a subscription.
What we learned
That the hardest part of a caregiving app is not the AI. It's deciding what the app is not allowed to say. Every interesting decision in this codebase was a decision to do less: don't invent a time, don't invent a date, don't translate a drug name you're unsure of, don't tell someone to stop taking something.
What shipped during the hackathon
v1.0 was rejected twice — once under 3.1.2 for a missing Terms of Use link, once under 2.1(a) because RevenueCat had no In-App Purchase Key and the vendor's own diagnostic string reached the screen. Both are fixed.
v1.1 — first public release. 16 languages, the scanner, reminders, refill and expiry forecasting, the medicine cabinet, the spoken check-in.
v1.2 — shipped the day this was written:
- Typing a medicine in is now free and unlimited. Until this build the camera was the only thing in the codebase that could create a medication — one construction site, in the scanner. That made a photograph not a convenience but the only door in. It also settles what may ever be charged for: a camera that saves ten minutes can honestly carry a price; the only way to record a prescription cannot.
- The setup is skippable. Dismissing the scanner now lands on the day's screen instead of returning you to the name field forever.
- A list for the doctor — every medicine, strength and time as plain text you can send, print or take to an appointment.
- A 7-day free trial, live in all 175 territories, read from the store rather than hardcoded — a trial advertised where the store will not honour it is the same disclosure failure that got v1.0 rejected.
- Terms of Use written for this app rather than boilerplate, leading with the two sentences that matter for a medication organizer: it does not give medical advice, and a dose must never be changed because of something it displayed.
- Changing the language now applies instantly, everywhere.
One thing we removed rather than added: the paywall had been selling free users a weekly summary “sent to everyone in the circle”. There is no circle and no sharing anywhere in the code. It was describing something that did not exist, so it went.
What's next for VitaCircle
The invite loop — so the schedule genuinely is shared and a missed-dose alert reaches a sibling rather than nagging the patient again. Then iPad, then Android. Sponsor-a-Senior becomes a live public counter the moment there are paid plans to count.


Log in or sign up for Devpost to join the conversation.