Inspiration

My life was spread across a budget app, a habit app, a notes app, a journal, a water reminder, and a focus timer — six apps, several subscriptions, six different ideas of what a button should look like, and not one of them aware that the others existed. My spending knew nothing about my mood. My sleep knew nothing about my focus. I was the integration layer, and I was doing it by hand.

The idea did not start as a product. I wanted that one app for myself. GraceOS is the fourth app I have shipped to Google Play — the first three taught me what it costs to build things nobody needs, and this one started with a user count of one.

Then I looked properly at everything I was competing with, and the pattern was consistent: apps that charge heavily for one feature, ship a UI that feels like a settings menu, bolt AI on as a chat bubble that does nothing, or bury the whole thing in ads.

And I watched what people around me actually did with their phones:

  • Some were badly addicted to social feeds
  • Some were plainly lonely
  • Some wanted AI but were frightened of typing their personal life into a chatbot owned by a company they had no relationship with
  • And many pay for an AI subscription every month while only using it for basics — paying for capacity they never touch

GraceOS is what I built out of those observations. One app, one design, my data on my phone, and an AI that costs me nothing to run.

What it does

GraceOS is one private app for the parts of life that usually need six apps: money, habits, journal and mood, health, focus, notes, documents, and a biometric vault. Every record lives in a local SQLite database on the phone — 56 tables, no account, no sign-up, no server of mine holding anything.

It has an AI companion, Grace, who can act rather than just talk. Say "spent 200 on groceries at Whole Foods" and the transaction is written — amount, merchant, category. Ask her to add a task, review a goal, reflect on your week. Every action she takes is undoable, because an assistant that writes to your finances has to be reversible.

Grace also listens offline. Download a Vosk speech model once and dictation — in the journal, in notes, in a conversation with her — runs with no network and nothing leaving the phone.

The app is split into two modes I designed as separate surfaces: Life for tracking and running things, Mind for focus, games, reflection, and rest.

Underneath those two words are 37+ modules, and the ones I am most attached to are not the obvious ones:

  • Mind Commits — a decision journal. You write down what you are choosing and why, and what you expect to happen. Weeks later it resurfaces and asks whether you were right, and Grace names the cognitive biases in your original reasoning. It is version control for your own judgement.
  • Letter to Me — a journal entry sealed until a delivery date you set. The content is genuinely hidden until then. A time capsule you write to yourself.
  • Practice Mode — rehearse a hard conversation with Grace before you have it. A salary negotiation, a difficult boundary, breaking bad news.
  • Dopamine Gateway — you set conditions that have to be met before a distraction unlocks. The app takes your side against your own impulse.
  • Life Documents — passports, insurance, warranties, with expiry reminders that fire before a renewal costs you money.
  • AI Academy — eight courses on using AI honestly and well, because the people most afraid of AI are usually the ones nobody taught.
  • Plus a Secrets Vault behind biometrics, relationships and cadence tracking, travel and trek logs, sleep stories, breathing exercises, ambient sound, and 19 games.
  • Original sound library — the 51 ambient tracks are AI-composed with Google's Lyria from my own prompts, not licensed stock audio. GraceOS owns every track outright.

The part that is really a design argument

The reason a single Today screen can show your habits, your spending, your mood and your focus minutes together is that one app owns all of it. That is not a feature I added. It is the only thing six separate apps can never do.

So the design had to hold across every module or the whole premise collapses. There is one shared widget library, four themes including AMOLED black and a warm sepia, and a single set of spacing, colour and type tokens. At one point I found 31 screens that had each hand-rolled their own version of the same selection chip — I deleted all 31 and replaced them with one component. Nobody will ever notice that work, and it is the reason the app does not feel like forty apps in a trench coat.

Instead of a feed

This is the part I did not expect to care about as much as I do.

Mind mode exists because the honest competitor for a quiet evening is not another productivity app — it is an infinite feed. So Mind is built to be somewhere you can go with the same reflex and come out differently: a game, a breathing exercise, a sleep story, a gratitude entry, a letter to yourself in a year. Finite by design. Nothing refreshes forever, nothing counts likes, and there is no other person in the app to perform for.

That is also why it works across ages. A student uses it for study projects and streaks. Someone in their thirties uses it for money and health. My parents' generation uses documents with renewal reminders, medication check-ins, and sleep. Nobody has to adopt the whole thing — the same app is a different app depending on which two modules you open, and none of it requires an account, which matters enormously to people who have learned to be suspicious of apps.

Who I built it for

Adults who want their whole life in one place without handing it to a company. A student tracking habits, someone managing money properly for the first time, a person who wants to journal without it being mined. Not children — the app has ads, subscriptions, and AI chat, none of which belong in a child's app.

I built the first version for exactly one user, which was me, and that is probably why the fourth app is the one that works.

How I built it

I designed the first UI/UX in Figma Make and Figma Design, then built the app with Claude Code, Antigravity, Kiro, and a lot of my own hands-on work on the final polish. Flutter and Dart, Riverpod for state, sqflite for storage. Over 3,100 automated tests, because I was one person and had no other way to know whether I had broken something.

The AI architecture is the part worth explaining, because I built it twice.

Version one: I served AI myself through AWS Bedrock and Lambda, with a per-user daily chat quota. It worked. I deleted it.

Two things killed it. Running an AI service means receiving user data — I was suddenly the company people were afraid of. And metering chats meant managing quotas, abuse, and per-user cost forever, on an app with no revenue yet.

Version two: the user brings their own key. Grace connects to any of twelve providers — Groq, OpenRouter, Gemini, Anthropic, Cerebras, NVIDIA and others — and the request goes from the device straight to the provider the user chose, under their own account. I never see it. Before a message leaves, a sanitizer swaps out email addresses, phone numbers, card numbers, and street addresses, then puts the real values back into the reply the user reads.

I also integrated on-device AI through llama.cpp, so Grace can run with no network at all. Every model in that catalogue is Apache-2.0 licensed — I removed several better-scoring models because their licences carried acceptable-use terms I did not want to hand a user along with a 2 GB download.

The monetization problem I actually had to solve

This is where RevenueCat came in, and it is my first time using it.

BYOK has a consequence I did not fully appreciate until I did the maths: I have no inference cost. Most AI apps must charge a subscription just to cover their model bills. I pay nothing per chat, so Pro is not funding my compute — it funds development. That changes what Pro can be. There is no chat limit on either tier, because there is nothing for me to ration.

So Pro sells what genuinely costs me work rather than access to the AI: every AI Academy chapter, all of Grace's personas and practice modes, every focus and sleep sound, formatted exports, restoring from a backup, themes. Monthly, annual, and a one-time lifetime purchase for people tired of subscriptions.

RevenueCat gave me three things I could not have built alone in this timeframe: entitlements that stay correct across subscription, lifetime, and restore-purchase paths; live revenue analytics across in-app purchases and ads in one place; and the ability to change what a tier contains without shipping an app update.

The ads, which I did not want

I planned to ship zero ads. I had watched apps ruin themselves with them.

My testers talked me out of it — they told me directly that I should monetise what I was giving away. So I designed ads under three rules:

  1. A payer never sees one. Every placement checks entitlement before it even requests an ad.
  2. Nothing interrupts your work. Rewarded ads are always something the user chose: a game hint, a replay after losing, the free data export. The one uninvited placement is an interstitial when you open Explore — the browse surface, never a module you are working inside — with a 50-second cooldown, so moving between modules does not mean an ad each time. Nothing appears in journal, health, finance, or a conversation with Grace.
  3. They fail honestly. No fill means no offer — the button just keeps working. Offline, it says so and points to Pro rather than failing silently.

There are no banner ads anywhere in the app.

The export placement is the one I am proudest of. Getting your own data out of GraceOS should never require a subscription — health data exports are free with no ad at all, and a full JSON backup of everything is free after one rewarded ad. The ad pays for the feature so the paywall never has to stand between someone and their own records.

The version of this I could not build

I had a bigger vision than what shipped, and the gap is mostly Android and mostly the current state of on-device AI.

Offline voices, which I cut. I had Piper wired for natural on-device speech, and finishing it meant native C++ bindings plus a voice model downloaded and cached on the phone for every voice offered. I removed it instead. The storage cost was real, the Android device voice already speaks, and shipping a second speech engine to marginally improve tone is not worth what it asks of the user. So offline runs one direction in GraceOS: Grace can hear you with no network, and she answers with the device voice.

On-device AI is real but narrow. A small quantised model on a phone is not a frontier model. It handles simple capture and reflection; it cannot reason across a year of your journal. It is also text only — a vision model needs a second projector file the runtime cannot load yet, so I list no vision models rather than let someone download 500 MB and discover it cannot see. I ship it labelled honestly rather than implying it is equivalent.

No sync, on purpose. There is no account and no server, so there is nothing to sync through. Moving to a new phone is a backup and a restore. That is a real limitation, and it is the same decision that makes the privacy claim true.

The platform sets limits I cannot argue with. Android's TTS engine silently truncates past 4,000 characters, so sleep stories had to be chunked into sequential utterances. Exact alarms are restricted to alarm-clock and calendar apps, so some reminders are best-effort by design. Background execution rules mean a tracker cannot simply run.

Breadth cost me depth. Nearly forty modules is too many for one person. Some are excellent, and some are adequate, and I know which are which. The tests are the only reason the whole thing holds together.

What I built is my best within those walls. Not the app in my head — the app that actually works on a real phone, today.

Challenges I ran into

Deleting working code. The Bedrock gateway functioned, and I removed it. That was the right call, and it did not feel like it at the time.

Being honest in the marketing. I found claims in my own paywall, privacy policy and store listing that promised things the app did not do — a module I had removed months earlier, "no ads" written before I had an ad SDK, exports described as Pro after I had made them free, "every module free forever" on a landing page for an app with a Pro tier. Auditing every claim against the actual code was slower and more uncomfortable than writing features, and I found more than I expected.

Bugs only a test could find. A test I wrote late stored 200 tags containing commas and got 400 back — every list field in the app was joined with a delimiter and split on read, so any tag, subtask, or photo path containing that character silently became two. Subtasks were worse: the completion flags are a parallel list, so one split subtask moved every checkbox after it onto the wrong line. It had been shipping the whole time quietly.

Doing it alone. No team, no reviewer, no designer. Just tests, testers, and a lot of rebuilding.

What I learned

That a monetization model is a product decision, not a pricing page. BYOK is not a technical shortcut — it is what makes it possible to charge for craft instead of charging for tokens, and it is the reason the privacy claim in my listing is true rather than aspirational.

That integration is the feature. Not any one of the modules — the fact that they share one database and one design, which is the only thing a folder of six apps can never give you.

And that shipping is a skill I did not have three failed apps ago. This one has a closed test behind it, real tester feedback in the build, and every claim checked against the code.

What's next

GraceOS is live on Google Play. Everything up to this point was built on my own judgement about what someone would want from an app like this. From here I get to find out.

The plan is depth over breadth. No new modules for a while — better versions of the ones people actually open, and on-device AI upgraded as small models get genuinely capable.

The part I am most curious about is the paywall. Because BYOK means I carry no inference cost, Pro is the one place where I am asking to be paid for craft rather than for access — and I do not yet know which of those things people will decide is worth paying for. RevenueCat lets me change what a tier contains without shipping an update, so it is a question I can answer by watching rather than by guessing.

Built With

  • admob
  • android
  • anthropic
  • antigravity
  • aws-kiro
  • claude-code
  • dart
  • ffi
  • figma
  • fl-chart
  • flutter
  • flutter-local-notifications
  • google-gemini
  • google-play-billing
  • just-audio
  • llama.cpp
  • openrouter
  • r2
  • revenuecat
  • riverpod
  • shared-preferences
  • shipaton
  • sqflite
  • sqlite
  • vosk
Share this project:

Updates

Submission history