Some time ago I mentioned having built a very simple web app to help me with budgeting with Ledger. Let me share it with you right now. It is extremely simple – the whole app resides in just one index.js
file which has less than 150 lines of code, and over half of it is boilerplate code or code related to authentication (which is very simplistic anyway).
The code is not something I would be especially proud of, but it doesn’t matter - it is but a simple hack put together in a few hours. It would probably be better to use the csv or xml export of Ledger instead of trying to parse the default format. Part of the config file is the list of Ledger command-line parameters, some of which (like --flat
) are essential for the app to even work. This is a terrible practice in “serious software”, since it means that putting legit-looking (but unexpected by the code) things in the config might break the app. It uses the execFileSync
function to run Ledger. This is another terrible practice, since it is a blocking function. This means that my app would most probably scale very poorly – Ledger is fast, but might not be fast enough. On the other hand, I knew that this app would be used by two users (possibly twice as much assuming it survives long enough for my kids to grow up and use it on a regular basis). Not “two users simultaneously”, mind you – two users altogether. Hence I decided – in a true situated software approach – that it’s not worth it to deal with any unnecessary complications, and execFileSync
is just simpler than dealing with callbacks or promises (even with async/await).
The most important question you could ask, however, is why not use Ledger’s budgeting capabilities? Well, even though I spent some time learning how to use them, I still find them a bit cryptic. More importantly, I wanted something a bit more fancy than what Ledger seems to offer. For each expense account included in my budget, I wanted my app to tell me more than just whether I’m still within the budget or not. For some categories of expenses, it is good to have “two” limits – a “soft” one (which my app calls “safe”) and a hard one. If I spend more than the soft limit, the bar for this category is shown in yellow; if I spend more than the hard limit, the bar is shown in red, which is a nice way of visualizing categories which are still within limits, but which should be treated with more care, so to speak.
Some categories, however, are treated in a yet another special way. There are things you spend money on once per month, like internet bills. For these categories showing the budget and the expenses so far is fine. Many categories, however, are things I spend money on every day (or almost every day), like food. For these ones (denoted in the config by the safe: 'linear'
option) the “soft limit” is just the fraction of the “hard” limit corresponding to the fraction of the month that passed to this point. This way I can set a budget for food and see if I’m within the budget every single day, which I find tremendously useful.
As I said, the app is very simplistic. For example, it always shows the budget for today – there is no way to see the budget for any other day (or month, for that matter). I might change it in the future, so that it could show for example the budget for the past month (or maybe even, say, current year) – but for now, it is perfectly enough for me.
Ah, did I mention? The app is in Polish, and all the strings are hardcoded in the view files. Sorry for that if you don’t speak Polish…
Edit: added the link to the app repo.