Topic · Local-first privacy

Your money doesn't need to pass through our servers.

Most expense trackers assume you upload data to a server "because that makes sync easier". True, but also a disproportionate trade-off. Balance Helper tries another route: local IndexedDB, no mandatory account, optional encrypted sync.

What local-first means in practice

When you open the app for the first time there's no login. Data goes into IndexedDB — a browser-integrated database, scoped to balancehelper.it, isolated from every other site. Close the page: data persists. Come back tomorrow: still there. No network call carries your amounts.

It also means if you close the window in incognito mode, or wipe site data, records are lost. Consistent with local-first: source of truth is your browser. For heavy users we recommend (a) installing as a PWA — on iOS, Android, or desktop — and (b) exporting a JSON backup occasionally.

Optional sync (Pro), end-to-end encrypted

People who want the same log on phone and laptop can enable sync — included in Pro. Technically:

  1. The first time you enable sync, the browser generates a random AES-GCM 256-bit key via the Web Crypto API.
  2. The key is saved in local IndexedDB. It never leaves the device.
  3. Before sending a record to the server, the browser encrypts it with the key. The output is an opaque byte blob (ciphertext + IV).
  4. On the server (Supabase), there's a row with the encrypted blob and nothing else sensitive. Amounts, notes, categories are completely unreadable.
  5. On another of your devices, after login, you import the key (export from one device, import to the other as a file). The new browser can now decrypt records.

If you lose the key, we can't recover it. The honest E2EE cost: the only way to be truly unable to read your data is not to have the key, which includes not having a recovery mechanism. The app suggests exporting the key as soon as you generate it, and treating it like a password-manager backup.

No cookies, no PII

To understand how the app is used, we collect aggregate metrics via Plausible Analytics (open-source, GDPR-friendly, no cookies, no PII). Event properties are categorical: page names, trigger types, counters. Never amounts, descriptions, or user IDs.

The only data tied to an account: email (for Google login), the plan flag in app_metadata (free or pro), and the encrypted sync rows. Nothing more.

What we don't do

  • No bank connection. We don't ask for account access. You enter the numbers manually.
  • No data sales. Even if we wanted to, we'd have nothing: we only see ciphertext.
  • No "advice". We don't suggest financial products and have no bank affiliations.
  • No AI over your numbers. No embeddings, no fine-tuning, no "AI summary of your expenses".

Estimate what concerns you

Below is a small tool to visualise what actually leaves your browser in the worst case (sync on, active session).

What leaves the browser

worst case
#
B

Common technical questions

"Is the browser safe for such sensitive data?" IndexedDB is sandboxed by origin. Other sites can't read your Balance Helper data. On a shared device, whoever accesses your browser profile accesses the data — same as a file on disk. Treat the browser session like an OS session.

"What if Balance Helper disappears?" Export the JSON backup and data stays readable without the app — cleartext, documented schema. No lock-in. Encrypted sync on Supabase obviously needs the key to decrypt; that's why E2E key export is a first-class function.

"Open-source?" The client is proprietary, but the data model is documented and the JSON export is readable. Open-sourcing the client is under consideration once stabilised.

Further reading

No account, no bank connection.

Open the app, enter your first expense. Everything stays in your browser.

Open the app