In an age of overly complex personal finance tools, Beancount offers a refreshing alternative: a simple, transparent, and programmable plain-text accounting system. This post introduces the foundational concepts of Beancount, guiding you through setting up your first ledger, understanding its double-entry system, and visualizing your finances with Fava and advanced plugins. Whether you’re new to plaintext accounting or looking to deepen your understanding, this guide will help you get started with a modern, flexible approach to tracking your money.

What is Beancount?

Beancount is an open-source Python library designed for local management of your financial ledger. Its notable features include:

  • Plain Text Database: Beancount utilizes plain text files as its database, allowing all transactions to be easily read and modified with any text editor. This feature is particularly appealing to individuals with coding experience.
  • Simplified Double-Entry Accounting: It supports double-entry accounting and simplifies this concept by using positive and negative symbols instead of the traditional credit and debit terms, which can be confusing for those without an accounting background.
  • Comprehensive Reporting: Beancount offers various reports to display your financial status, providing a clear overview of your finances.
  • SQL-Like Query Language: It provides a SQL-like language to query all transaction history, enabling you to conduct any analysis you desire.
  • Plugin Support: Beancount supports plugins written in Python, allowing you to further customize your ledger to meet any special requirements you may have.
Fava reporting

Visualization using Fava

The above image shows a visualization of a local Beancount ledger using Fava. Fava is another reason that Beancount has become popular: Fava provides an easy-to-understand visualization of your local ledger with common accounting statements (balance and income statements). More importantly, Fava also supports plugins! With the hard work of the community, there are many powerful tools that can help us analyze your ledger! I will talk more about these plugins in separate posts.

Fava-Dashboards reporting

Asset Visualization using Fava-Dashboards

Fava-Dashboards reporting

Sankey Visualization using Fava-Dashboards

The above two figures show advanced visualization of your ledger using the plugin Fava-Dashboards, which provides a more fancy and detailed visualization of the ledger.

Now, we have seen what Beancount (along with its ecosystem) can do, let us focus how can we use Beancount to track our finances.

Getting Start with Beancount

In this section, I will briefly introduce how to use Beancount to bookkeeping your personal finances. However, the examples in this section are only for introduction purpose only. For more fine-grained and practical usage, please refer other posts in this blog.

Environment Setup

As I mentioned early, Beancount is a Python library. So, as a common practice, we will create a virtual python environment:

1
2
3
4
$ mkdir beancount_example_dir
$ cd beancount_example_dir
$ pyenv virtualenv 3.11.4 beancount_example
$ pyenv local beancount_example

Here, I used the pyenv to manage the virtual environment, you can use whatever other tools that suits you. It does not matter in terms of using Beancount.

Now, we install the libraries:

1
pip install Beancount fava

Once the environment is set up, we can start building our ledger. Create a new file called my_ledger.bean with the following content:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
option "title" "Beancount Example Ledger"
option "operating_currency" "USD"


1970-01-01 open Assets:Banks:Chase:Checking USD
1970-01-01 open Income:Salary:AcmeCo USD
1970-01-01 open Expenses:Grocery USD
1970-01-01 open Expenses:Rent USD
1970-01-01 open Liabilities:Credit-Card:VISA USD
1970-01-01 open Equity:OpeningBalance USD


2024-01-01 * "Initialize my assets"
    Equity:OpeningBalance -1,000 USD
    Assets:Banks:Chase:Checking 1,000 USD

2024-12-01 * "" "Salary Income"
    Assets:Banks:Chase:Checking 5,000 USD
    Income:Salary:AcmeCo -5,000 USD

2024-12-02 * "" "Pay the rent"
    Liabilities:Credit-Card:VISA -2000.00 USD
    Expenses:Rent 2000.00 USD

2024-12-03 * "" "Buy some grocery using creit card"
    Liabilities:Credit-Card:VISA -500.00 USD
    Expenses:Grocery 500.00 USD

2024-12-04 * "" "Pay the credit card"
    Assets:Banks:Chase:Checking -500 USD
    Liabilities:Credit-Card:VISA 500.00 USD

Run the fava -p 8004 my_ledger.bean to visualize the ledger. -p 8004 is used to set the port number of local web service. In default, Fava uses the port number 5000, which is now used by the Control Center for AirPlay services in macOS Monterey. So, to avoid the conflicting, we need to set it to be other uncommon port number. In this case, I use 8004.

The following the figure shows visualization of this example ledger.

Sample Fava reporting

Sample Visualization using Fava

Decompose the Text

Now, let’s look closely into the ledger.

Configuring the Ledger

In the first part of this ledger, we define some configurations of this ledger:

1
2
option "title" "Beancount Example Ledger"
option "operating_currency" "USD"

In the Beancount, the configurations are set through key-values pairs with the key word option. Here we simply set the ledger name as “Beancount Example Ledger” and the set the most common currency to be “USD”.

Defining Accounts

The second block of the ledger defines the accounts of the ledger:

1
2
3
4
5
6
1970-01-01 open Assets:Banks:Chase:Checking USD
1970-01-01 open Liabilities:Credit-Card:VISA USD
1970-01-01 open Income:Salary:AcmeCo USD
1970-01-01 open Expenses:Grocery USD
1970-01-01 open Expenses:Rent USD
1970-01-01 open Equity:OpeningBalance USD

Here, we define five accounts and its corresponding currency (USD). These accounts are structured into a hierarchy defined by the colon symbol (:). In Beancount, there are five root types of the accounts:

  • Assets: it represents something that you own. For example, your bank accounts, broker accounts and stocks you hold.
  • Liabilities: it represents something that you owe. For example, your credit card and mortgage loan.
  • Income: it captures inflow of your assets. For example, your salary or dividends received from your investments.
  • Expenses: it captures the outflow of your assets. For example, you spend the money to exchange for food, drinks, clothing.
  • Equity: it represents the ownership value of the assets. Your assets actually includes the ones that you borrowed. The equity account shows the net asset you owned.

These five accounts are the essentials to the double-entry bookkeeping and accounting. So, they are treated like a first class citizen in the Beancount. All other accounts must be defined under one of them. I will talk more about these accounts.

Accounts Relationships

Account Relationships

The figure above visualize the relationships between these five accounts. We will encounter these accounts over and over again when using Beancount.

Logging Transactions

The third part of the ledger is the real transactions we want to log. In our above example, each transaction contains two postings1. For example, in the following transaction:

1
2
3
4
; The following three lines form a transaction
2024-12-02 * "" "Pay the rent"
    Liabilities:Credit-Card:VISA -2000.00 USD ; <-- This is a posting
    Expenses:Rent 2000.00 USD ; <-- This is another posting

We borrowed $2,000$ dollars from the VISA credit card to pay the rent. It involves two accounts: one Liabilities account and one Expense account. In Beancount, everything after semicolon ; is considered a comment.

When we form the transactions into multiple postings, we introduce the fundamental rule of double-entry accounting (as well as Beancount):

The sum of all postings of a transaction must equal zero

This rule leads important consequences of the double-entry accounting (Beancount). We will talk more about this with more details in a separate post.

And that’s it! We build the ledger in its simplest form. When more financial activities happen, you keep logging more and more transactions in the text form. Then we use Beancount and Fava to generate reports and visualizations.

Other Options

Of course, there are more plain text accounting tool out there. Beancount is one of the most commonly used. This website tracks different plain text accounting tools. I chose Beancount because of its simplicity and extensibility. We will see that there are many different plugins that enhance the ability of Beancount.

Related Resources


  1. One transaction does not necessarily have to be two postings, it can have more than two postings. But it has to be at least two postings. ↩︎