Skip to main content

10 posts tagged with "Double-Entry"

View all tags

Understanding Journal Entries in Beancount

· 8 min read
Mike Thrift
Mike Thrift
Marketing Manager

Journal entries are the backbone of double-entry accounting, and in Beancount, every * transaction you write is a journal entry. This guide explains the essentials—debits and credits, adjusting entries, and reversing entries—and shows how they map cleanly to Beancount's plain-text syntax. You'll learn how to keep precise books with minimal ceremony.


2025-09-02-journal-entries-in-beancount

A Quick Refresher: What Is a Journal Entry?

A journal entry is the formal, dated record of a financial transaction. It's expressed in terms of debits and credits that keep the fundamental accounting equation in balance:

Assets=Liabilities+EquityAssets = Liabilities + Equity

In a double-entry system, every transaction affects at least two accounts, and the total debits must equal the total credits. This simple rule is what makes downstream financial reports like the Profit & Loss statement and Balance Sheet trustworthy and accurate.


Debits and Credits in One Minute

The concepts of debits and credits can be confusing at first, but they boil down to a few simple rules. Think of it this way: "where did the value come from?" (credit) and "where did the value go?" (debit).

Here's a cheat sheet for how they increase the five core account types:

Account TypeIncreases With
AssetsDebit
ExpensesDebit
LiabilitiesCredit
EquityCredit
IncomeCredit

How a Journal Entry Looks in Beancount

Beancount uses simple, human-readable text directives to record transactions. Each transaction must balance to zero for every commodity (e.g., USD, EUR, AAPL stock). Beancount will throw an error if it doesn't.

Here is a basic transaction for buying coffee:

2025-09-10 * "Coffee Bar" "Team coffee"
Expenses:Food:Coffee 18.00 USD
Assets:Bank:Checking -18.00 USD

Notice how the two postings (lines with accounts) sum to zero: $18.00 + (-$18.00) = 0.

You can add powerful context directly in the narration using tags (like #clientX) for filtering and links (like ^INV-2025-001) to connect related entries.

For example, here's how you can link an invoice to its payment:

; First, record the invoice you sent to the client
2025-09-15 * "Acme Corp" "Invoice 2025-001 #clientX ^INV-2025-001"
Assets:AccountsReceivable 1000.00 USD
Income:Consulting -1000.00 USD

; Later, record the payment and link it back to the original invoice
2025-09-28 * "Acme Corp" "Payment on ^INV-2025-001"
Assets:Bank:Checking 1000.00 USD
Assets:AccountsReceivable -1000.00 USD

The #clientX tag lets you easily filter all transactions for this client, and the ^INV-2025-001 link creates a connection between the two entries that you can follow in reports.


Common Journal Entries (Ready to Paste)

Here are several common business transactions formatted for Beancount.

Owner Invests Cash

An owner contributes personal funds to start the business.

2025-01-01 * "Owner" "Initial capital contribution"
Assets:Bank:Checking 10000.00 USD
Equity:Owner-Capital -10000.00 USD

Cash Sale with Sales Tax

A customer pays in cash for a product, including an 8% sales tax you must later remit to the government.

2025-01-05 * "Walk-in Customer" "Cash sale with 8% tax"
Assets:Cash 108.00 USD
Income:Sales -100.00 USD
Liabilities:Tax:Sales -8.00 USD

Sale on Credit (Invoice) and Collection

You provide a service and invoice the client, then receive payment later.

2025-01-10 * "Acme Corp" "Consulting invoice ^INV-2025-002"
Assets:AccountsReceivable 2500.00 USD
Income:Consulting -2500.00 USD

2025-01-30 * "Acme Corp" "Payment on ^INV-2025-002"
Assets:Bank:Checking 2500.00 USD
Assets:AccountsReceivable -2500.00 USD

Expense on Credit Card

You purchase office supplies using a company credit card.

2025-01-12 * "OfficeMax" "Supplies on credit card"
Expenses:Office:Supplies 75.00 USD
Liabilities:CreditCard -75.00 USD

Payroll (Simple Model)

You run payroll, recording the gross wage expense, employee tax withholdings, and the net payment from your bank.

2025-01-31 * "Payroll" "January wages and withholdings"
Expenses:Payroll:Wages 2000.00 USD
Liabilities:Taxes:Withheld -400.00 USD
Assets:Bank:Checking -1600.00 USD

Monthly Depreciation

You record the monthly depreciation expense for an asset, like a laptop.

2025-01-31 * "Depreciation" "Laptop, straight-line"
Expenses:Depreciation 100.00 USD
Assets:Equipment:AccumDepr -100.00 USD

Prepaid Expense & Monthly Amortization

You pay for a full year of insurance upfront, then recognize one month's worth of the expense.

; 1. Pay for the annual policy
2025-01-01 * "InsureCo" "Annual insurance premium"
Assets:Prepaid:Insurance 1200.00 USD
Assets:Bank:Checking -1200.00 USD

; 2. Recognize one month of expense at the end of January
2025-01-31 * "InsureCo" "Amortize 1/12 of insurance"
Expenses:Insurance 100.00 USD
Assets:Prepaid:Insurance -100.00 USD

Unearned Revenue & Monthly Recognition

A customer prepays for a 3-month subscription. You record the cash and then recognize one month of income.

; 1. Customer prepays for service
2025-02-01 * "Subscriber" "3-month plan prepaid"
Assets:Bank:Checking 300.00 USD
Liabilities:Unearned:Subs -300.00 USD

; 2. Recognize one month of income after delivering the service
2025-02-28 * "Recognition" "Recognize month 1 of 3"
Liabilities:Unearned:Subs 100.00 USD
Income:Subscriptions -100.00 USD

Bad-Debt Allowance and Write-Off

You set aside an allowance for potentially uncollectible invoices and later write off a specific bad invoice.

; 1. Create a provision based on 2% of Accounts Receivable
2025-03-31 * "Provision" "2% of A/R for doubtful accounts"
Expenses:BadDebt 200.00 USD
Assets:AllowanceForDoubtful -200.00 USD

; 2. Write off a specific invoice that you know will not be paid
2025-04-15 * "Write-off" "Customer XYZ invoice"
Assets:AllowanceForDoubtful 150.00 USD
Assets:AccountsReceivable -150.00 USD

Periodic Inventory & COGS Adjustment

At the end of a period, you calculate the Cost of Goods Sold (COGS) by adjusting your inventory account.

2025-03-31 * "COGS adjustment" "Periodic inventory method"
Expenses:COGS 4500.00 USD
Assets:Inventory -4500.00 USD

Adjusting Entries vs. Reversing Entries

Adjusting entries are recorded at the end of an accounting period (like a month or quarter) to properly align revenues and expenses to the period in which they were actually earned or incurred. This includes accruals, deferrals, and estimates like depreciation.

Reversing entries are optional entries made on the first day of a new period that exactly reverse a specific adjusting entry from the prior period. Their purpose is to simplify bookkeeping. By reversing an accrual, you can book the subsequent cash transaction in a standard way without having to remember to split it against the liability account.

Example: Accruing and Reversing Utilities

Let's say you need to record your January utility expense, but the bill won't arrive until February.

; 1. Accrue the estimated expense at the end of January
2025-01-31 * "Accrual" "Estimate January utilities expense"
Expenses:Utilities 500.00 USD
Liabilities:Accrued:Utilities -500.00 USD

; 2. (Optional) Reverse the accrual on the first day of the next period
2025-02-01 * "Reversal" "Undo January utilities accrual"
Liabilities:Accrued:Utilities 500.00 USD
Expenses:Utilities -500.00 USD

; 3. Record the actual bill payment when it arrives in February
; The actual bill is for $520. Because of the reversal, you can
; book the full amount to the expense account without issue.
; The net expense for Feb will be $520 - $500 = $20.
2025-02-10 * "City Utilities" "Payment for January bill"
Expenses:Utilities 520.00 USD
Assets:Bank:Checking -520.00 USD

Note: The example in the outline shows splitting the final payment. The reversing entry method is an alternative that simplifies the final payment entry.


A Checklist for Every Beancount Journal Entry

Follow these steps to ensure your entries are clean and correct:

  1. Start with the date (YYYY-MM-DD) and a transaction flag (*).
  2. Add a payee and a descriptive narration. Use #tags and ^links for searchability.
  3. Include at least two posting lines that balance to zero for each commodity.
  4. Use proper account names under the five types: Assets, Liabilities, Equity, Income, Expenses.
  5. Optionally, add metadata like document: "invoices/INV-2025-001.pdf" for traceability.

Common Pitfalls (and How Beancount Helps)

  • Imbalanced Postings: If your debits and credits don't sum to zero, Beancount will refuse the entry. This is a core feature that prevents errors. You can even leave one posting amount blank, and Beancount will automatically calculate it for you.
  • Wrong Sign on an Account: It's easy to forget that Income, Equity, and Liabilities are increased with credits (which are typically negative numbers in Beancount). If you get it wrong, your reports will look strange, but the balancing rule still provides a safety net.
  • Missing Links Between Entries: Forgetting to link an invoice to its payment makes it harder to track what's outstanding. Using ^links consistently solves this by creating an auditable trail.

Where to Go Next

  • Beancount Language & Balancing Rules: Dive deeper into the official documentation.
  • Syntax Cheat Sheet: A handy reference for all Beancount directives.
  • Debits/Credits Primer: A great starting point if you're new to accounting rules.
  • Adjusting/Reversing Entries: More detailed articles on the accounting theory.

Appendix: Accounting Talk → Beancount Map

This quick translation guide can help you map accounting instructions to Beancount syntax.

Accounting InstructionBeancount Action
Debit an expensePositive amount to an Expenses: account
Credit a liabilityNegative amount to a Liabilities: account
Accrue revenueAssets:AccountsReceivable + <br> Income:* -
Defer revenueAssets:Bank:* + <br> Liabilities:Unearned:* -
Recognize deferred revenueLiabilities:Unearned:* + <br> Income:* -

With these patterns and examples, you can cleanly model nearly any business event in Beancount, ensuring your financial reports line up without any surprises.

Recording Taxes in Beancount (The Pragmatic Way)

· 8 min read
Mike Thrift
Mike Thrift
Marketing Manager

Taxes can feel like a special, complicated beast in the world of personal finance. But what if they weren't? What if you could treat them just like any other flow of money in your ledger? Good news: you can. By treating taxes as simple movements of value, your Beancount ledger will stay clean, easy to query, and—most importantly—understandable.

Below is a practical, no-nonsense pattern you can drop into a personal or small-business Beancount file. It’s a simple system for handling paychecks, tax payments, and even those pesky refunds that cross over into the new year. We'll cover the essential accounts you need, walk through real-world examples, and show you the exact queries to run to get the answers you need.

2025-08-25-recording-taxes-in-beancount


The Core Principles

Before we dive into the code, let's agree on a few simple rules. These principles keep things logical and prevent future headaches.

  • Separate "what it is" from "when the cash moves." 🗓️ This is the most important concept. A tax expense belongs to the year you earned the income (e.g., 2024), even if you settle the bill with the IRS in April 2025. If you don't separate the timing of the expense from the timing of the cash payment, your year-over-year reports will get messy and misleading.

  • Keep your account hierarchy boring and simple. 📁 Name your accounts clearly based on the type of tax (e.g., IncomeTax, SocialSecurity). This makes your queries incredibly simple. Don't clutter account names with vendor names or form numbers like "W-2" or "1099"; use metadata and tags for those details instead.

  • Embrace accrual for year-end adjustments. ⚖️ Even for a personal ledger, using a simple accrual entry at year-end is the cleanest way to make your reports accurate. It means recognizing an expense or refund in the correct year, even if the money doesn't move until the next. It’s one small extra step that saves you from mental gymnastics later.

  • Write for your future self. 🧠 Your goal is clarity. Only add extra details, like the tax year, to an account name if it genuinely makes your queries easier. Avoid creating a new set of accounts every single year (Expenses:Taxes:2024:Federal, Expenses:Taxes:2025:Federal, etc.) unless you have a compelling reason. A flat structure is often easier to manage.


A Minimal Account Skeleton

Here’s a basic set of accounts to get you started. This structure is US-centric, but you can easily adapt the names for your own country's tax system. Just drop these open directives into your Beancount file.

; --- US Federal Income & Payroll Taxes ---
; For money withheld from your paycheck
2024-01-01 open Expenses:Taxes:Federal:IncomeTax:Withheld USD
; For estimated payments or tax-day bills you pay directly
2024-01-01 open Expenses:Taxes:Federal:IncomeTax:Payments USD
; For tax refunds you receive
2024-01-01 open Expenses:Taxes:Federal:IncomeTax:Refunds USD

; Your FICA contributions
2024-01-01 open Expenses:Taxes:Federal:SocialSecurity USD
2024-01-01 open Expenses:Taxes:Federal:Medicare USD

; --- Other Common Taxes ---
; For sales/use taxes you pay on purchases
2024-01-01 open Expenses:Taxes:Sales USD

; --- Accounts for Year-End Adjustments (Optional but Recommended!) ---
; A temporary holding account for taxes you owe but haven't paid yet
2024-01-01 open Liabilities:AccruedTaxes:Federal:Income USD
; A temporary holding account for a refund you're owed but haven't received
2024-01-01 open Assets:Tax:Receivable USD

This setup separates withheld taxes from direct payments and refunds, making it easy to see exactly where your money went. The Liabilities and Assets accounts are our secret weapon for keeping year-end reporting accurate.


Example 1: The Paycheck

Let's book a typical paycheck where taxes are withheld automatically. The key is to record your gross pay first, then show how it was split between taxes and the cash that actually landed in your bank account.

2025-07-15 * "Employer Inc." "Salary for first half of July"
Income:Work:Salary -6,000.00 USD
Expenses:Taxes:Federal:IncomeTax:Withheld 1,200.00 USD
Expenses:Taxes:Federal:SocialSecurity 372.00 USD
Expenses:Taxes:Federal:Medicare 87.00 USD
Assets:Cash:Checking 4,341.00 USD

This single transaction tells the whole story:

  • You earned $6,000 in gross income.
  • $1,200 of it was sent to the IRS for federal income tax.
  • $372 went to Social Security and $87 to Medicare.
  • The remaining $4,341 is what you took home.

Pro-tip: You can attach metadata from your pay stub (like pay_period_end: "2025-07-15") to the transaction for an easy audit trail.


Example 2: Filing Your Return (The Year-Crossing Problem)

Here's the scenario that trips people up: It's April 2025, and you're filing your 2024 taxes. You learn that after all your withholding, you still owe an extra $3,000.

How do you record this? You want the expense to count toward 2024, but the cash payment happens in 2025. Here are two excellent ways to handle it.

Option A: The Manual Two-Step Accrual

This method is pure Beancount, no plugins required. It's a clear, two-step process.

Step 1: Recognize the expense at the end of the tax year. On the last day of 2024, you create a "true-up" entry. No cash is moving yet; you're just acknowledging the expense and parking it in a temporary liability account.

2024-12-31 * "Federal income tax true-up for 2024"
Expenses:Taxes:Federal:IncomeTax:Payments 3,000.00 USD
Liabilities:AccruedTaxes:Federal:Income -3,000.00 USD

Now, your 2024 income statement correctly shows this $3,000 expense.

Step 2: Record the cash payment when it happens. In April 2025, when you actually send the money to the IRS, you clear out the liability.

2025-04-15 * "IRS" "Payment for 2024 tax return"
Liabilities:AccruedTaxes:Federal:Income 3,000.00 USD
Assets:Cash:Checking -3,000.00 USD

Your 2024 reports are correct, and your 2025 cash flow is correct. Perfect! This same pattern works in reverse for a refund—just use Assets:Tax:Receivable instead of the liability account.

Option B: Automate It with a Plugin

If you prefer to keep the payment in a single transaction, a fantastic community plugin called beancount_reds_plugins.effective_date can help. It lets you assign a different "effective date" to a single line item.

First, enable the plugin in your main Beancount file: plugin "beancount_reds_plugins.effective_date"

Now, you can write a single transaction. The plugin will automatically split it behind the scenes to make your reports accurate.

; One entry; the plugin handles the rest
2025-04-15 * "IRS" "Payment for 2024 tax return"
Assets:Cash:Checking -3,000.00 USD
Expenses:Taxes:Federal:IncomeTax:Payments 3,000.00 USD
effective_date: 2024-12-31

Here, the cash portion is recorded on April 15, 2025, but the expense portion is retroactively applied to December 31, 2024. It achieves the same result as Option A with a different workflow.


What About Sales Tax?

For most personal ledgers, sales tax is simple. If you're not claiming it back, just split it out as its own expense during a purchase.

2025-07-19 * "Local Grocery Store"
Expenses:Groceries 12.32 USD
Expenses:Taxes:Sales 1.28 USD
Assets:Cash:Checking -13.60 USD

This lets you easily track how much you're spending on sales tax over the year. If you run a business that deals with VAT, you'd use a more formal system with payable and receivable accounts, but the principle is the same.


Queries You'll Actually Run

The whole point of this structure is to make getting answers easy. Here are some BQL queries to see your tax picture.

1. What was my total federal income tax for 2024?

SELECT cost(sum(position))
WHERE account ~ "Expenses:Taxes:Federal:IncomeTax"
AND date >= 2024-01-01 AND date < 2025-01-01;

2. How did that total break down between withholding, payments, and refunds?

SELECT account, cost(sum(position))
WHERE account ~ "Expenses:Taxes:Federal:IncomeTax"
AND date >= 2024-01-01 AND date < 2025-01-01
GROUP BY account
ORDER BY account;

3. Do I have any outstanding tax debts or receivables? (Useful for checking your work!)

SELECT account, units(sum(position))
WHERE account ~ "Liabilities:AccruedTaxes" OR account ~ "Assets:Tax"
GROUP BY account
ORDER BY account;

If this query returns non-zero balances, it means you have accruals you haven't settled yet.


Quick FAQ

  • Do I really need per-year accounts like Expenses:Taxes:2024? Probably not. The accrual method (or the plugin) keeps a flat account structure clean and readable. Only create per-year accounts if you find it makes your specific queries easier to write.

  • Can Beancount calculate my taxes for me? Not directly, but it can prepare the data. Some advanced users write scripts to pipe BQL query results into tax calculation software, which is great for estimating your liability during the year.

  • Is this tax advice? No. This is a bookkeeping pattern for organizing your data. The accounting is sound, but you should always consult a tax professional for advice specific to your situation.


Your Drop-In Checklist

Ready to get started?

  1. Add the account skeleton to your Beancount file (and adapt names for your country).
  2. Book paychecks by starting with gross income and splitting out the tax postings.
  3. At year-end, accrue any true-ups for payments or refunds using a liability/asset account (or use the effective_date plugin).
  4. Track refunds as receivables and clear them when the cash arrives.
  5. Run the BQL queries above to verify your totals before you file.

Keep it boring, keep it consistent, and your tax season will finally feel like just another part of your financial story—not a mystery to be solved.

The Accounting Cycle, Beancount-Style

· 9 min read
Mike Thrift
Mike Thrift
Marketing Manager

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. 🧑‍💻

2025-08-13-the-accounting-cycle-beancount-style


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 run bean-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.


Step 6: Publish Financial Statements 📊

This is the payoff. Using the numbers from your adjusted trial balance, you can now generate the key financial reports. Fava is the easiest way to do this, as it provides interactive, drill-down reports out of the box.

  • Income Statement (Profit & Loss): Shows your revenues and expenses over a period, resulting in your net income or loss.
  • Balance Sheet: A snapshot of what you own (Assets) and what you owe (Liabilities), as well as your net worth (Equity), on a specific date.
  • Cash Flow Statement: Reconciles your starting cash with your ending cash by showing where money came from and where it went.

For custom reports, you can use Beancount Query Language (BQL). Here’s a query for a monthly income statement:

-- P&L for August 2025
SELECT account, sum(position)
WHERE account ~ '^(Income|Expenses)'
AND date >= 2025-08-01 AND date <= 2025-08-31
GROUP BY account ORDER BY account;

Step 7: Closing the Books (Optional)

In traditional accounting, the "closing" process involves creating journal entries to zero out all temporary accounts (Income and Expenses) and transfer the net income into an equity account called Retained Earnings. This formally resets the temporary accounts for the next year.

In Beancount, this step is usually unnecessary. Fava's reports are date-aware; if you ask for a 2025 P&L, it will only use 2025 data. The balances don't "spill over." Most users simply leave the balances as they are.

However, if you need to perform a formal close for compliance or shareholder reporting, you can do so with a simple year-end transaction that moves the total income and expense balances into Equity:Retained-Earnings.


A Practical Monthly Close Checklist

Here’s a repeatable checklist to close your books each month using Beancount.

  • Capture: Import all bank and credit card transactions. Manually enter any cash expenses or out-of-band items.
  • Reconcile: Add balance assertions for all bank accounts, credit cards, and loan accounts, matching them to your statements.
  • Review: Scan the unadjusted trial balance in Fava. Investigate any strange or unexpected balances. Check for stale unpaid invoices (Assets:AccountsReceivable) or bills (Liabilities:AccountsPayable).
  • Adjust: Book entries for accrued revenue/expenses, deferred revenue, and any necessary corrections.
  • Validate: Run bean-check. Review the final adjusted trial balance.
  • Publish: Generate the P&L and Balance Sheet. Send them to stakeholders or save them for your records.
  • Wrap-up: Optionally, perform a closing entry if your business requires it. Archive a copy of your .beancount files for the period.

Why Beancount Shines for the Accounting Cycle

  • Transparency and Auditability: Your ledger is a text file. You can use git to version control your financial history, review changes with diff, and collaborate with your accountant in a clear, unambiguous format.
  • Total Control: You define your chart of accounts. You aren't locked into a software vendor's structure. Your data is yours, forever, in an open format.
  • Unmatched Power: The combination of SQL-like queries (BQL) and a rich web interface (Fava) gives you unparalleled power to slice, dice, and understand your financial data.

Copy-Paste Snippets to Get Started

Simple Chart of Accounts:

option "title" "My Personal Ledger"
option "operating_currency" "USD"

;; --- Accounts ---
1970-01-01 open Assets:Bank:Checking
1970-01-01 open Assets:AccountsReceivable
1970-01-01 open Liabilities:CreditCard
1970-01-01 open Liabilities:UnearnedRevenue
1970-01-01 open Equity:Owner:Capital
1970-01-01 open Equity:Retained-Earnings
1970-01-01 open Income:Consulting
1970-01-01 open Expenses:Office:Supplies
1970-01-01 open Expenses:Software
1970-01-01 open Expenses:Depreciation

Useful BQL Query:

-- Find all customers with an outstanding balance
SELECT payee, sum(position)
WHERE account = 'Assets:AccountsReceivable'
GROUP BY payee
HAVING sum(position) > 0
ORDER BY sum(position) DESC;

By mapping the timeless accounting cycle to Beancount's modern, text-based tools, you gain a system that is robust, transparent, and built to last. Happy bookkeeping!

Beancount.io vs. Traditional Accounting Software: Which One Fits You Best?

· 7 min read
Mike Thrift
Mike Thrift
Marketing Manager

For decades, the world of business accounting has been dominated by a familiar cast of closed, GUI-based systems like QuickBooks, Xero, and FreshBooks. They have set the standard, offering ease-of-use and visual workflows that cater to non-technical users. But for developers, power users, and anyone who values absolute transparency and control, a radically different approach has emerged: Beancount.io.

This article provides a direct comparison of Beancount.io with traditional accounting software. We'll break down their core differences in philosophy, flexibility, cost, and long-term maintainability to help you decide which system truly fits your needs.

2025-08-08-beancount-io-vs-traditional-accounting-software

1. Philosophy and Workflow

The most fundamental difference between these two approaches lies in their core philosophy.

Beancount.io Beancount.io is built on the philosophy of plain-text accounting. At its heart, every single financial transaction is an entry in a simple text file. This "accounting as code" model prioritizes human-readable, version-controllable records. Your financial data lives in a timeless, open format that you own completely—it can never be locked away by a vendor. This workflow is designed for users who are comfortable with code editors, version control systems like Git, and command-line tools.

Traditional Software Traditional accounting platforms are GUI-based and form-driven. You enter data using wizards, dropdown menus, and visual forms. This approach prioritizes immediacy and accessibility, making it easy for non-technical users to get started without a steep learning curve. However, your data is stored in a proprietary format or a cloud database, often requiring complex export and import procedures if you ever decide to migrate to another service.

Verdict: If you prioritize full control, data ownership, transparency, and automation, Beancount.io is the clear winner. If you need a "click and go" interface with a minimal learning curve, traditional software will feel more natural.

2. Flexibility and Customization

How well can the software adapt to your specific needs?

Beancount.io Being 100% scriptable is Beancount.io’s superpower. It integrates seamlessly with Python, allowing you to connect to any API, automate data fetching from bank feeds, programmatically tag transactions based on complex rules, and generate custom reports tailored to your exact specifications. Your ability to extend and customize is practically infinite, free from any vendor-imposed limitations.

Traditional Software These platforms offer a curated selection of integrations with popular tools like PayPal, Stripe, and various payroll services. While convenient, you are operating within the vendor's walled garden. Customization is limited to what the platform allows, and advanced reporting or automation often requires upgrading to a higher-tier plan or purchasing third-party add-ons. You can work with their APIs, but you'll always be bound by their ecosystem's rules and rate limits.

Verdict: Beancount.io provides unmatched flexibility for developers and technical users. Traditional tools are better suited for standard, plug-and-play workflows with popular business applications.

3. Collaboration and Transparency

How you work with others and audit your records differs significantly.

Beancount.io Collaboration on Beancount.io is managed through Git. This makes every change to your financial ledger completely transparent and auditable. You can see who changed what, when, and why—just like a code review workflow. This is ideal for distributed teams that already embrace tools like GitHub or GitLab. Furthermore, there are no hidden calculations; every number in a report can be traced back to the exact line-item entry in your ledger file, ensuring complete auditability.

Traditional Software Collaboration is handled through built-in user roles and permissions. You can invite your accountant, bookkeeper, or business partners to access the books directly through the web interface. This is highly effective for businesses that follow a traditional model of financial oversight. The downside is that some internal operations, like tax calculations or automated balance adjustments, can be opaque "black boxes," making it difficult to independently verify the logic.

Verdict: Beancount.io is perfect for teams that value granular auditability and code-style collaboration. Traditional systems are more accountant-friendly for real-time, shared GUI access.

4. Cost and Ownership

The financial models and the concept of data ownership are worlds apart.

Beancount.io The core Beancount software is open-source and free. You only pay for the value-added services of Beancount.io, which include hosting, intelligent automation, and premium features. There are no per-seat licensing fees, so you can scale your team without incurring extra costs. Most importantly, there is zero vendor lock-in. Your data is a collection of text files that you can move, edit, or store anywhere, anytime.

Traditional Software These services operate on a subscription model, typically billed monthly or yearly. Pricing is often tiered based on features, and you may face per-user or per-company fees that scale with your organization. This creates a dependency; if you stop paying, you risk losing access to your data and the software's functionality. This vendor lock-in is a significant long-term risk.

Verdict: Beancount.io is significantly more cost-effective in the long run, especially for technical teams that value data sovereignty. Traditional software offers predictable subscription costs but creates long-term dependency.

5. Learning Curve and Adoption

How quickly can you get up and running?

Beancount.io The learning curve is undeniably steeper. Adopting this system requires comfort with text-based editing, understanding basic syntax, and familiarity with tools like Git. However, the initial investment pays off. Once mastered, Beancount enables incredibly fast, repeatable workflows and provides a much deeper, foundational understanding of your financial picture.

Traditional Software These platforms are designed for non-technical business owners and offer minimal onboarding friction. You can be up and running, sending invoices and categorizing expenses, within minutes. That said, learning the more advanced features, such as custom report building or setting up multi-entity accounting, still requires a significant time investment.

Verdict: Beancount.io is the right choice if you're willing to invest time in learning a powerful system. Traditional software is faster to start with for non-technical users who need immediate results.

Side-by-Side Comparison

FeatureBeancount.ioTraditional Accounting Software
Core PhilosophyAccounting as code; plain-text ledgerGUI-based; form-driven
Data FormatOpen (Plain Text)Proprietary (Database)
Data Ownership100% user-owned and portableVendor-controlled; potential lock-in
FlexibilityInfinite; fully scriptable with PythonLimited to vendor's ecosystem & APIs
CollaborationGit-based; transparent change historyRole-based user permissions
TransparencyFully auditable; no hidden calculationsSome calculations can be opaque
Cost ModelOpen-source core; pay for hosting/automationMonthly/annual subscription (SaaS)
Learning CurveSteeper for non-technical usersLow; designed for quick start
Ideal UserDevelopers, power users, data analystsSMB owners, non-technical teams

When to Choose Each

The decision ultimately comes down to your team's skills, priorities, and workflow.

Choose Beancount.io if you:

  • Are a developer, data analyst, or technically-inclined power user.
  • Value absolute transparency, control, and long-term data portability above all else.
  • Want to fully automate your accounting and integrate it deeply into your custom workflows.
  • Are comfortable treating your financial records with the same rigor as source code.

Choose Traditional Accounting Software if you:

  • Want a quick-start, visual interface without any technical setup.
  • Need to provide immediate, accountant-friendly access with minimal training.
  • Prefer a managed, hosted solution where the vendor handles all updates and compliance.
  • Your integration needs are met by popular, off-the-shelf apps.

Final Thoughts

Beancount.io isn’t trying to be a better QuickBooks—it’s a fundamentally different way of thinking. It represents accounting as code. For technical professionals, this shift offers the same leap forward that version control with Git brought to software development: complete transparency, perfect reproducibility, and ultimate control.

At the same time, traditional accounting software continues to win on out-of-the-box ease-of-use and ready-made integrations for non-technical teams. The right choice isn't about which is "better" overall, but which is the perfect fit for your workflow, your priorities, and the degree of control you demand over your financial data.

The Beancount Ecosystem: A Comprehensive Analysis

· 46 min read
Mike Thrift
Mike Thrift
Marketing Manager

Core Functionality and Philosophy of Beancount

Beancount is an open-source, double-entry accounting system that uses plain text files to record transactions. At its core, Beancount treats your ledger as a dataset defined by a simple, strict grammar. Every financial event (transactions, account openings, commodity prices, etc.) is a directive in a text file, which Beancount parses into an in-memory database of entries. This design enforces the double-entry principle: every transaction must balance debits and credits across accounts. The result is a highly transparent and auditable ledger that you can version-control, inspect, and query with ease.

2025-04-15-beancount-ecosystem

Philosophy – correctness and minimalism: Beancount’s design prioritizes data integrity and simplicity. Its creator, Martin Blais, describes Beancount as “pessimistic” in assuming the user will make mistakes and thus imposes extra checks and constraints. For example, Beancount will not allow you to remove assets that were never added (preventing negative stock holdings or cash balances) and can enforce that every account is opened before use. It lacks Ledger’s concept of “virtual” or automatically balanced postings – an intentional choice to force fully balanced entries. Beancount effectively “goes hardcore” on correctness with more cross-checks than basic double-entry provides. This cautious approach appeals to users who “do not trust themselves too much” and want the software to catch their errors.

Minimal options, maximum consistency: In contrast to Ledger’s myriad of command-line flags and tuning options, Beancount opts for minimalism. There are very few global options, and none that change transaction semantics outside the ledger file. All configuration that affects accounting (like commodity cost basis methods or booking assumptions) is done in-file via directives or plugins, ensuring that loading the same file always produces the same results regardless of how reports are generated. This design avoids the complexity of Ledger’s many knobs and the subtle interactions between them. Beancount’s philosophy is that an accounting tool should be a stable, deterministic pipeline from input file to reports. It achieves this by treating the ledger as an ordered stream of directives that can be programmatically processed in sequence. Even things that Ledger treats as special syntax (like opening balances or price statements) are first-class directives in Beancount’s data model, which makes the system highly extensible.

Extensibility via plugins and query language: Beancount is implemented in Python and provides hooks to inject custom logic into the processing pipeline. Users can write plugins in Python that operate on the stream of transactions (for example, to enforce a custom rule or generate automatic entries). These plugins run as the file is processed, effectively extending Beancount’s core functionality without needing to modify the source. Beancount also includes a powerful query language (inspired by SQL) to slice and dice the ledger. The bean-query tool treats the parsed ledger as a database and lets you run analytical queries on it – for instance, summing expenses by category or extracting all transactions for a given payee. In Beancount 3.x, this querying capability was moved into a standalone beanquery package, but from a user perspective it still provides flexible reporting via SQL-like queries.

Plain text and version control: As a plaintext accounting tool, Beancount emphasizes user control and longevity of data. The ledger is simply a .beancount text file that you can edit in any text editor. This means your entire financial history is stored in a human-readable form, and you can put it in Git or another VCS to track changes over time. Users often keep their Beancount file under version control to maintain an audit trail of every edit (with commit messages describing changes). This approach aligns with Beancount’s philosophy that accounting data, especially personal or small-business finances, should be transparent and “future-proof” – not locked in a proprietary database. In Martin Blais’s own words, Beancount is a “labor of love” built to be simple, durable, and free for the community. It was first developed around 2007 and has evolved through major rewrites (v1 to v2, and now v3 in 2024) to refine its design while preserving its core philosophy of minimalism and correctness.

Tools, Plugins, and Extensions in the Beancount Ecosystem

The Beancount ecosystem has grown a rich set of tools, plugins, and extensions that enhance the core ledger functionality. These cover importing data, editing ledgers, viewing reports, and adding specialized accounting features. Below is an overview of key components and add-ons in the Beancount world:

Data Importing Utilities (Importers)

One of the most important needs for practical use is importing transactions from banks, credit cards, and other financial institutions. Beancount provides an import framework and community-contributed import scripts for this purpose. In Beancount 2.x, the built-in module beancount.ingest (with commands like bean-extract and bean-identify) was used to define importer plugins in Python and apply them to downloaded statements. In Beancount 3.x, this has been replaced by an external project called Beangulp. Beangulp is a dedicated importers framework that evolved from beancount.ingest and is now the recommended way to automate transaction import for Beancount 3.0. It allows writing Python scripts or command-line tools that read external files (like CSV or PDF statements) and output Beancount entries. This new approach decouples import logic from the Beancount core – for example, the old bean-extract command has been removed in v3, and instead your import scripts themselves produce transactions via Beangulp’s CLI interface.

Dozens of ready-made importers exist for different banks and formats, contributed by the community. There are importer scripts for institutions around the world – from Alipay and WeChat Pay in China, to various European banks (Commerzbank, ING, ABN AMRO, etc.), to US banks like Chase and Amex. Many of these are collected in public repositories (often on GitHub) or in packages like beancount-importers. For instance, the Tarioch Beancount Tools project (tariochbctools) provides importers for Swiss and UK banks and even handles crypto transaction imports. Another example is Lazy Beancount, which packages a set of common importers (for Wise, Monzo, Revolut, IBKR, etc.) and provides a Docker-based setup for easy automation. No matter which bank or financial service you use, chances are someone has written a Beancount importer for it – or you can write your own using Beangulp’s framework. The flexibility of Python means importers can handle parsing CSV/Excel files, OFX/QIF downloads, or even scraping APIs, then emit transactions in standardized Beancount format.

Editing and Editor Integration

Because Beancount ledgers are just text, users often leverage their favorite text editors or IDEs to maintain them. The ecosystem provides editor support plugins to make this experience smoother. There are extensions for many popular editors that add syntax highlighting, auto-completion of account names, and real-time error checking:

  • Emacs Beancount-Mode: An Emacs major mode (beancount-mode) is available to edit .beancount files, offering features like syntax coloring and integration with Beancount’s checker. It can even run bean-check in the background so that errors in the ledger (like an unbalanced transaction) are flagged as you edit.
  • VS Code Extension: A Beancount extension on the VSCode Marketplace provides similar conveniences for Visual Studio Code users. It supports syntax highlighting, alignment of amounts, auto-completion for accounts/payees, and even on-the-fly balance checks when you save the file. It can also integrate with Fava, letting you launch the Fava web interface from within VSCode.
  • Plugins or modes also exist for Vim, Atom, and other editors. For example, there’s a Tree-sitter grammar for Beancount, which powers syntax highlighting in modern editors and was even adopted in Fava’s web-based editor component. In short, whatever your editing environment, the community has likely provided a plugin to make editing Beancount files convenient and error-free.

For quick entry of transactions outside of traditional editors, there are also tools like Bean-add and mobile apps. Bean-add is a command-line tool that allows adding a new transaction via a prompt or one-liner, handling date and account suggestions. On mobile, a project called Beancount Mobile provides a simple interface to input transactions on the go (for example, recording a cash purchase from your phone). Additionally, a Beancount Telegram Bot exists to capture transactions through messaging – you can send a message with transaction details, and the bot formats it into your ledger file.

Web Frontends and Visualization Tools

(Fava) Fava’s web interface provides an interactive dashboard for Beancount, featuring reports like an income statement with visualizations (shown here as a treemap of expenses by category) alongside tables of accounts and balances.

The flagship frontend for Beancount is Fava, a modern web interface. Fava runs as a local web app that reads your Beancount file and produces a rich interactive experience in your browser. It offers a full suite of reports: balance sheet, income statement, net worth over time, portfolio holdings, performance charts, budgets, and more – all out of the box. Users often cite Fava as a major reason for choosing Beancount over other plain-text accounting tools. With a single command (fava ledger.beancount), you can browse your finances with graphs and tables instead of text. Fava supports features like: drilling down on accounts, filtering transactions by payee or tag, a query editor (so you can run Beancount queries and see results in the browser), and even an integrated web-based editor for your ledger. It is highly usable, making plain text accounting approachable for those who prefer visual interfaces.

Under the hood, Fava is written in Python (Flask on the backend) and JavaScript (Svelte on the frontend). It has its own release cycle and is actively maintained. Notably, Fava has kept pace with Beancount’s development – for instance, Fava 1.30 added support for Beancount v3, switching to use the new beanquery and beangulp packages internally. (It still supports Beancount 2 for older ledgers.) Fava’s focus on usability includes nice touches like auto-complete in the web editor, and a sleek UI with dark mode and responsive charts. There’s also a spin-off called Fava-GTK, which packages Fava in a desktop application for GNOME/Linux users who prefer a native app feel.

Beyond Fava, other visualization and analysis options exist. Because Beancount data can be exported or queried as tables, users often leverage tools like Jupyter notebooks or Pandas for custom analysis. For example, one user describes pulling data from Beancount via the query interface into a Pandas DataFrame to prepare a custom report. There are also community-contributed scripts for specific reports – e.g. a portfolio allocation analysis tool or a process control chart for spending vs. net worth. However, for most people Fava provides more than enough reporting power without needing to write code. It even supports extensions: you can drop in Python files that add new report pages or charts to Fava. A notable extension is fava-envelope for envelope budgeting within Fava. Overall, Fava serves as the central visualization hub of the Beancount ecosystem.

Command-Line Utilities and Scripts

Beancount comes with various CLI tools (especially in the older v2 branch, some of which were trimmed in v3). These tools operate on your ledger file to check it or generate specific reports in text or HTML:

  • bean-check: a validator that checks for syntax errors or accounting errors in the file. Running bean-check myfile.beancount will alert you to any imbalance, missing account, or other issues, and output nothing if the file is error-free.
  • bean-format: a formatter that tidies up your ledger by aligning numbers into neat columns, much like running a code formatter on source code. This helps keep the file clean and readable.
  • bean-query: an interactive shell or batch tool to run Beancount’s query language on your ledger. You can use it to produce custom tabular reports (e.g., bean-query myfile.beancount "SELECT account, sum(amount) WHERE ...").
  • bean-report: a versatile report generator (in v2) that can output predefined reports (balance sheet, income statement, trial balance, etc.) to the console or to files. For example, bean-report file.beancount balances would print account balances. (In practice, many of these text reports have been supplanted by Fava’s nicer presentation.)
  • bean-web / bean-bake: an older web interface that would serve the reports on localhost or “bake” them as static HTML files. These were mostly used before Fava became popular; bean-web provided a basic web view of the same reports bean-report could generate. In Beancount 3, bean-web has been removed (since Fava is the recommended web frontend now, offering a superior experience).
  • bean-example: a utility to generate an example ledger file (useful for newcomers to see a template of Beancount entries).
  • bean-doctor: a debugging tool that can diagnose issues in your ledger or environment.

It’s worth noting that as of Beancount v3, many of these tools were moved out of the core project. The core Beancount package was streamlined, and tools like the query engine and importers were split into separate packages (beanquery, beangulp, etc.) for easier maintenance. For example, bean-query’s functionality is now provided by the beanquery tool which is installed separately. From a user perspective, the functionality remains available; it’s just been modularized. The Arch Linux community noted this change when updating Fava: the Fava package added dependencies on beanquery and beangulp to support Beancount 3.x. This modular approach also allows others in the community to contribute to these auxiliary tools more independently of Beancount’s release cycle.

Beancount Plugins and Extensions

A standout strength of the Beancount ecosystem is the plugin system. By adding a plugin "module.name" line in your Beancount file, you can incorporate custom Python logic that runs during the ledger processing. The community has created many plugins to extend Beancount’s capabilities:

  • Data quality and rules: Examples include beancount-balexpr which lets you assert equations involving multiple accounts (e.g., Asset A + Asset B = Liability X), and beancount-checkclosed which auto-inserts balance assertions when you close an account to ensure it nets to zero. There’s even a plugin to ensure transactions in the file are sorted by date (autobean.sorted) to catch out-of-order entries.
  • Automation: The beancount-asset-transfer plugin can generate in-kind transfer entries between accounts (useful for moving stocks between brokers while preserving cost basis). Another, autobean.xcheck, cross-checks your Beancount ledger against external statements for discrepancies.
  • Recurring transactions and budgets: The “repeat” or interpolate plugin by Akuukis allows defining recurring transactions or spreading an annual expense over months. For budgeting, the fava-envelope extension (used via Fava) supports envelope budgeting methodology in plain text. There’s also MiniBudget by Frank Davies – a small standalone tool inspired by Beancount to help with budgeting for personal or small business use.
  • Tax and reporting: Some plugins help with tax accounting, like one that classifies capital gains into short vs long-term automatically. Another (fincen_114 by Justus Pendleton) generates an FBAR report for US taxpayers with foreign accounts, illustrating how Beancount data can be leveraged for regulatory reporting.
  • Community plugin repositories: There are curated plugin sets such as beancount-plugins (by Dave Stephens) focusing on things like depreciation entries, and beancount-plugins-zack (by Stefano Zacchiroli) which include assorted helpers like sorting directives.

In addition to plugins, other utility tools orbiting Beancount address specific needs. For example, beancount-black is an auto-formatter similar to the Black code formatter, but for Beancount ledger files. There’s a Beancount Bot (Telegram/Mattermost) for adding transactions via chat as mentioned, and an Alfred workflow for macOS to quickly append transactions to your file. A tool named Pinto offers a “supercharged” CLI with interactive entry (like an enhanced bean-add). For those migrating from other systems, converters exist (YNAB2Beancount, CSV2Beancount, GnuCash2Beancount, Ledger2Beancount) to help bring in data from elsewhere.

In summary, the Beancount ecosystem is quite extensive. Table 1 below lists some major tools and extensions with their roles:

Tool/ExtensionDescription
Fava (web interface)Full-featured web app for viewing and editing Beancount books. Provides interactive reports (balance sheet, income, etc.), charts, and query capabilities. Major usability booster for Beancount.
Beangulp (import framework)Standalone importer framework for Beancount v3, replacing older ingest module. Helps convert bank statements (CSV, PDF, etc.) into Beancount entries using plugin scripts.
Beanquery (query tool)Standalone SQL-like query engine for Beancount data. Replaces bean-query in v3, allowing advanced querying of transactions and balances via a familiar SELECT-FROM-WHERE syntax.
Bean-check / Bean-formatCore CLI tools to validate a Beancount file (check for errors) and auto-format it for consistency. Useful for maintaining a correct and clean ledger.
Editor Plugins (Emacs, VSCode, Vim, etc.)Plugins/modes that add Beancount syntax support and linting in text editors. Improve the experience of manually editing .beancount files with features like auto-complete and live error highlighting.
Community ImportersCollections of bank import scripts (many on GitHub) covering banks in US, EU, Asia, and more. Allow users to automatically ingest transactions from their financial institutions into Beancount.
Plugins (Ledger extensions)Optional in-file plugins to enforce rules or add functionality (e.g. expense sharing, recurring entries, custom balance assertions). Written in Python and run during file processing for customization.

| Converters (Migration tools) | Utilities to convert data from other formats into Beancount, e.g. from GnuCash or Ledger CLI to Beancount format. Facilitate adopting Beancount without starting from scratch. |

Comparison with Ledger, hledger, and Similar Systems

Beancount belongs to the family of plain text double-entry accounting tools, among which Ledger CLI (John Wiegley’s Ledger) and hledger are prominent. While all these systems share the core idea of plaintext ledger files and double-entry bookkeeping, they differ in syntax, philosophy, and ecosystem maturity. The following table highlights key differences between Beancount, Ledger, and hledger:

AspectBeancount (Python)Ledger CLI (C++)hledger (Haskell)
Syntax & File StructureStrict, structured syntax defined by a formal grammar (BNF). Transactions have explicit date flag "Payee" "Narration" lines and postings with quantities; all accounts must be explicitly opened/defined. No implicit postings; every transaction must balance.More free-form syntax. Payee/description typically on the same line as the date. Allows some implicit balancing (like a single-posting transaction can imply a second posting to a default account). Account names can be used without prior declaration. Offers lots of command-line options that can affect parsing (e.g., year assumptions, commodity merge rules).Largely follows Ledger’s syntax with minor differences. hledger is a reimplementation of Ledger’s core features in Haskell, so the journal format is very similar to Ledger’s (with some extensions and stricter parsing by default). For example, hledger is a bit more strict about dates and commodity syntax than Ledger, but not as strict as Beancount.
PhilosophyConservative & Pedantic. Emphasizes catching user errors and maintaining data integrity above all. Imposes many checks (balance assertions, lot tracking) by default. Minimal configuration – “one way to do it” approach for consistency. Designed as a library with plugins for extensibility (treats ledger data as a stream to be processed, enabling custom Python logic).Optimistic & Flexible. Trusts the user to input data correctly; fewer built-in constraints by default. Highly customizable with dozens of options and command flags to adjust behavior. Tends to be a monolithic tool with features built-in (reports, plots) and uses domain-specific language within the ledger for things like automated transactions and periodic transactions. Extensibility is typically via external scripts or the built-in query language rather than plugin APIs.Pragmatic & Consistent. Aims to bring Ledger’s approach to a broader audience with predictable behavior. hledger defaults to more consistency (no balancing assumptions without explicit accounts) and has fewer footguns than Ledger’s most lenient modes. It has a subset of Ledger’s features (some of Ledger’s more exotic options aren’t supported), but adds some of its own (like a web interface and CSV import built-in). Emphasizes stability and correctness, but without a plugin system like Beancount’s.
Transactions & BalancingStrict double-entry: every transaction must have equal total debits and credits. Does not allow unbalanced entries or placeholders (no "virtual postings" that auto-balance). Also enforces ordering independence: the ledger can be sorted by date arbitrarily because balance assertions are date-scoped, not relying on file order. Cost tracking for commodities is rigorous – when you sell assets, you must specify lots or Beancount will enforce FIFO/LIFO such that you can't remove something you didn't add.Allows more leniency in transactions. Ledger permits "virtual" postings (using square brackets [ ] or parentheses) which don't require an explicit balancing account – often used to handle budgeting or implicit equity balancing. It's possible in Ledger to enter an incomplete transaction (omitting one side) and let Ledger infer the balancing amount. Also, Ledger does not strictly enforce lot-by-lot asset removal; it will happily subtract from an aggregate commodity balance even if specific lots weren't tracked. This makes it easier to, say, do average-cost accounting, but means Ledger won't stop you from mistakes like selling more shares than you have in a given lot.Similar to Ledger in allowing virtual postings and implicit balancing, but with more consistent behavior. hledger enforces stricter parsing rules than Ledger but is more lenient than Beancount.
Inventory & Cost BasisPrecise lot tracking. Beancount attaches cost information to commodity lots (e.g., purchase of 10 shares at $100 each), and when reducing an inventory it requires matching a specific lot or using a defined strategy. It ensures capital gains and cost bases are computed correctly by design. Average-cost method isn't the default unless you explicitly write logic for it, because Beancount treats each lot distinctly to preserve accuracy.More abstract inventory. Ledger treats commodity amounts more fluidly; by default all lots are merged in reports (it just shows total quantities). It provides options to report by lot or average cost if needed, but this is a reporting concern. Historically, Ledger did not use cost info to enforce balance in multi-commodity transactions, which could lead to subtle capital gains miscalculations. However, Ledger's flexibility lets users choose FIFO, LIFO, average, etc., at report time via command-line flags.Similar to Ledger with flexible inventory handling. hledger can track lots when specified but doesn't enforce lot-by-lot tracking as strictly as Beancount. Capital gains calculations are available but require more manual setup.
Reporting & UIPrimarily through Fava (web UI) and bean-query/bean-report. Fava offers a polished web dashboard with graphs and charts, making Beancount very user-friendly for analysis. Also supports textual reports and SQL-like queries via bean-query. No official TUI (text UI), but editors/IDEs integration fills that gap.Primarily CLI-based reporting. Ledger has many built-in report commands (balance, register, stats, etc.) that output text to the terminal. It can produce charts (ASCII or via gnuplot) and even has some add-ons for HTML reports, but it does not have an official web interface maintained as part of the project. (There have been third-party attempts at web UIs for Ledger, but none as prominent as Fava for Beancount.) For a UI, users rely on terminal or maybe GUIs like Ledger-Live (a separate project).Offers both CLI and a simple Web UI. hledger inherits Ledger’s CLI reports (with similar commands) and additionally provides hledger-web, a basic web interface for viewing accounts and transactions in a browser. hledger-web isn’t as feature-rich as Fava, but it gives a read-only overview. hledger also has hledger-ui, a terminal curses-based interface for interactive use.
Extensibility & PluginsHigh extensibility via Python. The plugin API allows arbitrary Python code to run during ledger processing, which means users can implement custom features without modifying core. The ecosystem of plugins (for budgeting, etc.) showcases this. Also, one can write Python scripts to use Beancount’s libraries for custom reporting.Lower-level extensibility. Ledger can be extended by writing your own scripts that parse Ledger’s output or by using its internal query language in clever ways. It also has features like automated transactions (rules that automatically generate postings given triggers in the journal) and periodic transactions, which are kinds of built-in extensibility within the ledger file. But it does not offer an API to inject arbitrary code into the accounting engine – it’s not a library in the same way (though libledger exists for C++ developers).Moderate extensibility. hledger deliberately omits Ledger’s automated/periodic transaction features to keep things simpler, but it provides tools like hledger-import for conversion of other formats and allows add-ons. Being written in Haskell, it’s used as a library in some projects, but writing custom plugins is not as straightforward as Beancount’s approach. Instead, hledger focuses on covering common needs (reports, web, UI) within its official toolset.
Community & DevelopmentActive but primarily driven by one author (Martin Blais) and a small group of contributors. Major releases are infrequent (v2 was stable for ~6 years, then v3 in 2024). The community contributes via plugins and tools (Fava was originally a third-party project that became integral). Beancount’s mailing list and GitHub are active with discussions, and the user base has grown thanks to Fava’s appeal to non-developers.Long history (Ledger dates back to 2003) and wide usage among engineers. Originally a one-person project (Wiegley), it saw many contributors over time. Ledger’s development has slowed in recent years; it’s stable but fewer new features (the focus has shifted to maintenance). The mailing list ledger-cli is a hub for all plaintext accounting discussions (including Beancount and hledger). Many tools and scripts around Ledger exist, but the ecosystem is not as unified (no single “Ledger GUI”, etc., though multiple independent efforts exist).Growing community, with Simon Michael leading hledger’s development. hledger has annual releases and steady improvements, often tracking Ledger feature changes but also forging its own path. It enjoys popularity among users who want Ledger’s power with more predictability. The community tends to overlap with Ledger’s (plaintextaccounting.org covers both). hledger’s ecosystem includes add-ons like hledger-flow (for workflow automation) and it benefits from being written in Haskell (attracting those in that community).

In summary, Beancount differentiates itself with its emphasis on strictness, plugin-based extensibility, and a user-friendly web interface. Ledger remains the classic, highly flexible tool favored by command-line purists and those who need ultimate speed (Ledger’s C++ engine is very fast on huge files). hledger provides a middle ground – much of Ledger’s functionality with a bit more structure and an officially supported (if simple) web UI. All three share the advantages of plain text accounting (auditability, Git versioning, plain data), but Beancount’s ecosystem (especially with Fava) has arguably made it more accessible to the average user in recent years. On the flip side, Ledger/hledger users sometimes prefer their relative simplicity in setup (no Python needed) and long-proven stability. Ultimately, choosing between them comes down to personal preference: those who value rigorous correctness and a rich ecosystem often lean toward Beancount, whereas those who want lean, terminal-focused tooling might stick with Ledger or hledger.

Usage Scenarios for Beancount

Beancount is versatile enough to be used for personal finance tracking as well as (in some cases) small business accounting. Its core double-entry approach is the same in both scenarios, but the scale and specific practices can differ.

Personal Finance

Many Beancount users employ it to manage their individual or household finances. A typical personal finance setup in Beancount might include accounts for checking and savings, credit cards, investments, loans, income categories (salary, interest, etc.), and expense categories (rent, groceries, entertainment, etc.). Users record day-to-day transactions either manually (entering receipts, bills, etc.) or by importing from bank statements using the importer tools discussed earlier. The benefits Beancount brings to personal finance include:

  • Consolidation and Analysis: All your transactions can live in a single text file (or a set of files) that represents years of financial history. This makes it easy to analyze long-term trends. With Beancount’s query language or with Fava, you can answer questions like “How much did I spend on travel in the past 5 years?” or “What’s my average monthly grocery bill?” in seconds. One user noted that after switching to Beancount, “analysis of financial data (spending, giving, taxes, etc.) is trivial” either through Fava or by querying the data and using tools like Pandas. In essence, your ledger becomes a personal financial database you can query at will.
  • Budgeting and Planning: While Beancount doesn’t force a budgeting system, you can implement one. Some users do envelope budgeting by creating budget accounts or using the fava-envelope plugin. Others simply use periodic reports to compare spending to targets. Because it’s plain text, integrating Beancount with external budgeting tools or spreadsheets is straightforward (exporting data or using CSV outputs from queries).
  • Investments and Net Worth Tracking: Beancount excels at tracking investments thanks to its robust handling of cost bases and market prices. You can record buys/sells of stocks, crypto, etc., with cost details, and then use Prices directives to keep track of market value. Fava can show a net worth over time chart and portfolio breakdown by asset class. This is hugely useful for personal wealth management – you get insights similar to what commercial tools like Mint or Personal Capital provide, but fully under your control. Multi-currency handling is also built-in, so if you hold foreign currencies or crypto, Beancount can track those and convert for reporting.
  • Reconciliation and Accuracy: Personal finance often involves reconciling with bank statements. With Beancount, one can regularly reconcile accounts by using balance assertions or the documents feature. For example, every month you might add a balance Assets:Bank:Checking <date> <balance> entry to confirm your ledger matches the bank’s statement at month-end. The bean-check tool (or Fava’s error display) will alert you if things don’t line up. One user mentions doing a monthly reconciliation of all accounts, which “helps catch any unusual activity” – a good personal finance hygiene practice that Beancount facilitates.
  • Automation: Tech-savvy individuals have automated large parts of their personal finance workflow with Beancount. Using importers, cron jobs, and maybe a bit of Python, you can set up your system so that, for instance, every day your bank transactions are fetched (some use OFX or APIs) and appended to your Beancount file, categorized by rules. Over time, your ledger becomes mostly auto-updated, and you just review and tweak as needed. A community member on Hacker News shared that after 3 years, their Beancount books were “95% automatic”. This level of automation is possible because of Beancount’s plain text openness and scripting capabilities.

Personal finance users often choose Beancount over spreadsheets or apps because it gives them complete ownership of the data (no reliance on a cloud service that might shut down – a concern as Mint was discontinued, for example) and because the depth of insight is greater when you have all your data integrated. The learning curve is non-trivial – one must learn basic accounting and the Beancount syntax – but resources like the official documentation and community tutorials help newcomers get started. Once set up, many find that it brings peace of mind to have a clear, trustworthy picture of their finances at all times.

Small Business Accounting

Using Beancount for a small business (or nonprofit, club, etc.) is less common than personal use, but it is certainly possible and some have done it successfully. Beancount’s double-entry framework is in fact the same system that underpins corporate accounting, just without some of the higher-level features that dedicated accounting software provides (like invoicing modules or payroll integrations). Here’s how Beancount can fit into a small business context:

  • General Ledger and Financial Statements: A small business can treat the Beancount file as its general ledger. You would have asset accounts for bank accounts, accounts receivable, maybe inventory; liability accounts for credit cards, loans, accounts payable; equity for owner’s capital; income accounts for sales or services; and expense accounts for all business expenses. By maintaining this ledger, you can produce an Income Statement (Profit & Loss) and Balance Sheet at any time using Beancount’s reports or queries. In fact, Beancount’s built-in reports or Fava can generate a balance sheet and P&L in seconds that are perfectly in line with accounting principles. This can be sufficient for a small operation to assess profitability, financial position, and cash flow (with a bit of querying for cash flow, since direct cash flow statements aren’t built-in but can be derived).
  • Invoices and A/R, A/P: Beancount does not have a built-in invoicing system; users would typically handle invoicing outside (e.g., create invoices in Word or an invoice app) and then record the results in Beancount. For example, when you issue an invoice, you’d record an entry debiting Accounts Receivable and crediting Income. When the payment comes, you debit Cash/Bank and credit Accounts Receivable. This way, you can keep track of outstanding receivables by looking at the balance of the A/R account. The same applies to bills (A/P). While it’s more manual than specialized accounting software (which might send reminders or integrate with emails), it is perfectly doable. Some users have shared templates or workflows on how they manage invoices with Beancount and ensure they don’t miss open invoices (for instance, by using metadata or custom queries to list unpaid invoices).
  • Inventory or Cost of Goods Sold: For businesses selling products, Beancount can track inventory purchases and sales, but it requires disciplined entries. You might use the Inventory and cost accounting features: purchasing inventory increases an asset account (with cost attached to the items), selling it moves cost to an expense (COGS) and records revenue. Because Beancount insists on matching lots, it will enforce proper reduction of inventory with the correct cost, which can actually ensure your gross profit calculations are accurate if done right. However, there’s no automated SKU tracking or anything – it’s all at the financial level (quantity and cost).
  • Payroll and Complex Transactions: Beancount can record payroll transactions (salary expense, tax withholdings, etc.), but calculating those figures might be done externally or via another tool, then just booked into Beancount. For a very small business (say one or two employees), this is manageable. You’d, for example, record a single journal entry per pay period that splits out wages, tax withheld, employer tax expense, cash paid, etc. Doing this manually is similar to how one might do it in QuickBooks journal entries – it requires knowledge of what accounts to hit.
  • Multi-user and Audit: One challenge in a business setting is if multiple people need to access the books or if an accountant needs to review them. Since Beancount is a text file, it’s not multi-user in real-time. However, hosting the file in a Git repository can enable collaboration: each person can edit and commit, and differences can be merged.
  • Regulatory compliance: For tax filing or compliance, Beancount’s data can be used to generate the necessary reports, but it may require custom queries or plugins. We saw an example of a community plugin for Indian government compliance reporting, and one for FinCEN FBAR reporting. This shows that, with effort, Beancount can be adapted to meet specific reporting requirements. Small businesses in jurisdictions with simple requirements (cash accounting, or basic accrual) can certainly maintain books in Beancount and produce financial statements for tax returns. However, features like depreciation schedules or amortization might need you to write your own entries or use a plugin (Dave Stephens’ depreciation plugins help automate that for instance). There isn’t a GUI to “click depreciate asset” as in some accounting software; you’d encode the depreciation as transactions (which in a way demystifies it – everything is an entry you can inspect).

In practice, many tech-oriented small business owners have used Beancount (or Ledger/hledger) if they prefer control and transparency over the convenience of QuickBooks. A Reddit discussion noted that for standard small-business accounting with a limited volume of transactions, Beancount works fine. The limiting factor is usually the comfort level – whether the business owner (or their accountant) is comfortable with a text-based tool. One advantage is cost: Beancount is free, whereas accounting software can be costly for a small business. On the other hand, lack of official support and the DIY nature means it’s best suited for those who are both the business owner and somewhat technically inclined. For freelancers or sole proprietors with programming skills, Beancount can be an attractive choice to manage finances without relying on cloud accounting services.

Hybrid approaches are also possible: some small businesses use an official system for invoices or payroll, but periodically import the data into Beancount for analysis and archival. This way they get the best of both worlds – compliance and ease for day-to-day operations, plus the power of Beancount for consolidated insight.

In summary, Beancount can handle small business accounting, provided the user is willing to manually manage things that commercial software automates. It ensures a high degree of transparency – you deeply understand your books because you’re writing them – and for a diligent user, it can produce impeccable books. Both personal and business users benefit from Beancount’s core strengths: a reliable accounting engine, complete audit trail, and flexibility to adapt to unique scenarios (via scripting and plugins). Whether it’s tracking a household budget or a startup’s finances, Beancount offers a toolkit to do it with precision and openness.

Community and Development Activity

Beancount has a dedicated community and a development story that reflects its open-source, niche-but-passionate nature. Below are key points about its community, maintainers, and related projects:

  • Project Maintenance: Beancount’s primary author is Martin Blais, who began the project around 2007 and has shepherded it through multiple versions. Development for a long time was largely a one-man effort (aside from community contributions of patches). Martin’s philosophy was to build an accounting tool “useful to me first, as well as for others, in the simplest, most durable manner”. This personal motivation kept the project going as a labor of love. As of 2025, Martin Blais is still the lead maintainer (his name appears on commits and he answers questions on the mailing list/issue tracker), but the ecosystem around Beancount has many other contributors in their respective projects.

  • GitHub and Repositories: The source code is hosted on GitHub under the beancount/beancount repository. The project is GPL-2.0 licensed and has attracted a modest number of contributors over the years. In mid-2024, Beancount Version 3 was officially released as the new stable branch. This release involved splitting out some components: for example, the beangulp repo (for importers) and beanquery repo (for the query tool) are part of the beancount GitHub organization now, maintained somewhat independently. The main Beancount repo focuses on the core accounting engine and file parser. As of 2025, Beancount’s GitHub shows active issue discussions and some ongoing development – though not high volume, issues and pull requests trickle in, and occasional updates are made to fix bugs or refine features.

  • Fava Development: Fava, the web interface, started as a separate project (created by Dominic Aumayr, who copyrighted it in 2016). It has its own community of contributors and is also on GitHub under beancount/fava. Fava’s maintainers and contributors (e.g. Jakob Schnetz, Stefan Otte, and others in recent years) have been actively improving the interface, with releases every few months. Fava’s Gitter chat (linked on the Fava docs) and GitHub issue tracker are places where users and devs discuss new features or bugs. The project welcomes contributions, evidenced by a CHANGELOG note thanking multiple community members for their PRs. Fava’s close alignment with Beancount’s development (such as quickly adding support for Beancount v3 and new beanquery syntax) indicates good collaboration between the two projects.

  • Mailing Lists and Forums: Beancount has an official mailing list (previously on Google Groups, titled “Beancount” or sometimes discussed on the general Ledger list). This mailing list is a treasure trove of knowledge – users ask questions about how to model certain scenarios, report bugs, and share tips. Martin Blais is known to respond on the mailing list with detailed explanations. In addition, the broader Plain Text Accounting community overlaps heavily. The Ledger CLI mailing list often entertains questions about Beancount as well, and there is a forum at plaintextaccounting.org and a subreddit r/plaintextaccounting where Beancount topics come up frequently. Users on these platforms discuss comparisons, share personal setups, and help newcomers. The general tone of the community is very cooperative – Beancount users often help Ledger users and vice versa, recognizing that all these tools have similar goals.

  • Chat Groups: Besides mailing lists, there are chat channels like the Plaintext Accounting Slack/Discord (community-organized) and the Fava Gitter. These are less formal, more real-time ways to get help or discuss features. For example, one might hop on the Slack to ask if anyone has an importer for a specific bank. There is also a Matrix/IRC channel (historically #ledger or #beancount on IRC) where some long-time users idle. While not as populous as communities for mainstream software, these channels have knowledgeable folks who can often answer obscure accounting questions.

  • Contributors and Key Community Members: A few names stand out in the Beancount community:

    • “Redstreet” (Red S): A prolific contributor who has written many plugins (like beancount-balexpr, sellgains, and others) and often provides support. They also maintain a set of importer scripts and a tool called bean-download to fetch statements.
    • Vasily M (Evernight): Author of some importer frameworks and plugins like beancount-valuation, and contributions to Fava regarding investments.
    • Stefano Zacchiroli (zack): A Debian developer who created the beancount-mode for Emacs and his own plugin repo. He has advocated for plaintext accounting in academic settings as well.
    • Simon Michael: While primarily the lead of hledger, he runs plaintextaccounting.org which includes Beancount. This cross-pollination helped bring Beancount to the attention of Ledger/hledger users.
    • Frank hell (Tarioch): Contributor of the Tarioch Beancount Tools, a major set of importers and price fetchers especially for European institutions.
    • Siddhant Goel: A community member who blogs about Beancount (for example, his guide on migrating to v3) and maintains some importers. His blog posts have helped many new users.

    These and many others contribute code, documentation, and help on forums, making the ecosystem vibrant despite its relatively small size.

  • GitHub Stats and Forks: Beancount’s GitHub repo has accumulated a few hundred stars (indicating interest) and forks. Notable forks of Beancount itself are rare – there isn’t a well-known divergent fork that tries to be “Beancount but with feature X”. Instead, when users wanted something different, they either wrote a plugin or used another tool (like hledger) rather than fork Beancount. One could consider hledger a kind of fork of Ledger (not Beancount) and Beancount itself an independent re-imagining of Ledger’s ideas, but within Beancount’s repo there aren’t big splinter projects. The community has generally coalesced around the main repo and extended it via the plugin interface instead of fragmenting the codebase. This is likely because Martin Blais was open to external contributions (his docs even have a section acknowledging external contributions and modules) and the plugin architecture made it unnecessary to maintain a fork for most new features.

  • Community Resources: There are several high-quality resources for learning and using Beancount created by the community:

    • The Beancount documentation on GitHub Pages (and the source Google Docs that Martin maintains) – very comprehensive, including theory on accounting and how Beancount implements it.

    • Numerous blog posts and personal notes – e.g., LWN.net had an article “Counting beans… with Beancount”, and many personal blogs (as listed in Awesome Beancount’s “Blog Posts” section) share experiences and tips. These help build knowledge and attract new users.

    • Talks and presentations: Beancount has been presented at meetups and conferences (for instance, a PyMunich 2018 talk on managing finances with Python/Beancount). Such talks introduce the tool to broader audiences and often spark interest on forums like Hacker News.

  • Notable Related Projects: Apart from Fava, some other projects related to Beancount have their own communities:

    • Plain Text Accounting site – maintained by Simon Michael, it aggregates info on all such tools and has a forum where people share usage for various tools including Beancount.
    • Financial tooling integration: Some users integrate Beancount with business intelligence tools or databases. For example, one Google Groups thread details using PostgreSQL with Beancount data via custom functions. While not mainstream, it shows the community’s experimental spirit in pushing Beancount’s capabilities (e.g., to handle very large datasets or complex queries beyond the built-in).

In summary, Beancount’s community, while smaller than those of big open-source projects, is highly engaged and knowledgeable. The project enjoys a steady stream of improvements and very helpful support channels. The collaborative ethos (sharing importers, writing plugins, answering questions) means that a newcomer in 2025 can rely on extensive prior work and community wisdom to set up their accounting system. Development is active in the ecosystem sense – Fava releases, plugin development, etc. – even if the core’s changes are more occasional. The ecosystem’s growth (as evidenced by the Awesome Beancount list of dozens of tools) speaks to a healthy community making Beancount ever more capable.

Recent Developments and Upcoming Features

As of 2025, the Beancount ecosystem has seen significant developments in the past couple of years, and there are ongoing discussions about future enhancements. Here are some noteworthy recent developments and a glimpse of what might be coming:

  • Beancount 3.0 Release (2024): After a long period of Beancount 2.x being the standard, version 3 was officially released in mid-2024. This was a major milestone because v3 represents a simplification and modernization of the codebase. Martin Blais had envisioned v3 as a chance to “rearrange and simplify” the system further. While it was originally thought to be a big rewrite, in practice the update for users was not too disruptive. The main changes were under the hood: a new parser, some performance improvements, and the extraction of optional components out of the core. The release was rolled out gradually (v3 had been in beta since 2022, but by July 2024 it became the recommended stable version). Users like Siddhant Goel reported that migrating from 2.x to 3.x was “mostly uneventful” with only a few workflow changes.

  • Modularization – tools moved to separate packages: One of the big changes with Beancount 3 is that many tools that used to live in the monolithic repository were spun off. For example, bean-query is now provided by the beanquery package, and beancount.ingest was replaced by the beangulp package. Commands like bean-extract and bean-identify (for imports) were removed from core Beancount. Instead, the philosophy is to use standalone scripts for importing. This means that if you upgrade to v3, you’d install beangulp and run importer scripts (each importer is basically a small program) rather than having a central bean-extract config file. Similarly, queries are executed via beanquery which can be installed and updated independently of Beancount core. This modular approach was designed to make maintenance easier and encourage community contributions. It also slimmed down Beancount’s core, so the core focuses purely on parsing and accounting logic, while ancillary functionality can evolve separately. From a user perspective, after upgrading, one has to adjust commands (e.g., use bean-query from beanquery, or use Fava which abstracts this anyway). Fava’s changelog explicitly notes these changes: Fava now depends on beanquery and beangulp, and it handles import workflows differently for Beancount 3 vs 2.

  • Performance Improvements: Performance was one motivation for revisiting Beancount’s design. The v3 plan (as outlined in Martin’s “V3 goals” document) included optimizing the parser and possibly making the loading process faster and less memory-intensive. By 2025, some of these improvements have materialized. Anecdotally, users with very large ledgers (tens of thousands of transactions, or lots of stock trades) have reported better performance with the latest version. For instance, a user dealing with “microinvestment transactions” who faced performance issues noted these concerns on the Google Group – this kind of feedback likely informed v3. The new parser is more efficient and written in a clearer way, which could be extended in the future. Additionally, Fava 1.29 moved to a more efficient file-watching mechanism (using the watchfiles library) to improve responsiveness when the ledger changes. Looking forward, the community might explore incremental parsing (only re-processing changed parts of the file instead of everything) to handle large ledgers more quickly – this was hinted in the docs as “Beancount server / incremental booking” idea.

  • Investment Tracking Enhancements: There’s been ongoing work to make investment and portfolio reporting better. For example, handling of average cost basis vs. FIFO was discussed at length. While Beancount enforces lot matching, some users prefer average cost for certain jurisdictions. A proposal and discussion exist about making cost basis booking more flexible (possibly via a plugin or option). By 2025, no built-in switch for average cost is present, but the groundwork in v3 (the booking redesign) makes it easier for plugins to implement. A community plugin “Gains Minimizer” was released that can suggest which lots to sell to minimize taxes, showing the kind of advanced tooling being built around investments. Fava, too, added features like a portfolio summary extension (with rate of return calculations). In terms of upcoming features, one can expect more in this domain: possibly automated portfolio rebalancing suggestions or risk analysis, likely as external tools that read Beancount data (since the data is all there).

  • New Plugins and Extensions: The plugin ecosystem continuously grows. Recent notable additions include:

    • Budget reporting tools – e.g., a simple CLI budget reporter if one doesn’t use Fava’s UI.
    • Encryption and security – the fava-encrypt setup, allowing Fava to be hosted online with the ledger encrypted at rest, was introduced, addressing the concern of self-hosting your finances.
    • Quality-of-life plugins – like autobean-format (a new formatter that can handle more corner cases by parsing and reprinting the file), and beancheck integration in editors (flymake for Emacs).

    Looking ahead, the community is likely to continue filling gaps via plugins. For example, we might see more tax-related plugins (some users have shared scripts for things like computing wash sales or specific local tax reports).

  • Potential Upcoming Features: Based on discussions on the issue tracker and mailing list, a few ideas are on the horizon (though not guaranteed):

    • Time Resolution: Currently, Beancount only tracks dates (no timestamps) for transactions. There have been questions about adding time (for stock trades or ordering of same-day transactions). Martin Blais explicitly decided that sub-day timestamps were out of scope to keep things simple. This is unlikely to change soon – so upcoming versions probably will not add time resolution, sticking to the stance that if you need time, you incorporate it into narration or an account.
    • Enhanced GUI editing: Fava is continuously improving its editing capabilities. A possibility is a more full-featured web editor (with auto-suggest, maybe a form-based entry for new transactions). The groundwork using tree-sitter in Fava’s editor was laid. We might see Fava become not just a viewer but a more powerful editor, reducing the need to open a text editor at all for many tasks.
    • Better multi-ledger support: Some users maintain multiple Beancount files (for different entities or for splitting personal vs business). Right now, including files is possible but had limitations (plugins in included files, etc.). A recent plugin autobean.include was created to safely include external ledgers. In the future, we might see first-class support for multi-file setups – perhaps a concept of a Beancount “project” with multiple files (this is hinted by features like the VSCode extension’s beancount.mainBeanFile setting). This would help those running multi-entity bookkeeping or wanting to modularize their ledger.
    • Realtime or Incremental Computation: As ledgers grow, the ability to recompute reports quickly becomes important. There is an idea of a Beancount server that stays running and updates results as transactions change. This could manifest as an optimization in Fava or a daemon that editor plugins can query. Perhaps a future Fava release will leverage a continuously running Beancount process to make the UI more responsive for huge ledgers.
    • Fund Accounting / Non-profit features: There was an enhancement proposal about fund accounting in Beancount. Non-profit organizations have accounting needs (restricted vs unrestricted funds) that could potentially be modeled with Beancount’s tag or account hierarchy. The discussion didn’t yet lead to built-in features, but if more non-profits pick up Beancount, this could drive new capabilities (maybe just documented best practices or plugins for fund balance tracking).
  • Long-Term Outlook: Martin Blais hinted that he sees the future of Beancount in making the core more of an engine and moving more functionality to plugins. This is consistent with what we see (modularization in v3). So, an “upcoming feature” in philosophical terms is greater extensibility – possibly even allowing plugins to define new directive types or extend syntax in controlled ways. If that happens, Beancount’s core might remain relatively small and stable, while the ecosystem delivers most new functionality as add-ons. This could lead to a plugin marketplace or more centralized listing of plugins so users can pick and choose (the Awesome Beancount list is a start at that).

In conclusion, the Beancount ecosystem in 2025 is active and evolving. The release of Beancount 3.0 was a major recent event, ensuring the project’s foundation is solid for the future. Improvements in performance, tooling, and usability (especially via Fava) have continued to lower the barrier to entry. While Beancount remains a tool that requires some expertise, it is far more approachable now than a few years ago, thanks to these developments. Upcoming features will likely focus on refining the experience – faster performance, better integrations, and specialized extensions – rather than drastic changes to the core philosophy. The community’s trajectory suggests that Beancount will continue to mature as the centerpiece of plain text accounting, striking a balance between the austere power of double-entry bookkeeping and the convenience of modern software. As one user quipped on Hacker News, plain text accounting gives you “super powers” in understanding your finances – and Beancount’s recent and future improvements aim to make those super powers easier to wield for everyone.

Sources: Beancount documentation and repository; Fava documentation; “A Comparison of Beancount and Ledger” by Martin Blais; Awesome Beancount resource list; User experiences and community reports;

Understanding Receivables and Payables in Beancount

· 3 min read
Mike Thrift
Mike Thrift
Marketing Manager

Hello everyone! In today's blog post, we're diving into the world of Beancount, a double-entry accounting tool that's loved by many for its simplicity and power. More specifically, we're going to talk about two key concepts: Receivables and Payables.

Understanding these terms is crucial to using Beancount (or any double-entry accounting system) effectively. But don't worry if you're a beginner - we're going to break it all down, step by step!

Receivables and Payables: The Basics

2023-05-30-receiveable-and-payable

In accounting, "receivables" and "payables" are terms used to track money that is owed. "Receivables" refers to money that others owe to you, while "payables" refers to money that you owe to others.

Let's take an example:

  1. Accounts Receivable (A/R): Suppose you own a bookstore and a customer buys a book on credit. The money they owe you for the book is an account receivable.

  2. Accounts Payable (A/P): On the flip side, imagine you order a new set of books from a publisher, but you don't pay for them upfront. The money you owe the publisher is an account payable.

In Beancount, these are typically tracked through corresponding accounts. The main benefit here is that it provides you with a clear and accurate picture of your financial position at any point in time.

Setting Up Receivables and Payables in Beancount

The structure of your Beancount file can be as simple or as complex as you need it to be. For receivables and payables, you'll likely want to create separate accounts under your Assets and Liabilities sections.

Here is a simple example:

1970-01-01 open Assets:AccountsReceivable
1970-01-01 open Liabilities:AccountsPayable

Tracking Transactions

Payee side

After setting up your accounts, you can track transactions that involve receivables and payables. Let's look at an example:

2023-05-29 * "Sold books to customer on credit"
Assets:AccountsReceivable 100 USD
Income:BookSales -100 USD

Here, you're adding $100 to your receivables because a customer owes you this amount. Simultaneously, you're reducing your income by the same amount to maintain the balance (since you haven't actually received the money yet).

When the customer eventually pays, you'll record it like this:

2023-06-01 * "Received payment from customer"
Assets:Bank:Savings 100 USD
Assets:AccountsReceivable -100 USD

Payer side

The same principle applies for payables, but with reversed signs:

2023-05-30 * "Bought books from publisher on credit"
Liabilities:AccountsPayable 200 USD
Expenses:BookPurchases -200 USD

And when you pay off your debt:

2023-06-02 * "Paid off debt to publisher"
Liabilities:AccountsPayable -200 USD
Assets:Bank:Checking 200 USD

Wrapping Up

Receivables and payables are at the heart of any accounting system. By accurately tracking these, you gain a comprehensive understanding of your financial health.

This is just a starting point, and Beancount is capable of much more. I hope this blog post helps clarify these important concepts. As always, happy accounting!

Deconstructing a Beancount Ledger: A Case Study for Business Accounting

· 3 min read
Mike Thrift
Mike Thrift
Marketing Manager

In today's blog post, we will be breaking down a Beancount ledger for businesses, which will help you understand the intricacies of this plain text double-entry accounting system.

Deconstructing a Beancount Ledger: A Case Study for Business Accounting

Let's start with the code first:

2023-05-22-business-template

1970-01-01 open Assets:Bank:Mercury
1970-01-01 open Assets:Crypto

1970-01-01 open Equity:Bank:Chase

1970-01-01 open Income:Stripe
1970-01-01 open Income:Crypto:ETH

1970-01-01 open Expenses:COGS
1970-01-01 open Expenses:COGS:Contabo
1970-01-01 open Expenses:COGS:AmazonWebServices

1970-01-01 open Expenses:BusinessExpenses
1970-01-01 open Expenses:BusinessExpenses:ChatGPT

2023-05-14 * "CONTABO.COM" "Mercury Checking ••1234"
Expenses:COGS:Contabo 17.49 USD
Assets:Bank:Mercury -17.49 USD

2023-05-11 * "Amazon Web Services" "Mercury Checking ••1234"
Expenses:COGS:AmazonWebServices 14490.33 USD
Assets:Bank:Mercury -14490.33 USD

2023-03-01 * "STRIPE" "Mercury Checking ••1234"
Income:Stripe -21230.75 USD
Assets:Bank:Mercury 21230.75 USD

2023-05-18 * "customer_182734" "0x5190E84918FD67706A9DFDb337d5744dF4EE5f3f"
Assets:Crypto -19 ETH {1,856.20 USD}
Income:Crypto:ETH 19 ETH @@ 35267.8 USD

Understanding the Code

  1. Opening Accounts: The code starts by opening a series of accounts on 1970-01-01. These include a mix of asset accounts (Assets:Bank:Mercury and Assets:Crypto), an equity account (Equity:Bank:Chase), income accounts (Income:Stripe and Income:Crypto:ETH), and expense accounts (Expenses:COGS, Expenses:COGS:AmazonWebServices, Expenses:BusinessExpenses, and Expenses:BusinessExpenses:ChatGPT).

  2. Transactions: It then progresses to record a series of transactions between 2023-03-01 and 2023-05-18.

    • The transaction on 2023-05-14 represents a payment of $17.49 to CONTABO.COM from Mercury Checking ••1234. This is recorded as an expense (Expenses:COGS:Contabo) and a corresponding deduction from the Assets:Bank:Mercury account.

    • Similarly, the transaction on 2023-05-11 represents a payment of $14490.33 to Amazon Web Services from the same bank account. This is logged under Expenses:COGS:AmazonWebServices.

    • The transaction on 2023-03-01 shows income from STRIPE being deposited into Mercury Checking ••1234, totaling $21230.75. This is recorded as income (Income:Stripe) and an addition to the bank account (Assets:Bank:Mercury).

    • The last transaction on 2023-05-18 represents a crypto transaction involving 19 ETH from a customer. This is tracked under Assets:Crypto and Income:Crypto:ETH. The {1,856.20 USD} shows the price of ETH at the time of transaction, while the @@ 35267.8 USD specifies the total value of the 19 ETH transaction.

In all transactions, the principle of double-entry accounting is maintained, ensuring that the equation Assets = Liabilities + Equity always holds true.

Final Thoughts

This Beancount ledger provides a straightforward yet robust system for tracking financial transactions. As seen in the final transaction, Beancount is flexible enough to account for non-traditional assets like cryptocurrency, which is a testament to its utility in our increasingly digital financial landscape.

We hope this breakdown helps you better understand the structure and capabilities of Beancount, whether you're a seasoned accountant or a beginner trying to keep track of your personal finances. Stay tuned for our next blog post, where we'll delve further into advanced Beancount operations.

Beancount Cheat Sheet

· 2 min read
Mike Thrift
Mike Thrift
Marketing Manager

Example Account Name

Assets:US:BofA:Checking

cheatsheet-en

Account Types

Assets          +
Liabilities -
Income -
Expenses +
Equity -

Commodities

CNY, EUR, CAD, AUD
GOOG, AAPL, RBF1005
HOME_MAYST, AIRMILES
HOURS

Directives

General syntax

YYYY-MM-DD <Directive> <Parameters...>

Opening & Closing Accounts

2001-05-29 open Expenses:Restaurant
2001-05-29 open Assets:Checking USD,EUR ; Currency constraints

2015-04-23 close Assets:Checking

Declaring Commodities (Optional)

1998-07-22 commodity AAPL
name: "Apple Computer Inc."

Prices

2015-04-30 price AAPL   125.15 CNY
2015-05-30 price AAPL 130.28 CNY

Notes

2013-03-20 note Assets:Checking "Called to ask about rebate"

Documents

2013-03-20 document Assets:Checking "path/to/statement.pdf"

Transactions

2015-05-30 * "Some narration about this transaction"
Liabilities:CreditCard -101.23 CNY
Expenses:Restaurant 101.23 CNY

2015-05-30 ! "Cable Co" "Phone Bill" #tag ˆlink
id: "TW378743437" ; Meta-data
Expenses:Home:Phone 87.45 CNY
Assets:Checking ; You may leave one amount out

Postings

  ...    123.45 USD                             Simple
... 10 GOOG {502.12 USD} With per-unit cost
... 10 GOOG {{5021.20 USD}} With total cost
... 10 GOOG {502.12 # 9.95 USD} With both costs
... 1000.00 USD @ 1.10 CAD With per-unit price
... 10 GOOG {502.12 USD} @ 1.10 CAD With cost & price
... 10 GOOG {502.12 USD, 2014-05-12} With date
! ... 123.45 USD ... With flag

Balance Assertions and Padding

; Asserts the amount for only the given currency:
2015-06-01 balance Liabilities:CreditCard -634.30 CNY

; Automatic insertion of transaction to fulfill the following assertion:
2015-06-01pad Assets:Checking Equity:Opening-Balances

Events

2015-06-01 event "location" "New York, USA"
2015-06-30 event "address" "123 May Street"

Options

option "title" "My Personal Ledger"

Other

pushtag #trip-to-peru
...
poptag #trip-to-peru
; Comments begin with a semi-colon

The Magic of Plain Text Accounting with Beancount

· 5 min read
Mike Thrift
Mike Thrift
Marketing Manager

Discover the Magic of Plain Text Accounting with Beancount

Beancount.io banner

Introduction

2023-04-18-introduction-to-beancount

Welcome to a world where accounting is no longer a daunting task. Today, we introduce you to Beancount, a powerful, flexible, and intuitive plain text accounting tool. Beancount empowers you to take control of your finances by providing a transparent and straightforward approach to managing your money.

In this comprehensive guide, we will delve into the basics of Beancount, explain its core concepts, and walk you through its simple yet powerful features. By the end of this blog, you'll have a solid understanding of Beancount and be ready to start using it to organize and analyze your financial life.

What is Beancount?

Beancount is an open-source, plain text accounting system created by Martin Blais. Inspired by John Wiegley's Ledger system, Beancount aims to provide a robust and reliable method to manage personal and small business finances using plain text files. With Beancount, you can track your income, expenses, investments, and much more with ease.

Why Beancount?

Plain text accounting offers several advantages over traditional spreadsheet-based or software-based accounting systems:

  • Transparency: Beancount files are human-readable, making it easy to understand and audit your financial data.
  • Flexibility: Beancount can be easily customized to fit your specific needs, and you can use your favorite text editor and version control system to manage your financial data.
  • Portability: Your financial data can be accessed on any device, and it's easy to transfer between systems or share with others.
  • Future-proof: Plain text files are universally compatible, ensuring that your financial data will remain accessible, even as technology evolves.

Beancount's Core Concepts

To use Beancount effectively, it's crucial to understand its core concepts:

  • Transactions: Financial events, such as income, expenses, or transfers between accounts, are recorded as transactions.
  • Accounts: Transactions involve one or more accounts, such as assets, liabilities, income, or expenses.
  • Double-entry bookkeeping: Beancount enforces double-entry bookkeeping, ensuring that every transaction has balanced debits and credits.
  • Directives: Beancount uses a set of directives to define transactions, account openings, and other financial events.

Getting Started with Beancount

To start using Beancount, follow these simple steps:

  • Install Beancount: Install Beancount on your system using the provided installation instructions for your operating system.
  • Create your Beancount file: Create a new plain text file with the .beancount extension (e.g., my_finances.beancount).
  • Define your accounts: Use the "open" directive to define the accounts you'll use in your transactions.
  • Record transactions: Use the "txn" directive to record your financial transactions.

Or simply sign up at https://beancount.io. Here are some plain text accounting examples -

Example 1: Basic Transaction

2023-04-01 open Assets:Checking
2023-04-01 open Expenses:Groceries

2023-04-10 txn "Grocery Store" "Buying groceries"
Assets:Checking -50.00 USD
Expenses:Groceries 50.00 USD

In this example, we open two accounts, Assets:Checking and Expenses:Groceries. On April 10, 2023, we record a transaction for buying groceries worth $50. The transaction reduces the balance of Assets:Checking by $50 (debit) and increases the balance of Expenses:Groceries by $50 (credit).

Example 2: Income and Expense Transaction

2023-04-01 open Assets:Checking
2023-04-01 open Income:Salary
2023-04-01 open Expenses:Rent

2023-04-05 txn "Employer" "Salary payment"
Assets:Checking 2000.00 USD
Income:Salary -2000.00 USD

2023-04-06 txn "Landlord" "Monthly rent payment"
Assets:Checking -1000.00 USD
Expenses:Rent 1000.00 USD

In this example, we open three accounts: Assets:Checking, Income:Salary, and Expenses:Rent. On April 5, 2023, we record a salary payment transaction of $2000. The transaction increases the balance of Assets:Checking by $2000 (credit) and decreases the balance of Income:Salary by $2000 (debit). On April 6, 2023, we record a rent payment transaction of $1000. The transaction reduces the balance of Assets:Checking by $1000 (debit) and increases the balance of Expenses:Rent by $1000 (credit).

Example 3: Transfer Between Accounts

2023-04-01 open Assets:Checking
2023-04-01 open Assets:Savings

2023-04-15 txn "Bank" "Transfer from Checking to Savings"
Assets:Checking -500.00 USD
Assets:Savings 500.00 USD

In this example, we open two accounts: Assets:Checking and Assets:Savings. On April 15, 2023, we record a transaction to transfer $500 from the checking account to the savings account. The transaction reduces the balance of Assets:Checking by $500 (debit) and increases the balance of Assets:Savings by $500 (credit).

These examples illustrate the basic concepts of Beancount's double-entry bookkeeping system. By properly recording transactions, users can maintain accurate records of their financial activities and generate reports to gain insights into their financial situation.

Generating Reports and Analyzing Data

Beancount comes with a set of powerful tools for generating financial reports, including balance sheets, income statements, and more. You can also use Fava, a web-based user interface for Beancount, to visualize and interact with your financial data. https://beancount.io is built upon Fava with MIT license.

Conclusion

Embrace the power and simplicity of plain text accounting with Beancount. By understanding its core concepts and following the steps outlined in this guide, you'll be well on your way to managing your personal or small business finances with ease and precision. As you grow more comfortable with Beancount, you can explore advanced features and customizations to tailor the system to your unique needs.

Whether you're looking to track your spending, plan for the future, or gain insights into your financial habits, Beancount offers the flexibility and transparency needed to achieve your goals. With its user-friendly approach, Beancount has the potential to revolutionize the way you manage your finances and empower you to take control of your financial future.

Now that you have a solid foundation in Beancount, it's time to embark on your plain text accounting journey. Say goodbye to cumbersome spreadsheets and convoluted software, and welcome the world of Beancount. Happy accounting!

Introduction to Beancount.io

· 5 min read
Mike Thrift
Mike Thrift
Marketing Manager

Why Modern Bookkeeping Matters

Still managing your investments with spreadsheets? While spreadsheets are versatile, they can become cumbersome and error-prone as your investment portfolio grows. Enter Beancount.io – a sophisticated yet user-friendly investment tracking platform designed specifically for managing stock and cryptocurrency portfolios. Built with engineers and financial minimalists in mind, Beancount.io combines powerful features with an intuitive interface to streamline your investment tracking experience.

2019-09-07-introduction-to-beancount

Expenses

Income Statement

Balance Sheet

Double-entry Bookkeeping: The Foundation of Accuracy

Beancount.io is built on the principles of double-entry accounting – a time-tested methodology used by financial institutions worldwide. This system ensures mathematical accuracy through a simple yet powerful concept: every financial transaction must balance perfectly.

In double-entry bookkeeping, each transaction requires at least two entries – a debit (+) and a credit (-) – across different accounts. This built-in verification system makes it virtually impossible to record unbalanced transactions, ensuring your financial records remain accurate and reliable.

1970-01-01 open Income:BeancountCorp
1970-01-01 open Assets:Cash
1970-01-01 open Expenses:Food
1970-01-01 open Assets:Receivables:Alice
1970-01-01 open Assets:Receivables:Bob
1970-01-01 open Assets:Receivables:Charlie
1970-01-01 open Liabilities:CreditCard

2019-05-31 * "BeancountCorp" "Salary of May 15th to May 31st"
Income:BeancountCorp -888 USD
Assets:Cash 888 USD

2019-07-12 * "Popeyes chicken sandwiches" "dinner with Alice, Bob, and Charlie"
Expenses:Food 20 USD
Assets:Receivables:Alice 20 USD
Assets:Receivables:Bob 20 USD
Assets:Receivables:Charlie 20 USD
Liabilities:CreditCard -80 USD

As you can see in the two examples above, every transaction must fulfill the accounting equation.

Assets = Liabilities + Equity(aka Net Assets)

We used the Beancount syntax by Martin Blais and the web project Fava by Jakob Schnitzer to build this website. And it will alert you if any transaction has any legs not summing to zero.

Error Alert

Now you understand how we enforce the correctness of the ledger. But you may ask what are those "accounts"?

Understanding Accounts: The Water Bucket Analogy

Think of your financial accounts as a system of interconnected water buckets, where money flows like water between them. This analogy makes double-entry bookkeeping intuitive: when you transfer money from one account to another, it's like pouring water from one bucket to another – the total amount of water (money) in the system remains constant.

Beancount.io introduces five kinds of accounts.

  1. Income — Its amount is always negative or in debit. This is because you are making money, and then the money is debiting from "Income" account and crediting to your "Assets."
  2. Expenses — Its amount is always positive or in credit. This is because you are spending money, and the money is flowing from the "Assets" or "Liabilities" to the "Expenses."
  3. Liabilities — Its amount is positive or zero. Your credit card liabilities are a good example, which rises and falls in cycles.
  4. Assets — Its amount is positive or zero. Your cash or houses are always worth some prices.
  5. Equity — Your net assets. The system will calculate automatically for you. Equity = Assets - Liabilities and it reflects how wealthy you are.

Now you can open your customized accounts with those keywords above:

1970-01-01 open Assets:Cash
1970-01-01 open Assets:Stock:Robinhood
1970-01-01 open Assets:Crypto:Coinbase
1970-01-01 open Expenses:Transportation:Taxi
1970-01-01 open Equity:OpeningBalance

Advanced Investment Tracking with Commodities

Beancount.io excels at tracking diverse investments, from stocks to cryptocurrencies. Let's explore how it handles complex investment scenarios. For example, here's how you would record purchasing 10 Bitcoins at $100 each in 2014:

2014-08-08 * "Buy 10 Bitcoin"
Assets:Trade:Cash -1000.00 USD
Assets:Trade:Positions 10 BTC {100.00 USD}

And then three years later, you sell them (originally with costs of $100 per unit annotated with {100.00 USD}) at the price of $10,000 per unit annotated with @ 10,000.00 USD.

2017-12-12 * "Sell 2 Bitcoin"
Assets:Trade:Positions -2 BTC {100.00 USD} @ 10,000.00 USD
Assets:Trade:Cash 20,000.00 USD
Income:Trade:PnL -19,800.00 USD

Or the same transaction with @@ 20,000.00 USD means that at the price of $20,000 in total.

2017-12-12 * "Sell 2 Bitcoin"
Assets:Trade:Positions -2 BTC {100.00 USD} @@ 20,000.00 USD
Assets:Trade:Cash 20,000.00 USD
Income:Trade:PnL -19,800.00 USD

The sum of all legs of the transaction, including -2 BTC {100.00 USD}, are still, as always, zero.

The costs {100.00 USD} tag is important because you might have bought the same commodity at different costs.

100 BTC {10.00 USD, 2012-08-08}
10 BTC {100.00 USD, 2014-08-08}

If you want to simplify the process, you can set up the account at the beginning with FIFO or LIFO. FIFO stands for first in, first out, while LIFO stands for last in, first out. In the US, IRS uses FIFO to calculate your PnL and tax accordingly.

1970-01-01 open Assets:Trade:Positions "FIFO"

And then when you sell it in shorthand like -2 BTC {}, beancount will apply FIFO strategy automatically and sell the oldest commodity.

Getting Started with Beancount.io

Beancount.io is a modern cloud-based financial management platform that transforms your text-based transaction records into comprehensive financial statements, including income statements, balance sheets, and trial balances. By combining the reliability of plain text files with powerful visualization tools, Beancount.io helps you maintain precise control over your financial life while gaining valuable insights into your investment performance.

Start your financial journey with Beancount.io - Free during our promotional period!