How it is built

The architecture, for readers who want to know what sits underneath.


Stack

A native iPhone and iPad app written in TypeScript 5.9 under strict compilation, on React Native 0.81 and Expo SDK 54. Charts are drawn with Skia. Subscriptions run through RevenueCat and the App Store.

Where the data lives

The portfolio lives in a SQLite database on the device, queried through Drizzle ORM, and the app reads from it first. That is why it opens with no network and works offline. Changes queue locally and sync to a Supabase Postgres database in the background, every three minutes and whenever the app comes to the foreground, with realtime updates between your own devices. Row-level security limits every row to the account that owns it.

Inside the app, repositories hold the database queries, TanStack Query hooks cache and invalidate their results, and Zustand stores keep screen state that never needs to leave the device.

Privacy modes

You choose how much may leave the device. Each mode allows the following:

Cloud
Everything: sync across devices, live updates, analytics, crash reports and notifications.
Local-first
Prices, exchange rates, search and brokerage links when you ask for them. No background sync, analytics, crash reports or notifications.
Strict
Signing in, exporting your data and deleting your account. Nothing else leaves the device.

Server functions

Nineteen Supabase Edge Functions, written for Deno. Market-data calls go through them so provider keys never ship in the app and responses can be cached against rate limits. Grouped by job:

Market data
Live and historical prices, exchange rates, the risk-free rate, and price ingest.
Search
Ticker and name lookup when you add a holding.
Export and API
PDF reports, full data export, and the read-only API.
Account
Deleting the account, or deleting only its cloud copy while the app keeps working on the device; subscription events, push notifications and the contact form.

Data model

Nine asset classes: shares, funds, bonds, cash, metals, property, crypto, derivatives and a general class for anything else. Each carries its own fields. A bond has a coupon, a maturity and a payment frequency; metal is held by weight in troy ounces; property has an address and a type; a share has its ticker, exchange, sector and country. Those fields let exposure be read four ways, by class, country, sector and currency.

The transaction ledger records eleven kinds of entry: buy, sell, dividend, split, transfer, fee, capital call, distribution, return of capital, merger and spin-off. Cost basis follows a standing rule you set, first in first out, last in first out, or highest cost first. Each class has its own staleness threshold: one day for shares, funds, cash, metals, crypto and derivatives, thirty for bonds and other assets, ninety for property.

Portfolio review

The review is worked out on your phone. It checks the portfolio against limits you can set yourself, names every one it is past, and lists the trades that would bring it back, with the weight each holding ends at and the tax on each sale. Scenarios and drift use the same rules. No portfolio figure goes to an AI service, so the review works in every privacy mode, strict included, and with no connection.

Free and Pro

Free covers five holdings in one portfolio. Pro removes both limits and opens the analysis screens. Before upgrading, those screens show a sample portfolio, so you can see what each one does with real figures in place.

Testing

About 330 unit and component test files cover the app, written as given, when, then and querying the screen the way a person reads it. Forty-five end-to-end tests drive a release build on an iPad simulator with Detox, from sign-in through adding each asset class to signing out.