DEV Community

Viktor
Viktor

Posted on • Originally published at finman.vhworx.com

I got tired of feeding my expense tracker, so I spent years building one that feeds itself

TL;DR: I built FinMan — a free personal finance app that imports any bank statement with AI, reads utility meters and fuel receipts from photos sent to a Telegram/WhatsApp bot, and tells me what one kilometer in my car actually costs. It started as a Perl script. Here is what I learned along the way.

The problem with every finance app I tried

I just wanted to know where my money goes. Simple wish, right?

I tried the popular trackers. Every single one failed me the same way: too much manual work. Enter every expense by hand. Configure categories for an hour. And almost none of them could pick up online card payments automatically — which is where most of my money actually went.

At some point I caught myself spending more time feeding the tracker than understanding my finances. So I did the developer thing: I wrote my own.

The first version was gloriously unfashionable — Perl on the backend, plain HTML and JavaScript on the front. Ugly, but mine. And it did one thing the polished apps didn't: it worked the way I lived.

Breakthrough #1: expenses that record themselves

The first real win was integrating Monobank's webhook API. Pay with the card — a second later the transaction is in my app: amount, merchant, category. No typing. No forgetting. For the first time my spending picture was complete without me doing anything.

That became the design principle for everything after: if it requires discipline, it will eventually fail. Automate the input.

Breakthrough #2: stop writing bank parsers, let AI read the statement

Other banks meant statement imports. Each bank has its own format: CSV here, PDF there, different columns, different date conventions. I wrote parser after parser — Privatbank, PUMB, Raiffeisen, Revolut, Wise, Erste, N26...

Eventually I got tired and built a different mechanism: a declarative extraction engine where AI recognizes the structure of a statement it has never seen before. Today FinMan imports any statement. New bank? No new code.

Technical lesson: the hard part wasn't the AI — it was stable payment IDs (so re-imports don't duplicate transactions) and currency handling per row. The boring parts are always the hard parts.

Breakthrough #3: the camera is the best input device

Two monthly rituals quietly ate my evenings:

Utility meters. Read the meter, subtract last month, multiply by tariff, repeat per service. Now: photo of the meter → bot → AI reads the digits, recognizes which utility service it belongs to, computes the difference and the amount due.

Car costs. I always wanted the real number: how much per kilometer — fuel vs repairs vs maintenance separately. Now: photo of the fuel receipt + photo of the odometer → the app calculates consumption (L/100km or MPG) and cost per km/mile.

The best part: the bot figures out what you sent it all by itself. Just drop a photo — no menus, no prompts, no explaining. It just knows what to do.

Breakthrough #4: numbers that don't lie

Two smaller features turned out to matter the most for honest analytics:

  • Multi-currency with stored exchange rates. My local currency wasn't always stable, so comparing March to October in it was meaningless. Every payment keeps its rate; analytics can be viewed in a stable currency across any period.
  • Excluded categories. Business projects and investments don't mix into household totals — but can still be analyzed separately. Daily spending stays readable.

From personal tool to product

Last year I rebuilt everything on a modern stack — FastAPI + SQLAlchemy 2.0 async on the backend, Vue 3 + TypeScript on the front — added family groups (shared budgets with roles), a tenant mode for landlords (your tenant sends meter photos, you stay in control), and an AI-assisted translation pipeline that localized the product into 20+ languages.

The core features are free. The tool was born free — I made it for myself first, and that's still how every feature gets tested.

Try it: finman.vhworx.com · the full story · feedback & roadmap on GitHub

What's the one manual routine in your life you'd most like to automate away? That question is where this whole project came from.

Top comments (0)