Command Line Accounting – A look at the various ledger ports

Command line accounting – Overview

I have recently stumbled upon the idea of command line accounting. For quite a while I have now managed my books with gnucash. I am not unhappy with it, but I believe that ledger or one of its brothers may do better with the following issues:

  • File import: Since they have text files in the background, writing conversion scripts shouldn’t be too hard. Meanwhile, the gnucash importer has given me a fair amount of headache already.
  • Multiple currencies. I’m currently maintaining two gnucash files because the reports don’t handle multiple currencies in an easy way. Ledger promises to do this better.
  • Version control. It’s a text file, so you can hold it in git or mercurial and back-track what you added in a familiar (for me) way.

Ledger and its ports

Ledger is undoubtedly the first CLI accounting program. It has the largest community and can be considered the reference (for instance, in terms of text file format and  command set). It has spawned a number of ports however. Let’s take a quick look at all of them before we compare those that I consider the most interesting.

Project Language Status Comment
Ledger C++ Active Major contender
hledger Haskell Active Major contender, mostly compatible w/ ledger format
Penny Haskell Active Why Penny? explains that it has virtually no community, no  binaries
Beancount Python Active Major contender, defines new language;
One-man project, but very active
Abandon Scala Active Simpler subset of features and language;
still working towards multi-currency support.
Interesting, but not a major contender yet.
Go Ledger Go Active unclear how it improves upon ledger Perl Active in 2013 removed varying prices of commodities, Perl. Not a major contender (for me).
CL-Ledger Common Lisp Functionally complete,
but abandoned
sm-Ledger SmallTalk Proof of concept,


Ledger is still the main competitor after all these years. The main gripe I hold with it is that there are no Windows binaries of the current version and the build instructions involve a lot of steps. Consider this thread from the google group where one user builds the 3.0 version. Somehow what he shared back cannot be found anymore, only the instructions are available in the wiki. They involve swapping out a number of numerical libraries in the code and sound quite tedious however.

On the upside, ledger allows tracking of commodity price histories. It arguably has the largest community and the most import scripts.


hledger publishes binaries for all major operating systems. This makes it very unique in this field where the competitors only give build instructions sometimes. In terms of differences to ledger, the FAQ states:

  • No fluctuating price history (good or bad, I’m not sure at this point. Actually I’m leaning towards bad because I would like to track unrealized profits if possible.)
  • No budget reports (ok for me)
  • Has new commands like balancesheet, cashflow.


Beancount is a Python program and  thus cross-platform in theory. In practice, some Python programs are much easier to install than others. The installation instructions list a number of dependencies some of which will be hard to figure out on Windows systems (wget, ncurses).

Beancount compares itself to ledger here in a lengthy document. The main differences are:

  • Improved inventory tracking. Beancount identifies the cost basis of each unit individually, makes sure only units that are there can be spent and accurately tracks capital gains. Author points out that capital gains have since improved in ledger (I don’t know about hledger)
  • More strict overall: syntax: less date formats (among others), root account names enforced (assets, liabilities, etc.).
  • Order independence.
  • Internal number representation. Ledger: rational numbers; hledger: double. Beancount: decimal at parsed precision.


At this point, hledger is the only real option for me because it is the only major implementation that I can run on all my operating systems. The fact that it’s Haskell and I will thus have trouble contributing small fixes if I run into problems is a negative, of course. Lastly, one must keep in mind that all these projects share the same or at least have a similar file format. This means that you will not experience lock-in with any of them which I believe is a very important factor.