The end of December was also the year end of my first year with my plaintext accounting system. I now have a complete year's worth of data in my journal ready for running reports against and hopefully give me some insights into my family's spending over the past 12 months.
This isn't my first year doing home accounting, I've been a long time user of GNUCash, I was familiar with it, I was comfortable enough with it, I understood it's power and it's quirks, so why change?
I often found GNUCash quite a complex application, my home accounting needs are modest and I don't have need for a lot of it's functionality. One thing I often desired to do which GNUCash was quite poor at was making bulk edits to transactions.I would often change my mind about how I wanted to organise things but GNUCash was too rigid to make this easy.
I encountered plaintext accounting a few years ago, through the introductory web site plaintextaccounting.org which was posted on the orange site at some point. I was intrigued by the implication that I could edit my data using a standard text editor (no not that one) like Vim, which would make bulk edits very straightforward and also has the advantage of keeping my accounting data in a format that has better longevity than any other, plaintext.
Plaintext accounting isn't a single application, nor is it a single data format. It's a group of applications and formats that read and write accounting data in a parsed plaintext format rather than a database. The website lists many examples but for me it came down to just 3 choices that seemed most suitable for me: the original ledger, a more recent implementation in Haskell that uses the same data format called hledger, and a Python application that comes with its own format and a well regarded Web UI Beancount. I could see they were all good choices but I settled on hledger due to the very active development, excellent documentation and community support.
My initial set up with using hledger was on my new Windows 11 laptop, through WSL2 and my experience there was not smooth. I would often get obscure errors about encodings that didn't seem to happen on Linux proper so instead I built a dedicated Alpine VM which hosts all the data and tools I need and is accessible from whichever computer I'm using at home and this setup has proven successful.
Hledger provides tools for manually entering transactions which are very good, but my preferred method was to import from CSV files provided by my bank. To make this work you need to create a rules file that defines how hledger should read the file. The one from my primary bank for example includes some summary information a the top so in my rules file I tell it to skip the first 5 rows before it can get to the transactions and I need to tell it what column should be mapped onto each part of a ledger transaction.
I encounted another formatting issue here when hledger struggled to read the files I downloaded. After much head scratching this was because my banks CSV files are encoded as ISO8859-1, a pre-unicode extension to ASCII that provides the £ symbols important to UK users. In order to get hledger to work with these files I need to convert them to unicode using iconv -f ISO-8859-1 -t UTF-8 <csv_file>
which is a bit frustrating but I've stored it as a simple shell script so I don't need to remember much about it.
I also decided to store my data in a git repository so I can keep a revision history of my data as it changes. I could use this to synchronise my data between systems eventually but while I don't currently have a centralised git host on my home network I'm using syncthing to allow me to edit files locally on some systems if I choose to use GUI editors instead of doing everything over SSH.
I have learned many things over the course of the year, it has been a while since I kept detailed accounting records so I have been defining categories for my transactions as I go and changing my mind about naming and categorisation rules, and sometimes back again. True enough having the power of a proper text editor as well as shell scripting has made this all easy to do (with enough tooling expertise).
At the end of the year I did a lot of work to make all my journals consistent and will soon be able to close the book on the year and start afresh for 2025. I have been able to run a few reports that showed some interesting data such as the fact our average food bill has gone up 50% over previous estimates, it's highlighted that and a few other areas where we will be looking to reduce our spending next year.
For 2025 I will be going forward with the same categories i had settle on by the end of 2024 and using the same categorisation rules, which currently look like this.
expenses:banking ; banking interest payments and charges
expenses:childcare ; nursery and wrap-around care
expenses:claimable ; claimable expenses
expenses:personal ; personal luxury expenses, hobbies
expenses:food:groceries ; supermarket food and related consumables
expenses:food:service ; food with service, coffee shops
expenses:gifts ; family and friends presents
expenses:charity
expenses:home:supplies ; supplies
expenses:home:furniture ; furnishings, home electricals
expenses:home:insurance ; builds and contents, appliances
expenses:home:maintenance ; trades, hardware for repair and maintenance
expenses:home:council ; tax and bins
expenses:leisure:activities ; things we do
expenses:leisure:hobbies ; stuff we buy
expenses:leisure:kids ; kids activities
expenses:leisure:subscriptions ; streaming mostly
expenses:office ; stationary, computers, postage
expenses:healthcare ; medicines, dental
expenses:petcare ; vetinary, food if separated from groceries
expenses:auto:driving ; operating costs e.g. fuel, valeting
expenses:auto:licensing ; Legal driving costs e.g. tax and insurance
expenses:auto:maintenance ; MOT, repairs, breakdown
expenses:auto:publictransport ; planes, trains, trams, bus
expenses:utilities:telecoms ; phone and internet
expenses:utilities:energy
expenses:utilities:water
expenses:wardrobe ; clothes and hair cuts
One change from most of last year is that if I have a category that is 3 levels deep, I will not assign transactions to the second level, e.g. I could keep groceries as expenses:food
but food service as expenses:food:service
, but this made updating categories difficult and provided no benefit since hledger does not pool balances in high level categories like I initially expected it to. EDIT 2025-01-14: it can aggregate sub-balances but it isn't default behaviour, I intend to keep this change though for my other reasons.
I intend to keep fewer, larger journals which makes maintenance easier in my experience. I need to spend more time updating my accounts through the year so I don't end up catching up all the time importing months of data in one go. We also suck at tracking cash expenditure so I've started keeping a box for receipts and this can be used to record cash expenditure so it can be tracked like everything else.
There has been a decent learning curve this year but I don't think it was as steep as I was expecting. Overall it has been very positive and dare I say "fun". Keeping high quality data about something important and useful is a bit like gardening for me so I could count it as a hobby. I'm actually waiting excitedly for January's statements now so I can get started on a new financial year!