Beanie Budgets

Supported syntax

A working example of each piece of beancount that Beanie Budgets understands. Every one on this page was run through bean-check under beancount 2.3.6 and 3.2.3 before the page was built, so you can paste any of them into a ledger and they will load.

Reads and writes means the app both understands it and can produce it. Reads and keeps means the app understands it, values it, and leaves it exactly as you wrote it, but will not create one for you. Neither ever changes what is already in your files beyond the entry you are editing.

This is a reference for what the app supports, not a beancount tutorial. For the format itself, the official documentation is the place to start, and the compatibility table lists every construct in addition to the ones with an example here.

These examples in one file: example-ledger.bean. Save it into an empty folder and open that folder, in Beanie Budgets or in anything else that reads beancount.

Found something we missed? We have worked hard to cover beancount's syntax, checking the app against real beancount across thousands of generated ledgers and against grammars and specifications written by other people. However, Beancount is a big language and this is a new app so we probably still have gaps. If you find that a line of your ledger loads in bean-check but not in Beanie Budgets we would like to know about it. The app lists any lines it can't read under Settings, each with a code, please send these errors to us.

Opening Accounts

Every account has to be opened before anything can be posted to it. The app writes these for you when you add an account, and reads whatever is already in your file.

Reads and writes

Opening an account

A date, the word open, and the account. Naming a currency after it keeps the account to that one, and beancount will refuse a posting in anything else.

2026-01-01 open Assets:Bank:Current  GBP
2026-01-01 open Expenses:Food:Groceries  GBP
Reads and writes

An account that can hold anything

Leave the currency off and the account will take whatever you post to it. Useful for an expense account you might one day spend abroad from.

2026-01-01 open Expenses:Travel
Reads and writes

An account in more than one currency

List them separated by commas. A travel account holding both pounds and euros is the typical reason to want this.

2026-01-01 open Assets:Bank:Travel  GBP,EUR

2026-05-04 * "Bureau de change" "Euros for the trip"
  Assets:Bank:Travel     400.00 EUR
  Equity:Opening-Balances

Beancount holds you to the list of currencies: a posting in a currency you did not name is refused.

Reads and keeps

How shares should be sold

An investment account can say which lot a sale takes: FIFO, LIFO, HIFO, AVERAGE, STRICT or NONE. The text in quotes stands for, in order, oldest first, newest first, dearest first, a blended average, naming the lot yourself, and no matching at all.

2026-01-01 open Assets:Brokerage:VWRL  VWRL  "FIFO"
2026-01-01 open Assets:Brokerage:VUSA  VUSA  "LIFO"

Warning! If you don't use quotes, beancount reads it as the name of a commodity the account may hold, not as a booking method: open Assets:Brokerage FIFO passes bean-check and declares an account holding a commodity called FIFO. Beanie Budgets reads it the same way beancount does.

Reads and keeps

Details against an account

Indented key: value lines under an open hold whatever you want to remember about the account.

2026-01-01 open Assets:Bank:Savings  GBP
  institution: "Nationwide"
  sort-code: "07-01-16"

Kept exactly as you wrote them, including through an account rename. The app does not add them itself.

Reads and keeps

Closing an account

When an account is finished with, close records the date. Beancount then refuses anything posted to it afterwards, which is a useful check against a stray entry.

2020-01-01 open  Assets:Bank:Old-Savings  GBP
2026-02-28 close Assets:Bank:Old-Savings

Read and kept, and rewritten correctly if you rename the account. Beanie Budgets does not yet hide the account in the app.

Reads and writes

What an account name may contain

The first part has to be one of beancount's five roots: Assets, Liabilities, Equity, Income or Expenses. Every part after it may start with a capital or a digit, and may contain hyphens, so a pension scheme or a tax year works as a name.

2026-01-01 open Assets:Retirement:401K:Cash
2026-01-01 open Expenses:Taxes:2026:Payments-On-Account
2026-01-01 open Liabilities:Non-current:Mortgage

Basic Transactions

The shape almost every line in a ledger takes: a date, who it was with, and where the money went. Everything here is read and written by the app unless a note says otherwise.

Reads and writes

A transaction

A date, a flag, who you paid, what it was for, and the two sides of the money. The * means settled; every posting is an account and an amount.

2026-03-14 * "Sainsbury's" "Weekly shop"
  Expenses:Food:Groceries      42.18 GBP
  Assets:Bank:Current         -42.18 GBP
Reads and writes

Letting beancount work out the other side

Leave the last amount off and it is whatever balances the transaction. Handy, and worth keeping for the side you care least about: an inferred posting can never be wrong, because it is defined as whatever makes the books balance.

2026-03-02 * "Octopus Energy" "February electricity"
  Expenses:Home:Electricity    88.40 GBP
  Assets:Bank:Current
Reads and writes

Splitting one payment

A transaction can have as many postings as you like, so one card payment can be broken into what it was actually spent on.

2026-03-19 * "Tesco" "Shop and a new kettle"
  Expenses:Food:Groceries      31.05 GBP
  Expenses:Home:Supplies       24.00 GBP
  Liabilities:Card:Visa       -55.05 GBP
Reads and writes

Marking a transaction as not settled yet

A ! in place of the * marks a transaction you are not sure about, so you can come back to it. Beancount reads it the same way; the flag is just a note to yourself.

2026-03-21 ! "Uber" "Airport, receipt to check"
  Expenses:Travel:Taxi         64.00 GBP
  Assets:Bank:Current         -64.00 GBP
Reads and writes

Tags and links

A #tag groups transactions by theme, and a ^link ties together the several entries that make up one event, such as a trip paid for in instalments.

2026-04-02 * "easyJet" "Flights out" #holiday-2026 ^lisbon-trip
  Expenses:Travel:Flights     218.60 GBP
  Assets:Bank:Current        -218.60 GBP
Reads and writes

Notes against a transaction or a posting

Any key: value line adds your own detail. Indented under the header it belongs to the whole transaction; indented under a posting it belongs to that posting alone.

2026-03-28 * "Ace Plumbing" "Boiler service"
  invoice: "INV-2291"
  Expenses:Home:Repairs       145.00 GBP
    warranty-until: 2027-03-28
  Assets:Bank:Current        -145.00 GBP
Reads and writes

Comments

Anything after a semicolon is ignored, on its own line or at the end of one. Useful for explaining a transaction to yourself, and kept exactly where you put it.

; Christmas presents, split with my sister
2026-12-03 * "John Lewis" "Present for Mum"
  Expenses:Gifts               60.00 GBP  ; her half comes back in January
  Assets:Bank:Current         -60.00 GBP
Reads and keeps

Sums and separators in an amount

An amount can be written as a calculation, and long numbers can carry thousands separators. Both are read and kept exactly as you wrote them.

2026-03-01 * "Landlord" "March rent"
  Expenses:Home:Rent         1,250.00 GBP
  Assets:Bank:Current       -1,250.00 GBP

2026-03-08 * "Dishoom" "Dinner, split four ways"
  Expenses:Food:Restaurant    112.00 / 4 GBP
  Assets:Bank:Current

The app keeps these as written for as long as the amount is unchanged. Entries it writes itself use plain numbers.

Advanced Transactions

Buying and selling something whose price moves. These are the lines the app reads and values but will not write for you.

Reads and keeps

Buying shares at a cost

Braces hold what each unit cost. The account then holds ten units of VWRL rather than a sum of money, and the app values them at whatever your latest price says.

2026-01-15 * "Vanguard" "Buy VWRL"
  Assets:Brokerage:VWRL       10 VWRL {90.00 GBP}
  Assets:Brokerage:Cash     -900.00 GBP
Reads and keeps

One cost for the whole lot

Double braces mean the figure covers the posting rather than each unit, which is how a dividend reinvestment or a fractional purchase usually arrives from a broker. Beancount divides it across the units for you.

2026-02-10 * "Vanguard" "Reinvested dividend"
  Assets:Brokerage:VUSA      5.482 VUSA {{465.00 GBP}}
  Assets:Brokerage:Cash      -465.00 GBP
Reads and keeps

A price rather than a cost

An @ records what a unit changed hands for without giving the holding a cost basis. Beancount keeps the position as bare units, and so does the app: there is no gain to report because nothing says what was paid.

2026-01-20 * "Vanguard" "Buy VMID"
  Assets:Brokerage:VMID       40 VMID @ 30.50 GBP
  Assets:Brokerage:Cash    -1,220.00 GBP

Worth knowing because it surprises people: 40 VMID @ 30.50 GBP gives the account forty units and no cost basis. bean-query and Fava say the same, and the app matches them rather than inventing a basis from the price.

Reads and keeps

Selling, naming the lot

A sale repeats the cost it was bought at, gives the price it went for, and leaves the gain to be worked out. The bare Income posting picks up the difference.

2026-01-05 * "Vanguard" "Buy VFEM"
  Assets:Brokerage:VFEM       20 VFEM {48.00 GBP}
  Assets:Brokerage:Cash     -960.00 GBP

2026-06-12 * "Vanguard" "Sell half"
  Assets:Brokerage:VFEM      -10 VFEM {48.00 GBP} @ 55.00 GBP
  Assets:Brokerage:Cash      550.00 GBP
  Income:Investments:Gains
Reads and keeps

Choosing which lot by date

Where two lots cost the same, the date in the braces says which one is being sold. Useful when your broker's statement identifies a holding by when you bought it rather than by what you paid.

2026-01-08 * "Vanguard" "First VAGP purchase"
  Assets:Brokerage:VAGP       10 VAGP {25.00 GBP}
  Assets:Brokerage:Cash     -250.00 GBP

2026-04-08 * "Vanguard" "Second, at the same price"
  Assets:Brokerage:VAGP       10 VAGP {25.00 GBP}
  Assets:Brokerage:Cash     -250.00 GBP

2026-07-02 * "Vanguard" "Sell the April lot"
  Assets:Brokerage:VAGP      -10 VAGP {2026-04-08} @ 27.00 GBP
  Assets:Brokerage:Cash      270.00 GBP
  Income:Investments:Gains
Reads and keeps

Letting the account decide which lot

Empty braces say only that a lot is being reduced, and leaves the choice to the booking method on the account. This one is FIFO, so the oldest goes first.

2026-01-01 open Assets:Brokerage:VHYL  VHYL  "FIFO"

2026-02-02 * "Vanguard" "First VHYL purchase"
  Assets:Brokerage:VHYL       10 VHYL {50.00 GBP}
  Assets:Brokerage:Cash     -500.00 GBP

2026-05-02 * "Vanguard" "Second, dearer"
  Assets:Brokerage:VHYL       10 VHYL {60.00 GBP}
  Assets:Brokerage:Cash     -600.00 GBP

2026-08-02 * "Vanguard" "Sell ten, oldest first"
  Assets:Brokerage:VHYL      -10 VHYL {} @ 65.00 GBP
  Assets:Brokerage:Cash      650.00 GBP
  Income:Investments:Gains

The app reads the booking method and works the disposal out the same way beancount does. It will not add a booking method to an account for you.

Reads and keeps

Commission folded into the cost

A # inside the braces adds a dealing charge to the lot rather than expensing it separately. Beancount spreads it across the units, so these three cost 95.00 each plus 4.95 between them.

2026-03-03 * "Vanguard" "Buy VUKE with dealing charge"
  Assets:Brokerage:VUKE        3 VUKE {95.00 # 4.95 GBP}
  Assets:Brokerage:Cash     -289.95 GBP
Reads and keeps

What a holding is worth today

A price line records a quote on a date. This is what lets the app value a holding at anything other than what you paid for it, and what puts it into your net worth in your own currency.

2026-06-01 price VWRL  101.50 GBP
2026-07-01 price VWRL  104.25 GBP

Only a price line is used for valuing. The @ on the transaction that bought the holding is not.

Reads and keeps

Buying foreign currency

The rate goes on the posting as an @, which is what lets the two sides balance across currencies. The dollars then sit in the account as dollars.

2026-05-06 * "Wise" "Dollars for the trip"
  Assets:Bank:Dollars      1,000.00 USD @ 0.79 GBP
  Assets:Bank:Current       -790.00 GBP

To show those dollars in pounds the app needs a price USD 0.79 GBP line as well. Without one it shows what you hold in dollars rather than converting at a rate your file never states, which is what beancount does with the same file.

Assertions

Lines that check your ledger against reality rather than recording anything. This is what stops a mistake from six months ago quietly sitting in your balance, and the app writes these for you when you use Correct Balance.

Reads and writes

Checking a balance

A balance line says what an account should hold on a date. If it does not, beancount tells you, and so does the app.

2026-03-01 * "Opening"
  Assets:Bank:Joint      1,234.56 GBP
  Equity:Opening-Balances

2026-04-01 balance Assets:Bank:Joint   1,234.56 GBP

Checked at the start of its date, before anything else that day. So a statement balance on the 31st is asserted on the 1st of the following month.

Reads and writes

Allowing for a penny or two

Adding ~ and an amount accepts anything within that much, which is useful where a provider rounds differently from your ledger.

2026-03-01 * "Opening"
  Assets:Pension:Workplace      1,234.58 GBP
  Equity:Opening-Balances

2026-04-01 balance Assets:Pension:Workplace   1,234.56 ~ 0.05 GBP
Reads and writes

Making an account match a known figure

A pad before a balance inserts whatever entry is needed to make the assertion come out right. This is how an opening balance is normally written, and what the app's Correct Balance does.

2026-01-01 pad     Assets:Bank:Savings  Equity:Opening-Balances
2026-01-02 balance Assets:Bank:Savings  8,500.00 GBP

The padding entry is generated rather than written into your file, so changing the figure in the balance line changes what the pad contributes. The pad has to be dated strictly before the assertion.

Reads and writes

Checking a holding rather than a sum

An assertion works in whatever the account holds, so a share count can be checked against a broker statement without knowing what it was worth that day.

2026-01-15 * "Transfer in"
  Assets:Brokerage:VMIG       10 VMIG {90.00 GBP}
  Equity:Opening-Balances

2026-04-01 balance Assets:Brokerage:VMIG   10 VMIG

Organising a Ledger

Once a ledger has a few years in it, it stops being one file. These are the lines that hold it together and describe it.

Reads and writes

Splitting into several files

An include pulls another file in, so accounts, prices and each year's transactions can live apart. Paths are relative to the file doing the including.

; main.bean
include "accounts.bean"

2026-03-04 * "Co-op" "Shop"
  Expenses:Food:Groceries     18.40 GBP
  Assets:Bank:Current
Reads and writes

Including a whole folder

A wildcard saves listing every file by name, which is what you want once each year or each account type has its own.

include "accounts/*.bean"

2026-03-04 * "Co-op" "Shop"
  Expenses:Food:Groceries     18.40 GBP
  Assets:Bank:Current
Reads and writes

Telling beancount about the file

operating_currency is the one that matters most: it is the currency your totals are shown in, and the app reads it to know what your net worth should be counted in.

option "title" "Our household ledger"
option "operating_currency" "GBP"
Reads and keeps

Tagging a run of transactions

Everything between a pushtag and its poptag picks up the tag, which beats writing it on twenty entries from one holiday.

pushtag #lisbon-2026

2026-05-05 * "Hotel Lisboa" "Two nights"
  Expenses:Travel:Hotel      180.00 GBP
  Assets:Bank:Current

2026-05-06 * "Time Out Market" "Dinner"
  Expenses:Food:Restaurant    42.00 GBP
  Assets:Bank:Current

poptag #lisbon-2026

The pushed tag reaches every transaction inside and stops at the pop. The app shows those transactions tagged, and keeps the pushtag/poptag pair where you put it.

Reads and keeps

Describing a commodity

A commodity line gives a ticker a readable name, and any metadata you want alongside it.

2026-01-01 commodity VWRL
  name: "Vanguard FTSE All-World UCITS ETF"
  asset-class: "Equity"

The app reads asset-class and uses it for the Allocation report, so declaring it is worth the two lines.

Reads and writes

A note against an account

A dated note about an account.

2026-02-14 note Assets:Bank:Current "Rang them about the overdraft fee"

A document line works the same way for a file path, and is read and kept, though beancount refuses the file if the document is not actually there, so there is no example of one here.

Reads and writes

A budget

Fava's budget directive sets what you mean to spend on a category over a period. The app reads these and drives Budget Monitoring from them.

2026-01-01 custom "budget" Expenses:Food:Groceries "monthly"   400.00 GBP
2026-01-01 custom "budget" Expenses:Travel        "yearly"   2,000.00 GBP
Reads and writes

A transaction that repeats

A bracketed instruction at the end of the narration turns one entry into a series, so a rent payment or a subscription is written once. UNTIL a date, or REPEAT n TIMES.

2026-01-01 * "Landlord" "Rent [MONTHLY UNTIL 2027-01-01]"
  Expenses:Home:Rent       1,250.00 GBP
  Assets:Bank:Current

2026-01-05 # "Netflix" "Subscription [MONTHLY REPEAT 12 TIMES]"
  Expenses:Subscriptions      10.99 GBP
  Assets:Bank:Current

The occurrences are worked out as the file is read rather than written into it, so your file keeps the one entry. Either flag works, and # is the one Fava's own forecast plugin uses.