Zero cloud AI
The health score, the subscription detector, merchant intelligence, forecasting, categorisation: all of it is rule-based and computed on-device. No model file. No inference runtime. No API call.
Not “encrypted in transit”. Not “anonymised”. It does not leave. The ledger is an ObjectBox database on your device, and the entire intelligence path makes exactly one request to the internet, for today’s exchange rates.
Everything. Literally everything.
One request. This one.
open.er-api.com/v6/latestA free, key-less exchange-rate feed. No API key. No account. No identifier. It sends nothing about you, and it gets back a list of numbers.
And that is the complete list.
network call in the entire intelligence path
financial fields our backend will accept
AES-GCM on every backup container
Trash, because nothing is recoverable from a server
The health score, the subscription detector, merchant intelligence, forecasting, categorisation: all of it is rule-based and computed on-device. No model file. No inference runtime. No API call.
No Plaid. No aggregator. No screen-scraping. No credentials for us to lose, because we never ask for them. WealthWise reads the SMS your bank already sent you.
There is a Control Plane. It has no transactions table and no endpoint that accepts one. It answers three questions: who is this person on a new device, did they actually pay, what should be turned on. Switch it off and the app still works.
The encrypted container is written to your own iCloud Drive or your own Google Drive folder. There is no server of ours in the middle. The key is random, per-device, and lives in the OS keychain.
The allowlist is enforced server-side. An event carrying an amount, a merchant or a note is rejected with a 400, not quietly dropped. Crash stack traces are scrubbed of paths, amounts, emails and quoted literals before they are ever stored.
Face ID or fingerprint, an app-lock timeout, and a separate balance lock with a timeout of its own. Delete is soft everywhere and Trash holds for 30 days, because a local-only app has no server copy to fall back on.
The app is fully usable with our backend switched off. That is not a fallback mode. It is the design.
Nothing in WealthWise is fetched, so nothing in WealthWise is loading. The heavy maths happens in a background isolate, the answer is cached against the ledger’s revision, and the controls you touch are the operating system’s own.
The scale is the feedback. There is nothing else: no splash, no highlight, no 300ms of ink crawling across the surface.
An imitation is a thing that looks right in a screenshot and feels wrong in your hand. So where the platform ships a control, the app uses the platform’s control.
UITabBarThe system’s own tab bar: genuine Liquid Glass on iOS 26. Not a Flutter widget wearing its clothes.
CupertinoSliverRefreshControlPull down and the activity ticks scrub in one by one, exactly the way Mail does it. Same control, same feel.
UIContextMenuInteractionLong-press gives you the platform’s lift-and-blur preview, its haptics, its timing. Nothing reimplemented.
Dynamic Type · VoiceOverInherited from the OS rather than approximated. Crank the text size and the layout actually reflows.
Opening AI Insights on a four-thousand-transaction ledger does not stall a single frame. The aggregation is dispatched to an isolate and posts one message back when it’s done. Refreshing does the same thing. The thread that draws your screen is never asked to do arithmetic.
The insights bundle is persisted to the database, so even the first open after an app restart paints instantly.
Results are keyed to the ledger revision. Same revision, same answer. Nothing is recomputed to tell you what it already knows.
The revision bumps. Only now does the aggregation re-run, and it re-runs off the UI thread.
Not a stripped-down one, not a read-only one. Every feature works with the radio off, because there was never an online mode for it to degrade from. Aeroplane, basement, dead SIM: same app.
press scale
press duration
chart intro, easeOutCubic
haptic call sites, one toggle