Inspiration

Where I live, a car is one of the most expensive things a family owns, and almost nobody knows what it really costs to run. Fuel receipts fade in the glovebox, the service book gets lost, the road licence expires without anyone noticing, and when it's time to sell, there's no history to show a buyer.

I tried the popular car-logging apps and they felt like spreadsheets from 2012: ads, accounts you're forced to create, and nothing that understood a car imported from Japan through Mombasa, paid for in shillings. I wanted a logbook that is private, offline-first, beautiful, and built for every car and every currency. That became Kratos XT.

What it does

  • Fuel & charging: real consumption measured tank-to-tank, cost per km, range, receipt scanning.
  • Service & wear: every service with parts and invoices, brake-pad and tyre wear projected forward.
  • Documents: insurance, licences, logbooks, with expiry reminders.
  • Trips: GPS tracking with a live map, a glowing car that follows the road, full-screen replay, trip videos, a Lock Screen Live Activity, and a tax-ready mileage log (IRS / HMRC / CRA rates).
  • Costs: total cost of ownership, cost per km over time, monthly recaps.
  • Family & devices: optional sync across phones and a web dashboard.
  • 49 languages, dark-first "luxury car" design, no ads, works fully offline.

How I built it

  • Flutter (via FVM) for iOS and Android from one codebase, using a Bloc / Repository / DataProvider architecture with GetIt.
  • Drift (SQLite) as the source of truth, with seven schema versions and tested migrations, because the data lives on the phone first.
  • Firebase (Auth, Firestore delta sync, Storage) only for the optional sharing features.
  • flutter_map + CARTO tiles for maps; native Swift (ActivityKit, AVAssetWriter) and Kotlin (MediaCodec, foreground services) where Flutter couldn't reach.
  • RevenueCat for a one-time Pro purchase, with no subscription.
  • A local CI/CD pipeline: a git hook runs the analyzer and 800+ tests, bumps the build, and ships to TestFlight and Google Play from a single commit flag.

Some of the maths is simple but easy to get wrong. Fuel economy has to be measured between two full tanks, not per fill:

$$ \text{L/100 km} = \frac{\sum_{i=a+1}^{b} V_i}{O_b - O_a} \times 100 $$

where $O_a$ and $O_b$ are the odometer readings at two full fills and $V_i$ the litres added in between. Trip distance sums the great-circle distance between GPS points, dropping any hop that implies an impossible speed:

$$ d = 2R \arcsin\sqrt{\sin^2\tfrac{\Delta\varphi}{2} + \cos\varphi_1\cos\varphi_2\sin^2\tfrac{\Delta\lambda}{2}}, \qquad \frac{d}{\Delta t} < 250\ \text{km/h} $$

Monetization with RevenueCat

Kratos XT is free to use forever for logging, with Kratos XT Pro as a one-time $9.99 purchase. No subscription, because a car logbook should not rent your own data back to you.

  • RevenueCat powers Pro on both stores from one integration: a single kratos_xt_pro entitlement, one Lifetime package in the default offering, App Store and Google Play products behind it, and the Test Store for debug builds.
  • Fair free tier: 2 cars, 20 GPS trips and 3 inspections a month, 10 cloud receipt reads a month, sharing with one person. Pro unlocks unlimited cars, the family, cloud receipt reading, trip videos, the heat map, cost per trip, wear alerts and the sale report.
  • Paywall at the right moment, never in the way: a glimpse during onboarding, the full paywall once after the first car is added, then only at "good moments" (at most 3 times, a week apart), plus a gentle reminder when free cloud reads run low.
  • Early users kept everything: anyone who used Kratos XT before Pro existed got it for life (a legacy flag), and purchases restore across devices through RevenueCat.

What I learned

  • Offline-first changes everything. Sync has to be a delta of changes recorded by SQLite triggers, not "upload the database".
  • Background location is a trust contract. iOS will suspend an app, and reviewers ask for proof. Holding a proper background session, adding a watchdog that restarts silent GPS, and showing a Live Activity made tracking both reliable and visible.
  • Release builds hide bugs debug builds don't. Android resource shrinking silently removed the notification icon, so no reminder ever fired until a diagnostics report caught it.
  • Localisation is product work. Translating into 49 languages means designing layouts that survive German compound words and right-to-left Arabic.

Challenges

  • App Store review. Background location (guideline 2.5.4) needed a clear explanation, a real on-device recording, and a feature that makes the need obvious.
  • Keeping the odometer honest when editing old records: validation had to compare against readings around that date, not today's.
  • Double taps and race conditions. Ending a trip twice once saved duplicate trips, fixed with a single in-flight stop and a loading state.
  • Doing all of it as one developer, which is why automated tests, a one-flag deploy pipeline and diagnostics reports mattered as much as features.

What's next

Automatic trip detection, CarPlay, and more of the cost insights people ask for.

Built With

Share this project:

Updates

Submission history