Counting beans—and more—with Beancount
It is normally the grumpy editor's job to look at accounting software; he does so with an eye toward getting the business off of the proprietary QuickBooks application and moving to something free. It may be that Beancount deserves a look of that nature before too long but, in the meantime, a slightly less grumpy editor has been messing with this text-based accounting tool for a variety of much smaller projects. It is an interesting system, with a lot of capabilities, but its reliance on hand-rolling for various pieces may scare some folks off.
Text
"Text based" means just what it says on the tin—all of the information used by Beancount is stored in regular text files. Those who are used to GUI tools for accounting may be daunted, but text editors are remarkably flexible tools with a wide array of customization possibilities. Emacs is one editor that is noted for its integration with other tools, such as compilers, build systems, debuggers, and source-code control—making it into an IDE for some. An Emacs minor mode for Beancount is available and there are also customization packages for Vim and Sublime.
At its core, Beancount "simply" implements double-entry bookkeeping on various types of items (which could be pork bellies, money in multiple currencies, vacation hours, beans, air miles, or anything else that can be counted). A typical transaction might look something like:
2018-04-01 * "yearly subscription"
Expenses:Subscriptions:LWN 75.60 USD
Liabilities:US:BigBankCorp:TuxCard
That adds the amount of an LWN subscription to the appropriate expense
account, while deducting the same amount from the "TuxCard" liability account.
The "-75.60 USD" to balance out the transaction is automatically
applied to that final entry. On a complicated transaction, with several
different expense buckets, it may be easier to let Beancount do the math;
for this transaction, it probably makes sense to simply put the value into the
entry:
...
Liabilities:US:BigBankCorp:TuxCard -75.60 USD
The "balancing" nature of transactions is one of the fundamental concepts behind Beancount (and double-entry accounting as a whole, I think, though I am far from an expert): all transactions must sum to zero. This central idea is described in "Beancount - The Double-Entry Counting Method" by Beancount developer Martin Blais. As with much of the Beancount documentation, that document is helpful and well-written, but in some ways the documentation is like the tool itself: it opens up huge possibilities, but doesn't grab new users by the scruff of the neck and say "do it this way". In addition, some of the documentation is starting to get a bit long in the tooth, with dates from 2014 and 2015, so it may not all accurately reflect the current state.
The open-ended nature of the documentation seems clearly in keeping with the philosophy of the project as a whole: provide lots of power and only minimal guidance. Which is not to say that there is no guidance at all, just that it is rather general and non-prescriptive. The "Getting Started" document is helpful, as is the "Tutorial & Example" file. But, what to track, how to do so, and how to integrate that tracking into your life or business is largely left up to you. For those who are not afraid of the command line, though, Beancount does not lock users into a particular scheme: changing account names or the hierarchy is easily done with a regular expression in the editor or a simple script.
In addition, Beancount makes it easy to start tracking new things at any point—simply establish the account, perhaps a starting balance, and begin recording transactions. There is no need for everything to be rooted to a single "epoch" date, so things can change as needs do. Account names are largely free-form (though spaces are not allowed) and hierarchies can be established using colon separation:
1970-01-01 open Expenses:Dining
1970-01-01 open Expenses:Dining:Drinks
1970-01-01 open Expenses:Dining:Tips
2017-10-23 open Expenses:Dining:FaveRestaurant ; how much am i spending here?
That creates a hierarchy of dining expense accounts that can be used to
allocate parts of the tab into different buckets—or all into
Expenses:Dining if desired or the details have been lost. The dates are
arbitrary to some extent, though expenses cannot be recorded to them prior
to their "open" date (or after their "close" date for closed accounts, naturally).
Comments start with a ";", but Beancount silently ignores lines that
do not fit syntactically, which allows adding things like headers for Emacs Org Mode to help organize the input file.
Beancount is written in Python and released under the GPLv2. Installation from the Python Package Index (PyPI) using pip is straightforward, but it does require Python 3.5 or higher. Once installed, there are a dozen or so utilities available, all starting with "bean-". If you already have some data in a file, bean-check filename will tell you if there are any problems with the file; if you don't have any data, capturing the output of bean-example into a file will provide you with a detailed test bed (and crib-sheet) full of fictional Beancount data.
Imports and reports
It is certainly possible to add all of the data of interest by hand (or with assistance from an editor plugin), but importing transactions directly from CSV and other file types from banks, credit card companies, brokerages, and the like is possible as well. Once again, it requires some hand assembly, but the process to create importers is documented; Beancount has a few different commands that provide a framework for gathering useful information from the myriad of different formats. Being able to make use of Beancount without spending inordinate amounts of time manually entering data will likely depend on having enough of these for the sources of interest for your business or personal finances.
Reports of various sorts are, of course, a staple of any accounting system. Beancount provides several different ways to get reports, starting with the bean-report command. It has many different report options, both in terms of what is reported and how (e.g. balance reports, balance sheets, income reports, and net worth) as well as what format to produce the report in (e.g. text, CSV, HTML, and so on).
The inclusion of "HTML" in the output formats leads us to one—two, actually—of the most useful ways to examine Beancount data. The first comes with Beancount; bean-web starts a web server on localhost:8080 that provides different reports, over monthly and yearly time frames, that can be explored in the browser. A screen shot of the interface using the example data can be seen on the right. In addition, the bean-bake command will create a directory tree or ZIP file containing all of the processed data in a format suitable for sending to accountants or others to browse on their own systems.
The web pages created by bean-web are fairly bare-bones—simple HTML that just presents the data at hand. For those looking for a more eye-catching, interactive, JavaScript-based site, Fava may fit the bill. It runs a web server at localhost:5000 that provides many of the same kinds of reports as bean-web, but in a more interactive form. Fava has its own unique ways of looking at the data too, as can be seen on the left.
Fava has its own editor component that can be used to enter transactions in a way that will be familiar to those coming from the GUI-accounting world. The file itself can be edited directly using that interface as well. Another thing that Fava gives direct access to is Beancount's query capabilities, which can also be accessed from the command line using bean-query. For both, the Beancount Query Language (BQL) can be used to query the data set in ways that will seem familiar to SQL users. As noted in the BQL document, though, there are specific needs for accounting queries that are not met by simply pulling the data into, say, SQLite tables and doing queries on those.
Another interesting aspect of Beancount is that it knows little about what it counts. US Dollars, zorkmids, stocks, shopping points, or Whuffie are all treated the same way. The text file can establish its "operating currency" (or currencies), but that simply affects how some reports are generated. Any of the commodities can be priced relative to another (on a given date) using the "price" directive, as with this fictional gold price:
2018-04-13 price GLD 254.62 USD
Prices can also be specified as part of a transaction, like a stock buy or
a currency conversion; as long as the price information is available, any
commodity can be converted to any other so that reports can all be in a
single currency (e.g. "What is our net worth in zorkmids?").
Conclusion
This just scratches the surface of what Beancount can do, of course. It is not the first, nor the only, text-based accounting system out there, as the Plain Text Accounting page will attest. In addition, it will not come as a surprise that text files are relatively easy to convert between these different systems, so trying out one does not preclude trying out or using one of the others down the road.
Text offers a number of advantages over binary formats; it is more durable, usable without any application at all, easy to diff or store in Git (or other version control system), and so on. Editors may not seem like the first choice for an interface to an accounting system—and may not work out in the long run, it is too soon to tell. It does have enough going for it that further investigation, including using it for a small-business project, seems indicated. That may well lead to more articles here; stay tuned ...