Ledger CLI is an open source command line accounting tool used for calculating reports from a ledger (a file containing a list of transactions for different accounts). With Ledger CLI you are able to view a register (a list of transactions), balance of accounts, budget report, etc. In this post, I'll be going over defining a basic ledger and calculating balance and register reports.
- VS Code
- I know: a text editor for a command line tool? For me this significantly improved the editing experience.
- ledger - VS Code Extension
- For adding syntax highlighting of ledger files.
Let's start by defining a ledger file. For example, we can save an empty text file as
sample.ledger. Once we have the file saved, we can now gain the benefit of syntax highlighting if we're using a tool that supports ledger syntax highlighting.
A valid transaction consists of 7 elements:
- Date (with a YYYY/mm/dd format)
- Vendor name on the same line as the date separated by a space
- From Account name on a new line, indented with 4 spaces
- From Account amount on the same line as the From Account name, separated by at least 2 spaces
- To Account name on a new line, indented with 4 spaces
- To Account amount on the same line as the To Account name, separated by at least 2 spaces
- From Account and To Account amounts must add to 0.
Here is an example of a valid transaction meeting these requirements:
2019/12/14 Acme, Inc My Bank Account -12.34 My Expense Account 12.34
I'm particular about having the amounts aligned, which can be achieved by adding extra spaces:
2019/12/14 Acme, Inc My Bank Account -12.34 My Expense Account 12.34
Ledger's system relies on double entry accounting, meaning transactions always occur between two accounts. For the sake of a concrete example, let's add a few more transactions:
2019/12/01 Opening Balance Equity -3300.00 My Bank Account 3300.00 2019/12/05 Mars Expeditions My Bank Account -1024.42 My Expense Account 1024.42 2019/12/14 Acme, Inc My Bank Account -12.34 My Expense Account 12.34 2019/12/16 Doe & Doe LLP My Bank Account -900.00 My Expense Account 900.00 2019/12/17 Fresh Foods Galore My Bank Account -58.65 My Expense Account 58.65 2019/12/24 Santa Claus My Bank Account -102.34 My Expense Account 102.34
Notice that we're dealing with three accounts:
My Bank Account and
My Expense Account. I hope that the
My Bank Account account is self-explanatory, in essence symbolizing a bank account.
My Expense Account is an expense account where all spenditures are tracked. Finally, because all transactions must occur between two accounts, we create an equity account to track any balance that was already in the bank account in this case.
One more thing: To run the ledger CLI tool, we'll be specifying the file we are working on with the
-f flag (
ledger -f sample.ledger ...).
Viewing a register, or a listing of transactions, can be as simple as running
ledger -f sample.ledger register or
ledger -f sample.ledger reg:
$ ledger -f sample.ledger reg 19-Dec-01 Opening Balance Equity -3300 -3300 My Bank Account 3300 0 19-Dec-05 Mars Expeditions My Bank Account -1024.42 -1024.42 My Expense Account 1024.42 0 19-Dec-14 Acme, Inc My Bank Account -12.34 -12.34 My Expense Account 12.34 0 19-Dec-16 Doe & Doe LLP My Bank Account -900 -900 My Expense Account 900 0 19-Dec-17 Fresh Foods Galore My Bank Account -58.65 -58.65 My Expense Account 58.65 0 19-Dec-24 Santa Claus My Bank Account -102.34 -102.34 My Expense Account 102.34 0
We can also view a register for a specific account by specifying the account name after the register command:
$ ledger -f sample.ledger reg "My Bank Account" 19-Dec-01 Opening Balance My Bank Account 3300 3300 19-Dec-05 Mars Expeditions My Bank Account -1024.42 2275.58 19-Dec-14 Acme, Inc My Bank Account -12.34 2263.24 19-Dec-16 Doe & Doe LLP My Bank Account -900 1363.24 19-Dec-17 Fresh Foods Galore My Bank Account -58.65 1304.59 19-Dec-24 Santa Claus My Bank Account -102.34 1202.25
This report is similar to a bank statement, where you see the amount of the transaction and remaining balance for the account.
Similar to the register report, the balance report can be executed with the balance command:
ledger -f sample.ledger balance or
ledger -f sample.ledger bal.
$ ledger -f sample.ledger bal -3300 Equity 1202.25 My Bank Account 2097.75 My Expense Account -------------------- 0
0? That means that the sum of all accounts equal to zero. In other words, the same amount that was taken from one account went into another account (or several in the case of split transactions) evenly, and thus there is balance in the world. If a transaction does not balance, Ledger CLI would not calculate any report; instead, it would specify with an error message the offending transaction and the amount that was not accounted for.
Akin to the register report, you can specify the account name to the balance command to get the balance of a specific account:
$ ledger -f sample.ledger bal "My Bank Account" 1202.25 My Bank Account
Specifying Time Periods (Months)
So far, the reports we ran are on every transaction in the
sample.ledger file. Realistically, we would be interested in a specific period of time. Unfortunately, the Ledger CLI documentation is lacking so I do not know the full extent to how we can specify time periods; however, I will show how you can query a specific month (which is to the extent that I use this feature for).
The period is specified with the
-p flag after a report command (i.e.
balance from what we've discussed) followed by a period query.
For instance, since I am writing this in December and all of the transactions are limited to this month, the following queries will all display the same report:
ledger -f sample.ledger reg -p "this month"
ledger -f sample.ledger reg -p "dec"
ledger -f sample.ledger reg -p "in dec"
ledger -f sample.ledger reg -p "2019/12"
ledger -f sample.ledger reg -p "in 2019/12"
Other queries include
"last month", and
### are the first three characters of the month).
The documentation for ledger can be found here (section
14.3.5 discusses pre-commands including period): https://www.ledger-cli.org/3.0/doc/ledger3.html
When entering transactions it can be a bit mundane to have to write the amounts for each transaction twice. Fortuantely, Ledger CLI will assume the equal, and opposite, amount will be applied to the other account listed in the transaction.
This means that our
sample.ledger can also be defined as follows:
2019/12/01 Opening Balance Equity My Bank Account 3300.00 2019/12/05 Mars Expeditions My Bank Account My Expense Account 1024.42 2019/12/14 Acme, Inc My Bank Account My Expense Account 12.34 2019/12/16 Doe & Doe LLP My Bank Account My Expense Account 900.00 2019/12/17 Fresh Foods Galore My Bank Account My Expense Account 58.65 2019/12/24 Santa Claus My Bank Account My Expense Account 102.34
Even better is the ability to add transactions into what Ledger CLI calls "buckets". In our case, all of the transactions pertain to the
My Bank Account account. Rather than have to input this account for each transaction, we can specify a bucket as follows:
bucket My Bank Account 2019/12/01 Opening Balance Equity -3300.00 2019/12/05 Mars Expeditions My Expense Account 1024.42 2019/12/14 Acme, Inc My Expense Account 12.34 2019/12/16 Doe & Doe LLP My Expense Account 900.00 2019/12/17 Fresh Foods Galore My Expense Account 58.65 2019/12/24 Santa Claus My Expense Account 102.34
Notice that when the amount is negative it means that amount is being taken away from the listed amount and being added to the bucket account. When the account is positive, it is being added to the listed account from the bucket account.
In this post, I went over the very basics of getting started with Ledger CLI. I went over how to create a file, how to write transactions, and how to view register and balance reports. This post is truly a surface introduction to Ledger CLI as it can accomplish a lot more. I personally use it because I needed an accounting solution that supported multiple currencies. Perhaps in a future post I will discuss dealing with multiple currencies, structuring accounts, and budgeting. In the meantime, if you want to learn more about Ledger CLI, I highly recommend checking out these resources: