The Accounting Cycle, Beancount-Style
Financial statements don't appear by magic. They are the final product of a structured, repeatable process known as the accounting cycle. While the principles are universal, the tools you use can dramatically change the experience. This guide walks you through the accounting cycle with a focus on Beancount, the powerful plain-text accounting tool.
We'll see how Beancount's text-first approach eliminates tedious steps, what you should automate, and which reports give you the clearest picture of your financial health. 🧑💻
TL;DR: The Beancount Workflow
- Capture & Journal: Record every transaction as a clean, double-entry posting in your
.beancount
text file. - Validate & Reconcile: Use
balance
assertions to confirm your ledger matches bank statements and runbean-check
to catch errors. - Review: Generate an unadjusted trial balance for a quick sanity check.
- Adjust: Post entries for accruals, deferrals, depreciation, and other period-end items.
- Re-review: Check the adjusted trial balance to ensure everything is correct.
- Publish & Close: Generate your Income Statement, Balance Sheet, and Cash Flow statement. Closing the books is optional in Beancount, as reports are date-aware.
This flow can be visualized like this:
Step 1: Capture and Record Transactions
This is the foundational step. Every financial event—a sale, a purchase, a bank fee—must be recorded. In Beancount, you do this by creating transactions in a simple text file, typically named main.beancount
or organized into multiple files by year.
Each transaction must follow the rules of double-entry bookkeeping, meaning the sum of all postings must be zero. Beancount enforces this for you.
2025-08-10 * "Walmart" "Purchase of office supplies"
Expenses:Office:Supplies 45.67 USD
Assets:Bank:Checking -45.67 USD
- Pro-Tip: Use tags like
#project-phoenix
or#client-acme
to add dimensions to your data. This makes querying and reporting incredibly flexible later on.
Reconciliation Hygiene ✅
The most powerful feature for ensuring accuracy is the balance assertion. At the end of a statement period (e.g., end of the month), you declare what the balance of an account should be.
2025-08-31 balance Assets:Bank:Checking 12345.67 USD
If the sum of all transactions affecting Assets:Bank:Checking
up to that date doesn't equal 12345.67 USD
, Beancount will raise an error. This simple directive turns your ledger into a self-auditing document.
For those backfilling historical data, the pad
directive can automatically create a balancing transaction to make your opening balances match your first assertion.
Step 2: "Post to the Ledger" (A Freebie!)
In traditional accounting systems, you first write entries in a "journal," and then a separate "posting" step copies those values to the "general ledger."
With Beancount, your .beancount
file is both the journal and the ledger. When you write and save a transaction, you've already posted it. There is no separate step. This directness is a core advantage of plain-text accounting—what you see is what you get.
Step 3: Prepare an Unadjusted Trial Balance
Before you start making adjustments, you need a quick "does this all add up?" check. A trial balance is a simple report that lists every account and its total balance. The grand total of all debit balances must equal the grand total of all credit balances.
You can generate this with a simple query:
bean-query main.beancount \
"SELECT account, sum(position) GROUP BY 1 ORDER BY 1"
Or, for a more visual approach, open your ledger in Fava (the web interface for Beancount) and navigate to the "Trial Balance" report. Look for anything unusual—an asset account with a credit balance, or an expense account with a strange value.
Step 4: Book Adjusting Entries
Adjusting entries are crucial for accurate reporting under the accrual basis of accounting. They ensure that revenues are recognized when earned and expenses are recognized when incurred, regardless of when cash changes hands.
Common adjustments include:
- Accruals: Recording revenue you've earned but haven't invoiced yet, or an expense you've incurred but haven't paid.
- Deferrals: Handling prepayments. If a customer pays you for a year of service upfront, you book it as a liability (
Liabilities:UnearnedRevenue
) and recognize 1/12th of it as income each month. - Non-Cash Items: Recording things like depreciation of assets.
- Corrections: Fixing errors or accounting for missed items from bank feeds, like a small interest payment.
Example: Accruing Revenue
You finished a project on August 31st but won't send the invoice until September. To recognize the income in the correct period (August), you make an adjusting entry:
2025-08-31 * "Accrue revenue for client project #1042"
Assets:AccountsReceivable 3000.00 USD
Income:Consulting -3000.00 USD
Example: Recording Depreciation
Your company has a depreciation schedule for its assets. At the end of the period, you book the expense:
2025-12-31 * "Annual depreciation on computer equipment"
Expenses:Depreciation 4800.00 USD
Assets:Fixed:AccumulatedDepreciation -4800.00 USD
Step 5: Run an Adjusted Trial Balance & Validate
Once your adjusting entries are in, run the trial balance report again. This is your Adjusted Trial Balance. It provides the final set of numbers that will be used to create the financial statements.
This is also the perfect time to run Beancount's built-in sanity check:
bean-check main.beancount
This command verifies all syntax, balancing rules, and assertions. If it runs without any output, your books are mechanically sound.