Project 01Assurance tooling
Bank
ReconciliationMatch a bank statement to the cash book, classify every reconciling item, and produce the statement and adjusting entries.
A bank reconciliation proves that the cash balance in the books and the balance at the bank are two views of the same money. This tool does the mechanical part the way a junior accountant would: match by cheque number first, then by amount and date, then investigate what's left. It ships with a month of invented data for a student club so you can see it work before pasting your own.
- Inputs
- Bank statement CSV and cash-book (GL cash account) CSV
- Matching
- Cheque number → amount + date window → cheque-number discrepancy → manual
- Outputs
- Two-sided reconciliation statement, classified reconciling items, proposed adjusting entries, CSV export
- Sample data
- Forest City Seniors Connect (fictional club), March 2026
- Privacy
- Static page, no server. Parsing and matching run in your browser; nothing is sent anywhere.
Step 01Load data
Bank statement and cash book
Paste a CSV export into each box, drop a file, or load the sample. Columns are detected from the header row (dates, descriptions, withdrawals and deposits, or a single signed amount). Cash-book entries dated before the statement period are treated as items brought forward from the last reconciliation.
Recognised headers: date, description, withdrawal/debit, deposit/credit, or amount (deposits positive), optional balance.
Recognised headers: date, ref/cheque, description, party/payee, category, receipt/debit, payment/credit, or amount (receipts positive).
Step 02Results
Reconciliation
Only items the bank knows about and the books don't get a journal entry. Outstanding cheques and deposits in transit are timing differences: the books are already right, the bank just hasn't caught up.
Step 03Review
Matching workbench
Every line, with how it was matched. Select one bank line and one cash-book line to match them by hand (different amounts become a discrepancy), or unmatch a pair the engine got wrong. The statement above updates immediately.
The accountingWhy it works this way
What a bank reconciliation proves
The cash account in the general ledger and the bank's statement should describe the same money, but they never agree on a given day. Cheques the club has written haven't all been cashed. A deposit made after the branch closed shows up tomorrow. The bank charged a fee nobody has recorded yet. A reconciliation lists every one of those differences, and when the two adjusted balances agree, you have evidence that both records are complete and that nothing is missing or invented. It's one of the first controls an auditor tests, and it's the first thing I'd want in place as a treasurer.
Two sides, two kinds of difference
The statement is built in two columns. On the bank side, start from the balance per the statement and adjust for things the books know about but the bank doesn't yet: add deposits in transit, deduct outstanding cheques. These are timing differences, and the books need no entry. On the book side, start from the balance per the cash book and adjust for things the bank knows about but the books don't: interest earned, service charges, NSF cheques that bounced, and errors in the books. Each of these needs a journal entry, which is why the tool proposes them.
Why cheque numbers come first
Descriptions are unreliable: the bank says POS PURCHASE FRESHMART #114 and the books say "Refreshments — St. Patrick's social."
Amounts alone are ambiguous when two reimbursements happen to be $36.00. A cheque number is a unique identifier that both records share,
so it is the strongest key. Only after cheque matches are exhausted does the engine fall back to exact amount within a date window
(default seven days, because a cheque written on the 27th may clear in the next month), choosing the closest date when there
are several candidates.
The transposition rule
When a cheque number matches but the amounts differ, one side has an error. If the difference divides evenly by nine, the tool flags a probable transposition: $65.40 written for $56.40 is off by exactly $9.00, and swapping any two digits always produces a difference divisible by nine. The sample data plants one of these on cheque 1046. If one amount is exactly ten or a hundred times the other ($50.00 recorded as $5.00), the decimal point slid instead. Neither rule proves anything, but both say where to look first.
Items that deserve a second look
- NSF cheques. A deposit that bounced reduces cash and reinstates the receivable from whoever wrote it. The bank usually adds a fee on top, which is a separate expense.
- Stale-dated cheques. Anything outstanding for more than six months has probably been lost. It should be investigated and, if appropriate, cancelled and reissued rather than left on the list forever.
- Unexplained bank debits. A withdrawal the books don't know about is either an unrecorded payment or something worse. It goes to a suspense account until identified, never straight to an expense.
- Brought-forward items that never clear. The tool treats cash-book entries dated before the period as last month's outstanding items. If one still hasn't cleared, it stays on the list and is flagged by age.
The control around the tool
A reconciliation is only evidence if the person preparing it isn't the person who signs the cheques or makes the deposits. In a small club that separation is hard, so the next best thing is a second signature on the finished reconciliation and a copy of the bank statement obtained independently. Auditors do the same at scale: they confirm balances directly with the bank and test the outstanding items against the following month's statement to check they really did clear.
How it's builtNotes
One self-contained HTML file, no libraries, no build step, no server. The CSV parser handles quoted fields, embedded commas, tab and semicolon delimiters, and detects columns from header names rather than positions so a bank export with different column order still loads. Dates are parsed as ISO, day-first or month-first, auto-detected from the data with a manual override. Amounts are handled in integer cents to avoid floating-point drift; the matching engine runs in three passes and exposes every decision in the workbench so a reviewer can override it.
- Stack
- HTML, CSS, vanilla JavaScript
- Dependencies
- None (fonts from Google Fonts)
- Data handling
- Entirely client-side; nothing leaves the page
- Limits
- Single account and period per run; no persistence between visits by design
- Sample
- Forest City Seniors Connect, a fictional student club. All names, vendors and figures are invented.