Work

PERSONAL PROJECT

Expense Analyzer

A bank statement goes in; a clear picture of where your money went comes out. The statement is read in your browser and never uploaded. No sign-up. No login.

Type
Personal project
Input
Bank statement · PDF or CSV
Runs
In your browser · no upload, sign-up or login
Built with
JavaScript · IndexedDB · WebLLM on WebGPU
Launch app coming soon

What it does

You add a bank statement (a PDF or CSV file). The app sorts each payment into Spent, Income, Invested or Moved, so you can see where your money went. You can check and fix anything it gets wrong.

How it works

Your statement is read in this browser, not uploaded. No sign-up. No login.

Under the hood there is no backend at all. The app is a set of static files: plain JavaScript modules with no framework and no build step. It installs as a progressive web app and keeps working offline. Every payment goes through a layered decision engine: rules that can explain themselves come first, an optional AI model comes last, and you have the final say.

How Expense Analyzer sorts a bank statementYou add a bank statement as a PDF or CSV file. Everything else happens in your browser, with no backend. The app reads the statement and removes duplicates. Then each payment goes through layers checked in order, and the first confident one decides: your earlier choices, your rules, built-in everyday words, words learned from your fixes and, last and optional, a suggestion from an AI model that runs on your device. Each payment lands in Spent, Income, Invested or Moved. You check and fix anything, and your fixes feed the history and learned-word layers. The result is saved in this browser, in IndexedDB, and works offline. You can save a backup file, optionally encrypted. Nothing is uploaded; the only download is the optional AI model.Bank statementPDF or CSVIN THIS BROWSER · NO BACKEND1 · Read the statementpdf.js · PapaParse · duplicates removed2 · Sort each paymentfirst confident layer winsHistory · your earlier choicesYour rulesBuilt-in everyday wordsWords learned from your fixesAI suggestion · optional, on-deviceSpentIncomeInvestedMoved3 · You check and fixeach category shows why it was chosen4 · Saved in this browserIndexedDB · works offlineBackup fileyou save it · can be encryptedno upload · no sign-up · no loginonly other download: the optional AI model
Everything inside the dashed box happens in your browser. Dashed arrows: your fixes teach the earlier layers.

The decision engine

  • Deterministic first. Each payment is checked against your own earlier choices, then your rules, then a built-in dictionary of everyday words, then words learned from your fixes. The first layer that is confident decides. A layer only answers when it is sure; otherwise the payment falls through to the next layer instead of being guessed.
  • AI last, and optional. If no layer is confident, a small open model (Qwen, 0.5B to 4B parameters, 4-bit) can suggest a category. It runs on your device with WebLLM on WebGPU, inside a Web Worker, and is downloaded only when you tap Download.
  • Suggestions never change totals. An AI or learned guess is stored as a suggestion. It counts only once you accept it.
  • Explainable. Every category records why it was applied (a rule, your history, your own choice or a learned word), and the app shows that reason in one line.
  • Learns from your fixes. When you fix a payment, the app records its meaningful word (for example EMERGENCYFUND) against the category you chose. After two consistent fixes it applies that category on its own. It never overrides a choice you made by hand.

Key decisions and trade-offs

1. Read the statement in the browser, not on a server

Decision. The statement is read in the browser and is never uploaded.

Trade-off. Your statement never leaves your device, so there is no server copy of it. The flip side is the next decision: without a server, nothing is shared between your devices.

2. No sign-up, no login, saved only in this browser

Decision. There are no accounts. Your data is saved only in the browser you used.

Trade-off. You can start straight away, with nothing to register. The cost is that your data won't appear on your other phone or computer, and clearing browser data can delete it. That is why the app asks you to save a backup file after your first statement.

3. Four clear categories, and you have the final say

Decision. Every payment lands in one of four categories: Spent, Income, Invested or Moved.

Trade-off. Four categories keep the picture simple enough to read at a glance. Automatic sorting can still get a payment wrong, so you can check and fix anything it gets wrong.

4. Rules first, AI only as a fallback

Decision. Rules and learned words decide whenever they are confident. The AI model is only asked about what is left.

Trade-off. Rules leave more payments unanswered, so you check a few more by hand. In return, every automatic answer is predictable and explainable, and the app works fully on devices that can't run a model.

5. An on-device model, not a cloud AI service

Decision. The AI model runs in your browser, so a payment's description is never sent to an AI provider.

Trade-off. The model is a large one-time download and needs a device with WebGPU. So it is opt-in and checked against the device's capability first. Only one model runs per browser, watchdogs stop a model that hangs, and a model that crashed is not started again automatically.

Privacy and reliability

  • No backend and no analytics. A Content Security Policy allows only the app's own files plus the hosts that serve the optional model, and no transaction data goes to them.
  • Backups you control. You can save a backup file, optionally encrypted (AES-GCM-256 with a key derived by PBKDF2), or turn on automatic backups to a folder, because browser storage can be cleared.
  • Tested in a real browser. The tests use Python and Playwright, in headless Chrome with WebGPU.

Stack

JavaScript (ES modules, no framework) · IndexedDB (Dexie) · pdf.js · PapaParse · WebLLM on WebGPU · Web Workers · Service Worker (PWA) · Web Crypto · Python + Playwright

Next case study: Multi-Agent Code Review & Auto-Debugging System