Ledger
lock.cmpxchg8b.com
lock.cmpxchg8b.com
For many years I suffered through QuickBooks because I just assumed that was the Only Way. The single biggest pain point (and it's hard to pick just one) is that QuickBooks makes it absolutely mind-numbingly difficult to bulk-change any entries in your ledger -- if you categorize 1000 items one way and your accountant later tells you to recategorize them, there is NO WAY (or at least there was no way when I did this in the early 2000s) to bulk recategorize items. So I remember the pain of having to manually change thousands of entries or, worse, doing indecipherable things like making single journal entries like "moving from X category to Y category".
Discovering ledger was a breath of fresh air because the source data is just text! If you need to change data or recategorize or make any tweaks whatsoever you have the entire world of text manipulation tools at hand. You can write shell scripts and use IDEs (and believe it or not Github Copilot works REALLY well).
It's just amazing to realize that the perfect accounting solution has been there the whole time and is vastly vastly SIMPLER than I ever imagined. I went through all the SaaS tools (Xero, etc.) and nothing felt right. Ledger just works and feels right.
Suffering through QuickBooks is literally a product feature. Like, when they were porting it to the online version, bookkeepers got upset that the web version didn’t have many of the frustrating quirks of the desktop version that they’d spent decades learning to deal with. They see their having learned the bizarre ins and outs of the software as a moat that keeps their clients from doing their books themselves, so many/most require their clients to use it. And Intuit is far more responsive to the interests of CPAs/bookkeepers than it is to the end users who pay for it.
Source: I worked in Intuit’s SBG and was really surprised when I heard that from some of the product people. I’m so used to being user-focused and searching out ways to be more user friendly that it never occurred to me that, in a 3-sided market, making the software hostile to the user could be a selling point.
> and believe it or not Github Copilot works REALLY well).
And yes, this is one area where LLM can help. That valley between "manually duplicating these near identical entries is painful" and "but it's not painful enough to warrant a custom generator". LLM is often great for that kind of boilerplate. Gotta doublecheck the bejesus out of it though.
Some notes:
- The initial setup of the books is pretty time consuming especially if you have a lot of accounts. I recommend starting your most important accounts and adding as you go along.
- Mass changing categories is just a search and replace so I have been getting pretty fine grained with the categories as I go along.
- Being a small business the separation from business and personal is needed from a legal standpoint, but from a practical standpoint I live off an owner’s draw and a put cash into the LLC when investing in its growth. Having hledger have all my accounts, personal and business and being able to filter out appropriate reports has been great for seeing things like is the business a money pit or am I actually growing wealth over time.
- I combine hledger csv output with Jupyter to generate the specific reports and charts I need. I.e business specific versus combined for taxes. This filtering also has me thinking of other ideas like figuring out which credit cards to apply for based on my expenses.
Overall more fine tuned than what I have been able to achieve with Quickbooks over 8 years.
Or, at the end of the day is the default interchange format in this space just CSV?
So at some point you are going to have to deal with an accountant who will not typically know what ledger is. The solution is actually very simple: we wrote a small ruby script that generates an excel file that contains a balance and profit and loss statement in a format they are familiar with. That's the cool think about everything being text based, it's really easy to pipe the ledger output into a script and into a gem that generates an Excel file and add some styling.
The raw journal files are also in a format accountants can easily comprehend, they didn't actually look at those in our case, but if they want to know where the Excel comes from they are welcome to audit them.
Something tells me they can't be too picky about such things. My experience with the tax authorities in three countries now tells me they'll take whatever odd format data you hand them.
https://www.skatteetaten.no/en/business-and-organisation/sta...
> SAF-T Financial is a standard format used in the exchange of accounting data. SAF-T, or Standard Audit File-Tax, is the result of a joint development collaboration between the business community, the accounting sector and the Norwegian Tax Administration, based on a recommendation by the OECD.
I’ll do my part and throw in what I believe is the most popular modern take on this, beancount. I ended up going back to ledger but if the super old school interface and stack bother you, beancount might be nicer. Plus the beancount docs are just out-of-this-world good for learning double-entry accounting in general.
Docs: https://beancount.github.io/docs/the_double_entry_counting_m...
Comparison: https://beancount.github.io/docs/a_comparison_of_beancount_a...
I guess similar results might be possible with other accounting tool but Ledger perfectly meets my requirements. Also, it integrates pretty well with Emacs and I get to check my reports from there.
Includes a list of similar software and ports and their current status (active/inactive).
Outside of automatic git hooks for validation, I really only run hledger when reconciling balance with spouse or when reporting taxes.
Pick one particular "zone" of finances (eg: monthly bills) and track only that part of it for a while.
You'll figure it out!
You don't need a lot of commands to use Ledger successfully. 99% of the time, I only use one (`ledger bal`). The main thing is how to put stuff in your ledger file (and in fact, I devote most of the book to that). And, of course, the discipline to do it regularly (which I outsource to Beeminder).
Comparison of the two: https://hledger.org/ledger.html
I'm trying to start using hledger.
This [ledger's approach] totally breaks the ability to break different transaction types into different files and then import all files into a master file.
It's a common trope with less popular languages. Often when I check out some project on GitHub, the first "feature" in the readme is "written in rust".
[0]: https://hackage.haskell.org/package/hledger-1.32.3/docs/Hled...
They call out that it is hard to learn, but most of that in my experience is because people don't realize that credit cards and debit cards.
Just remember the formula:
Assets= liabilities + capital
It may be counterintuitive at first, but keeping that formula true is the requirement.
Debits on the left and are positive Credits on the right and are negative.
Using Excel and a cash basis has killed lots of companies where customers pay for services and products, which looks like income, while the related expenses haven't been paid for.
Accounting for computer scientists is a good read. it presents double entry accounting in a way that should be more familiar to us, as a graph theory problem.
Sometimes non-accounting people get hung-up on the words "debit" and "credit" and think they have to do with "owing" or "being owed" money, being "positive" or "negative", etc.
The effect of a debit or credit on the business depends on the accounts in the transaction and debit and credit don't have anything to do with the "direction" of a flow of money.
My 100-level accounting instructor summarized it as: "A debit is the entry in the left column, and a credit is an entry in the right column." Without the context of the specific accounts being debited or credited the terms themselves don't confer significant meaning.
A basic knowledge of bookkeeping and accounting terminology can confer near "super powers" when it comes to dealing with finance people. It's easy to learn and worth the time.
Double-entry bookkeeping is one of the oldest and longest-practiced "IT" disciplines. Your work probably touches revenue / expenses for your employer and someday you'll need to interface with accounting or finance people. Being able to speak the language, even poorly, has helped me gain trust and credibility that I don't believe speaking only in IT terms would have.
If you get paid $1000, your Income account gets -1000 and your Checking account gets +1000.
Background: I studied the basics of accounting on 8th and 9th grade, and acted as a treasurer or auditor in some university student associations. I accepted the traditional presentation as a given; "it'll make sense in the end".
Then I learned the negative number thing and the sums-to-zero concept and suddenly it was completely clear what was happening. Ledger manual's "Principles of Accounting with Ledger" was where this finally kicked in.
https://ledger-cli.org/doc/ledger3.html#Principles-of-Accoun...
PTA sign convention makes it very straightforward:
If the posting amount is negative it's a credit
If the posting amount is positive it's a debit.
I use this mnemonic:
debit / to / plus / left / short words
credit / from / minus / right / longer words
Lol, that'd be nice! I think you'll want to edit that.
Assets = Liabilities + Equity
Or net assets = equity.
The corollary for an accounting period
Assets + Expenses = Liabilities + Equity + Income
is more interesting. We say that the left side has a debit balance and the right side has a credit balance. It's easy to see how a few transactions work.
Pay a bill from checking, debit Expenses, credit Assets.
Buy something on credit card, debit Expenses, credit Liabilities.
Pay credit card, credit Assets, debit Liabilities.
Receive a payment for services, debit Assets, credit Income.
To close the accounts for the period, credit total Expenses to 0, debit Equity by that amount, and debit total Income to 0 and credit Equity by that amount.
Naturally, things are kept in subaccounts but this is the overall effect on the accounting equation.
Because the accounting equation has been the same for centuries.
Assets = Capital + Liabilities
https://www.accaglobal.com/gb/en/student/exam-support-resour....
Capital = Assets - Liabilities.
I can imagine GP had a similar confusion.
A - L = P
We put it on the right side to say that was the Owners value.
I never knew why they insisted on that but now I do.
So, the usual accounting equation is written:
assets = liabilities + capital
Yes, capital is similar to liabilities. It is owed to the investors (which may just be an individual).
The full equation prior to closing the books for a period is:
assets + expenses = liabilities + income + capital
For an individual, 'capital' is usually called 'net worth'.
Once the books close, (income - expenses) is moved to capital as 'retained earnings'.
In traditional, hand entered debit/credit accounting, the left hand side adds up to the same number as the right hand side. The books are balanced - the accounts on the left 'weigh' the same as the ones on the right.
In computerized accounting, the left hand side (debit) accounts are normally positive and the right hand side (credit) accounts are normally negative. There is no equation - all the accounts add up to zero, and every double entry transaction adds up to zero.
[1] - https://hledger.org
1. Open the Drafts App on my iPhone.
2. Type "lfood", which triggers TextExpander with my ledger food expense snippet [1]. I make use of the TextExpander fill-ins feature [2] to automatically set the current date and to give me a list of dropdowns that I can use to change the account, but usually I just leave the default and only fill in the expense amount.
3. Enter the expense amount, select the credit card that I used from a dropdown if it's different from the default.
4. Trigger the 'Save to Ledger' action [3] that I created within the Drafts app [4], which appends the ledger entry to my ledger file on Dropbox.
I created a short gif [5] showing this entire process in action.
[1] https://i.imgur.com/NXEimql.png
[2] https://textexpander.com/learn/using/snippets/advanced-snipp...
[3] https://i.imgur.com/LNDJNGi.png
I've been using Ledger for almost a decade (tiny single-person "company"). At one point, though, I started migrating my stuff to PTA by OpenBSD dev Ingo Schwarze [2]. It is a small Perl utility and relies on the numbered accounts system in a separate file, so I do feel more on the same page with general accounting-related discussions and corner-case howtos in my country.
I also like how PTA's reliance on account numbers also allows for a single-line oriented, very compact journal format [3]. This is great for further parsing with Unix tools. There was interesting discussion on PTA vs Ledger etc involving the author [4].FWIW, PTA is also linked on the plaintextaccounting.org website
To be fair, because of little prior experience with accounting in general, I did somewhat mess up my initial system of accounts in Ledger. So the migration to PTA is also in a standstill at this point. But it is a nice system for people in countries where the numbered chart of accounts might be preferred.
My only complaint is, the author might have written it in something as tiny and easily portable like Awk instead (for us occasional Windows users). But Perl, despite being "huge" in this comparison, is included in the OpenBSD base, and it is praised for text parsing, so the preference is understandable.
1: https://en.wikipedia.org/wiki/Chart_of_accounts
3: https://cvsweb.bsd.lv/~checkout~/pta/journal.example.en
4: https://undeadly.org/cgi?action=article;sid=20200928123430
I'm sure you can create ledger accounts that match your required chart of accounts.
The example account tree you linked to seems very business oriented, and driven by interests of stakeholders & tax authorities. Ledger gets used by private individuals too, and not everything is tracked for the goal of standard business report.
Personally for me, if I had to use such a standard account tree, then I'd need to use a second system of classification for the things I am interested in.
Example 1: I have 3 heating and 2 cooling mechanisms in this house, with very different costs to operate. Each device gets a separate account. For the pellet stove, I also need to keep track of consumption to buy the right amount of fuel before the next winter, so there's even non-currency items tracked in my accounting. That doesn't sound like it'll fit in a standard scheme.
Example 2: We own a van built as a recreational vehicle. I want to track the expenses related to that (potentially expensive) hobby, whether trips, consumables, equipment or repairs. But at the same time, it's just a vehicle, and has "normal vehicle" costs just like the regular car.
The standard alphabetic ordering of `ledger balance` isn't very useful. I created a small script to sort the output into a format where the entries are listed in a more sensible order. One solution could be (I haven't done this yet) is prefixing each account name with the number from the standard format, that should result in the ledger balance being more useful.
A small shortcoming of Ledger in relation to this seems to be that it is not very comfortable to modify your initial accounts system later on, e.g. modify the hierarchy of things when you found some mistakes, etc. In the numbered chart of accounts system (which you have in a separate file, like PTA does), this seems easier.
I would also confirm that spotting accidental data entry errors is also easier in a single-line oriented journal like PTA. In Ledger, one entry consists of at least 3 lines, which is quite verbose.
Obviously, a more seasoned diy-accountant probably simply doesn't make any errors of this kind, or automates these tasks to an extent, so there's that. :)
Nonetheless, Ledger is obviously still a remarkable piece of software. I also recall some philosophically interesting blog posts by the author John Wiegley, on maths, thinking in general or something similar. He is obviously a brilliant mind.
Reorganising an account to go in a different place is just a global search/replace across all ledger files. I would say a search/replace is easier than what you would have to do in a different accounting system, but it's also more dangerous. It's a good idea to have a bunch of asserts in place in addition to the --strict mode to make sure that "ledger balance" still produces sensible results when doing that.
Oh, this is a great find, thanks very much for pointing it out. I admit I haven't (at least not in recent years) looked into Ledger's manual, so I was not aware or had forgotten about this possibility. This one would, indeed, solve a lot of potential problems or confusion.
`2008-01-01 Opening Balance`
hledger-flow is my BFF for managing this: https://github.com/apauley/hledger-flow
Like others have mentioned plaintextaccounting.org is a great resource into the larger community.
https://ledger-cli.org/doc/ledger3.html#Principles-of-Accoun...
the data page might be as simple as
id|date|comment|from|from_amount|to|to_amount|balance_func()
then a few report pages summing the valuesI will be honest, I use ledger and I like how it can express the complex transaction, however I also have to admit that I have never used them. If I were storing my finance data in a relational database or a spreadsheet, I would be very tempted to use the simplified two party model. I probably would not actually do it, but when I am elbow deep in code making sure to handle N-Party transactions correctly, I would be tempted.
The author of the plain text accounting system(PTA) went with this simplified model and made a good case for it, one line per transaction is much easier to parse, for both the human reading them and the machine. note that PTA does support split transactions but they are the special case.
The main problem is that I don't want to give a third party access to my bank accounts, so importing into gnucash is (1) download pdf statements from bank (2) use python scripts I wrote to convert to csv (3) use gnucash importer to import.
This is fairly painful stuff, more so because my bank statements are all generated on different days of the month. So I can't form a habit of doing this regularly enough to make the data useful.
A few YouTube vids made the interface less daunting and I read a few Reddit comments on how people use it themselves, and I'm applying what I can to my own setup.
If there's anything a new GnuCash user should read or learn, please let me know!
For the past decade or so I record the transactions on the mobile version, and use desktop software to dissect the data in more effective ways.
The best my (awful) banks seem to be able to manage is old-fashioned CSV exports, so there’s little benefit from having something with the ability to call out to an API or import (US) standardised file formats.
Anyone else doing it this way? Seems to be going pretty well so far and of course doesn’t require learning a new query language. I’m sure there’s a lot more to (h)Ledger than that, though.
The only thing I'm really missing are custom fields, I slam a lot of information about transactions into comments.
Processing the CSVs takes about one second per year of my data, so what I think I'll probably do is summarize it out to ledger format each year.
I was using awk to do the CSV parsing, and it's blazing fast. But it gets a little bit unwieldy if you have to do multiple passes through a file or if a single CSV file has multiple sections. So I moved them to Python which is far more capable, but slower.
Everytime I make a transaction, I put a note on my phone. The note is a simplified version of hledger file format. Example:
24feb 12.5 cash food eating out at xx 6.5 bank1 phonebill 25feb ...
and so on. As you can see, each block is started with the date, and each line corresponds to a journal entry. In each entry, the first item is the dollar amount, the 2nd item is the credited account, the 3rd item is the debited account, and the rest will be taken as the entry description.
Every week end, I will parse this note with a Python script that I wrote, and put the output in the actual journal file. The shorthand account names in the note will be converted into actual account name (e.g. 'bank1' to 'assets:bank:bank1'), based on a dictionary file.
I'd then proceed to manually check that all ending balances in hledger match with the actual amount in the real world. (It's pretty satisfying to see the numbers match.)
After I've finished processing the note from my phone, that note will be archvied and I will start with a new note.
24feb
12.5 cash food eating out at xx
6.5 bank1 phonebill
25feb
...My preferred backend is SQL based, so it's a relatively amenable to inspection and custom tooling.
Throw away all other software, you don’t need any of that.
Excel is the worst thing ever happened to data scientists.
If sciencist knew awk/perl + gnuplot and basic C, most of the errors would't happened.
From HN: Scientists rename human genes to stop MS Excel from misreading them as dates
I do use ledger if it's for other people's money though, cus the liability of getting things wrong is higher.
My bank automatically classifies expenses and you can of course export to csv for further analysis. I have two virtual debit cards one for personal and one for business stuff so all of the stuff ledger does is fully automatic.
Sometimes accounts of same type in same country can’t be merged. I have a very stupid example: I’m unable to close Robinhood account because I own a few YNDX shares that I can’t sell or transfer. So I have it just hanging there (but excluded from my ledger)
Does your track all your loan liabilities to the penny, or how much interest accrued on your mortgage? Does it know when the rent is due and provide you a forecasted minimum balance in your checking account? Since you mentioned "business stuff": does it know the difference between an expense and an asset?
There's a time in life where simple works, but as your net worth grows "my bank handles all that" will become less and less true.
I agree with your overall sentiment, but for that specific use-case, there are tons of apps where everyone in the group can see, add, and edit the transactions live, and then square up later.
When I lived in a shared house at university, we used Splid [1], which is very easy to use yet supports advanced features like multiple currencies. If you ever find yourself needing to split expenses, I can highly recommend it.
For example, let’s say Anna, Bill and Josh start a group. Anna buys groceries, so she enters the following transaction: 30 EUR, groceries, paid by Anna, applies to {Anna, Bill, Josh}.
Then, Anna, Bill and Josh can all see (on their own phone) that transaction in the transaction log, and they can also all see that Anna’s balance is 20 EUR, and Bill and Josh both have a balance of -10 EUR.
Then, let’s say Bill and Josh go for coffee, Bill enters: 10 EUR, coffee, paid by Bill, applies to {Bill, Josh}. Then the balances become: Anna 20 EUR, Bill -5 EUR, Josh -15 EUR.
So the nice part is that because everything is synced, everyone in the group can easily add transactions and see the transaction log and balances, all from their own phone.
For Mac for example, this one is very nice: https://apps.apple.com/de/app/moneymoney/id872698314?l=en