DEV Community

Naioua.d Anas
Naioua.d Anas

Posted on

How I Built a 100% Client-Side Bank Statement Parser (Zero Servers, Maximum Privacy)

The Accounting Nightmare We All Share
Every tax season, freelancer, and small business owner runs into the exact same brick wall: downloading bank statements as PDFs and realizing their accounting software needs them as a clean CSV or Excel sheet.

You’re then left with three choices:

Manually type out dozens of transactions (mind-numbing).

Pay for expensive premium software.

Upload highly sensitive financial data—containing your account numbers, home address, and spending habits—to a random third-party website that promises a "free conversion."

As a developer, option 3 felt like a security nightmare waiting to happen. So, I decided to build option 4: A fast, completely free, and 100% client-side bank statement parser.

Meet StatementFlow.

Why Client-Side? (The Tech Stack Decision)
When dealing with financial data, privacy isn't just a feature—it's the core requirement. If I built a traditional backend (Node.js/Python) to extract data from these PDFs, two things would happen:

Users would have to trust my server with their banking history.

I would have to pay for server computing power to process heavy PDF files.

By keeping everything in the browser, the user's data never leaves their machine. Your bank statements stay yours.

Here is how I structured the architecture using basic frontend tech:

The Parser Engine: Utilizing browser-native PDF parsing libraries to extract the raw text nodes from the document layout.

The Rule Matcher: A flexible regex engine that identifies common bank layouts (Date, Description, Amount, Balance) without needing a database.

The Exporter: A simple client-side blob generator that packages the clean array into a downloadable standard CSV or XLSX file instantly.

The Hardest Part: The "Wild West" of Bank PDF Layouts
If you’ve ever opened a PDF in a text editor, you know it’s a chaotic mess of coordinates, not structured text. To make things worse, no two banks format statements the same way.

Bank A might put the date, description, and amount on a single line.

Bank B might wrap descriptions into two lines, pushing the amount to the next line.

Bank C might use multi-page tables where headers repeat awkwardly.

To solve this without a massive AI model running in the cloud, I focused on building a deterministic line-by-slide scanning algorithm. By analyzing the bounding boxes of the text elements natively in the browser, the tool groups items horizontally into rows before trying to read the text. If it looks like a table row on the screen, it treats it like a table row in code.

Where it Stands Today (And It's Open Source)
I wanted this tool to be accessible to anyone who hates manual bookkeeping. It’s entirely free, requires no login, and works in seconds.

🚀 Try the live demo: bank-statement-converter.pages.dev

💻 Check out the code / Star the Repo: https://github.com/itsanssoff-source/Bank-Statement-Converter-

What's Next?
Right now, the parser natively handles standard bank layouts perfectly. I’m currently expanding it to recognize trickier credit card formats and international bank layouts.

If you are a developer, I’d love your feedback on the extraction logic! If you are a freelancer or business owner, I hope this saves you a few hours of manual data entry this month.

Let me know what you think in the comments below!

Top comments (1)

Collapse
 
johnfrandsen profile image
John Frandsen

Really nice build. Keeping the parsing fully client-side so the statement never leaves the user's machine is the right instinct here, and the privacy framing is exactly what makes people willing to actually use it.

One thing worth flagging since you mentioned expanding into "international bank layouts": reverse-engineering PDF layouts is a genuinely endless long tail. Every bank, every template, even the same bank across years renders a slightly different table — so the parser is always one layout tweak away from silently dropping a column. With financial data that matters, because a small parse error can quietly mis-categorize transactions downstream in someone's accounting. It's worth being explicit with users about that accuracy ceiling rather than presenting parsed output as ground truth.

The complementary path for your EU/UK users is that regulated banks there now expose transactions as structured JSON over open banking / PSD2 APIs — merchant, amount, currency, and booking/value dates already normalized and machine-readable, with no layout to parse at all. Because the bank hands you the data of record rather than an OCR of a presentation PDF, the accuracy problem mostly disappears, and it stays privacy-preserving in the same spirit you care about: the user authorizes access inside their own banking app (SCA), so you never touch credentials or receive a statement upload.

Where a tool like StatementFlow still clearly wins is the long tail — unsupported banks, credit-card PDFs, and historical statements that predate API access. A "try the structured API first, fall back to PDF parse" flow would be a genuinely strong UX for the accounting use case you're solving.

(Disclosure: I'm affiliated with open-banking.io, one of the cert-free ways to read those EU/UK bank transactions via API — mentioning it because it's directly relevant to the API-vs-parse tradeoff above, not as a pitch.)