Inspiration
My day was scattered across six apps. Tasks in one, expenses in another, a notes app for whatever I was turning over, and a breathing app I opened twice and then forgot about. None of them knew the others existed, so the only place any of it came together was in my head, which is exactly the place I wanted it to stop living.
Two things made me build rather than keep shopping.
The first is connectivity. I build from India, where patchy signal is normal rather than an edge case, and almost every life-management app I tried was cloud-first. The moment the bars drop they show a spinner, and an app that cannot be trusted on a train is not somewhere you put your day.
The second is the khata. Families here keep a running book of who owes what, and it is a genuinely social ledger rather than an accounting one. Every app that touched it wanted to become a payments product, take a cut, and turn a note between two people into a transaction. I wanted the book, without any of that.
What it does
Clear Path holds nine parts of a day in one place, grouped into three areas.
Daily practice. Tasks with real recurrence, where completion is tracked per occurrence so yesterday's tick never hides today's work. Focus sessions you can name and save as templates. Zen, a guided breathing session for the gap between two things.
Reflection. A one-tap daily mood check-in that turns into a readable month. Thoughts, a local-first notebook. A dashboard that puts momentum, today's mood, the remaining tasks and recent spending on one screen.
Money. Expense capture in seconds, including scanning a UPI QR code to prefill the form, with bill splitting that does the arithmetic. Budgets as a boundary per category, with a ring that closes as you spend. And the ledger, a running balance per person that settles to zero.
The whole thing is offline-first. The local database is the primary copy, not a cache, so every feature works with no signal and syncs when there is one.

How we built it
Flutter, one codebase, 233 Dart files and roughly 85,500 lines across 589 commits since 11 February 2026.
Storage is local-first by design. Writes land in SQLite on the device and mirror to Cloud Firestore, rather than the other way around. That ordering is the single decision the entire offline story rests on.
Firebase Authentication handles identity, including Google sign-in, and the app never sees a password.
AI is Gemini 2.5 Flash Lite through Firebase AI, used for optional things only: drafting a task breakdown, improving note text, and parsing a dictated task. Every call is metered against a daily budget.
Subscriptions run on RevenueCat, wired server-authoritatively. A purchase triggers a RevenueCat webhook, the official RevenueCat Firebase Extension writes the customer document into Firestore, and the app streams that document to derive entitlement. There is no custom Cloud Function anywhere in that path, because the Extension's native document shape is already the contract. Firestore rules make that document read-your-own and never client-writable, so a modified client cannot grant itself Pro. Entitlement is cached in preferences so it survives being offline. I built the paywall myself rather than using the prebuilt one, so it matches the app's design.
The monetization line. Free gives you 100 tasks, 200 expenses, 6 accounts, one signed-in device and 4 AI calls a day. Pro raises those to 300 tasks, 600 expenses, 18 accounts, five devices and 8 AI calls a day, and adds cloud sync for notes and the ledger. I drew the line so the free tier stays genuinely usable for months instead of expiring into a trial. Pro sells continuity across devices and headroom, not access to the app.
Challenges we ran into
Pro users saw Free on the web build. The entitlement document was sitting in Firestore the whole time. The cause was ordering: I awaited the RevenueCat login call before starting the Firestore listener, and on web the SDK is deliberately unconfigured, so that call hangs and the listener never starts. Reading the entitlement only ever needed Firestore, never a configured SDK, so the fix was to start the watch first and treat the login as best-effort.
A test key force-closes a release build. Moving from the Test Store to a real build, the app died instantly on launch with almost nothing useful in the log. RevenueCat rejects a test key in a release binary by design, which is correct behaviour and completely invisible until it happens to you. Keys now come from build-time defines rather than a bundled file, so debug and release cannot pick up each other's credentials.
Recurring tasks looked finished forever. Completing one made it vanish the next day. The model carries a legacy boolean that means "was completed at some point", while the real truth is a set of completed dates. Filtering on that boolean in SQL dropped tasks that were genuinely pending today, before any correction could run. I moved completion filtering out of SQL entirely, then found the same assumption had quietly broken alarm scheduling in four more places.
Voice capture silently lost every detail. Saying "read 30 pages every day at 9 PM" saved a task called "Read" with no time, no recurrence and no goal. The confirmation chips read correctly, which made it look like an AI accuracy problem. It was plumbing: the field showed the cleaned title, and the save path was parsing that field instead of the original sentence. Now the raw utterance is kept and parsed, and the AI result merges over the pattern-matched one rather than replacing it.
Accomplishments that we're proud of
An entitlement a client cannot forge. Pro status is written by a webhook and read under rules that forbid client writes. Patching the app does not buy you anything, which is a property I would want even on a much larger team.
Offline-first that genuinely holds. Not a cache with a sync button. Every feature writes locally first and reconciles later, so the app behaves the same on a train as on wifi.
One dictated task costs one AI call. The suggestion chips and the save path share a single parse, keyed by the spoken phrase, instead of billing the budget twice for the same sentence. Editing the title afterwards does not re-parse. On a budget of four free calls a day, halving the cost of the most-used AI feature is the difference between a limit that feels generous and one that feels stingy.
113 test files, concentrated on the seams that broke: recurrence, entitlement and the voice pipeline.
Six months, solo. Design, Flutter app, Firebase backend, subscription infrastructure, Android home-screen widgets and this website.
What we learned
A derived column will eventually lie to you. The recurring-task bug and the alarm bug were the same misplaced trust in a convenience flag. When I renamed it to say plainly that it means "was ever completed", the remaining misuses became obvious on sight. Naming a field after its actual meaning is cheaper than any comment warning people about it.
Ordering bugs hide on the platform you test least. The RevenueCat login problem was invisible on Android and total on web. Anything awaited during sign-in is a place where one platform's no-op is another platform's deadlock.
Read the sponsor's failure modes before you need them. The test-key crash cost me an evening and was documented behaviour the whole time. Skimming the release checklist earlier would have turned it into a five-minute configuration step.
Meter AI where the work happens, not where the call happens. Budgeting per API call would have charged users twice for one sentence. Caching the parse by phrase let me set a smaller free limit that still feels fair.
What's next for Clear Path
Google Play production. The subscription backend is verified end to end against the Test Store. What remains is Play Console products with per-currency pricing and the service account that links Play to RevenueCat, which by all accounts is the step most likely to go wrong.
Purchasing on the web, which needs RevenueCat Web Billing. Until it is live the web paywall says so honestly and points people to mobile rather than showing a button that cannot work.
iOS. The code is already platform-agnostic, so this is store setup and testing rather than a rewrite.
Shared tasks. The schema for assigning a task to a friend is in place but nothing delivers it yet, and I would rather ship it with the privacy wording and anti-spam rules written first than bolt those on afterwards.
Regional pricing that reads correctly everywhere, which the app already supports through store-driven prices and needs no code change once the products are configured.