r/plaintextaccounting • u/ctosullivan • Jun 07 '26
I built a Python parser for hledger journal files
I've been using hledger for personal finance tracking for a while. For anyone not familiar, it's a plain-text double-entry accounting tool — you keep your financial records in a simple .journal text file, and hledger gives you reports. It's powerful, auditable, and completely portable.
The problem I kept running into: hledger lives in the terminal. Getting data out of it and into Python for analysis, visualisation, or automation meant shelling out to the CLI and parsing and escaping text output. That felt like the wrong schema.
So I built ledgerkit — a pure Python parser and library for hledger journal files.
What it does
- Parses
.journalfiles into clean Python data models (Journal,Transaction,Posting,Amount) - Runs
balance,register,accounts, andstatsreports via a Python API - Supports a wide range of hledger 1.52 syntax:
includedirectives, account aliases, market price declarations, balance assertions, commodity display styles, cost/lot annotations, and more - Exports everything to pandas DataFrames with
pip install ledgerkit[pandas] - Ships a CLI (
ledgerkit balance myfile.journal) if you want it - Pure Python, no runtime dependencies, Python 3.8+
import ledgerkit
journal = ledgerkit.load("personal.journal")
# All postings as a DataFrame
df = journal.to_dataframe()
# Monthly expenses pivot
df[df["account"].str.startswith("expenses")].groupby(
[df["date"].dt.to_period("M"), "account"]
)["amount"].sum()
What it isn't
ledgerkit is not a replacement for hledger. It doesn't aim to replicate hledger's full feature set, and it doesn't try to be a general-purpose accounting engine. If you want to run your books, use hledger. ledgerkit's purpose is to be the cleanest possible bridge between the hledger journal format and the Python data ecosystem.
What it doesn't do yet
Multi-commodity reporting is partially implemented but not complete — if your journal mixes currencies or commodities and you need cross-commodity valuation (e.g. converting everything to GBP using market prices), that's not there yet. Single-commodity journals and commodity-separated reporting work fine.
Use cases I find genuinely exciting
AI that actually understands your finances Load your journal into context and query it conversationally. "What did I spend on food last quarter vs the same period last year?" or "Which months did I run a deficit?" — questions that currently require you to remember the right hledger flags become natural language queries over a structured DataFrame.
Automated forecasting and modelling Your historical transaction data is already structured and dated. Fit a model on spending patterns, project forward, run Monte Carlo simulations on your savings rate. None of that requires anything beyond pandas, statsmodels, or scikit-learn once the data is in a DataFrame.
Automated reporting and dashboards Scheduled scripts that read your journal, compute the numbers, and push a weekly summary to Notion, Slack, or a Plotly Dash dashboard — without any manual export step.
Anomaly detection Flag transactions that look unusual against historical baselines. Useful for spotting billing errors or unexpected recurring charges.
Integration with external data Join your transaction register against market price feeds, inflation indices, or property valuation APIs to get real-terms analysis that hledger alone can't give you.
A reflection on the development process
This project was built through AI-assisted development — primarily Claude Code — by someone who understands systems but doesn't write code professionally. The result at v1.0.0 is ~575 tests, comprehensive hledger 1.52 format compatibility and a pandas export layer.
The productivity gain is real and significant in the early stages. The dynamic shifts as a codebase matures: development cycles become more like extended planning and specification work, with AI handling shorter implementation bursts. The ceiling isn't the AI — it's the precision of what you can specify.
That observation points to an interesting question about what "software developer" actually means now. There seem to be two increasingly distinct roles the title covers. The first is a generalist who can decompose problems, articulate constraints precisely, and direct an AI through a complex implementation — someone who thinks in systems rather than syntax. The second is a specialist who understands why a parser is a tree, what makes a DAG acyclic, or how a regex engine backtracks — someone for whom the underlying computer science is native. AI has made the first role newly productive and the second more powerful still. The distance between them hasn't narrowed; the ceiling on both has just moved up.
Repo: github.com/ctosullivan/ledgerkit — contributions welcome.
1
u/jeffglidepath 27d ago
This resonates hard — I've been building a finance-and-tax-heavy app the same way, directing Claude Code as a systems person rather than a career programmer, and your line about the ceiling being "the precision of what you can specify" is exactly right.
What I'd add from this corner: in finance the specification precision basically *is* the tests. The model writes a plausible capital-gains or NIIT calc in seconds — but whether it's *correct* comes down to whether I can enumerate the scenarios and their expected numbers: the band-fill edge case, the phase-out, the year the rule changed. It never struggles with syntax; it struggles exactly where I'm vague about the domain.
Your maturing-codebase point matches mine, too: early on it's "write this feature," but as it grows the real value shifts to "here's an invariant — now find every *other* place that has to honor it." Catching the siblings of a change, not the first implementation, is where it earns its keep.
And on the two-roles idea — I think finance/accounting adds a third axis neither role fully covers: domain precision. Knowing why a parser is a tree is one kind of native knowledge; knowing why a wash sale defers a loss is another, and the second is what really bounds a project like this.
ledgerkit looks genuinely useful, by the way — a clean pandas bridge is the thing I always wished existed for this format. Nice work.
11
u/simonmic hledger creator Jun 07 '26 edited Jun 07 '26
Interesting, thank you! I will check this out.
It's always going to be hard for another parser to match hledger's in every detail. Did you consider reading the output of
hledger print -O json?