Skip to main content

UI Features

Explore the main features of the beancount.io web interface for editing, querying, uploading documents, and customizing your Beancount workflow.

Use the editor, transaction form and query reports to work with your ledger. The executable recipes below target stock Fava 1.30.16 with Beancount 3.2.3 and beanquery 0.2.0; follow the pinned local setup.

Beancount.io uses a separate dashboard. Its product source confirms ledger routes for editing, querying, documents and Settings, plus consumers for several Fava display options. That does not make stock Fava's keyboard shortcuts, insertion rules, plugin execution or URL paths a hosted compatibility promise. The image below shows the hosted dashboard, not the stock UI.

beancount.io ledger dashboard showing a net worth trend chart, account balances, and an AI assistant bar

Explore the live ledger →

1. Editing and Data Entry

The Built-in Editor

Stock Fava's editor offers completion for accounts, payees and tags. Use default-file to choose its initial source file. insert-entry also positions the cursor at the latest insertion marker in that file; it is not a core Beancount option.

2000-01-01 custom "fava-option" "default-file"
2024-01-01 custom "fava-option" "insert-entry" "^Expenses:Food$"

This fragment selects its containing file. New entries after January 1, 2024 that match Expenses:Food are inserted before the marker unless a later eligible rule or a later posting's account takes precedence. See the complete multi-file insertion example.

Adding Transactions

In stock Fava, click + or press n to open the transaction form. The narration field accepts space-separated tags and links, such as Lunch #food ^receipt-001. Account names must already have open directives.

Save this complete ledger as ui-demo.beancount to try the reports below. The positive expense is a debit; the negative cash posting is its credit.

option "title" "UI Demo"
option "operating_currency" "USD"
2024-01-01 open Assets:Checking USD
  fava-uptodate-indication: TRUE
2024-01-01 open Income:Salary USD
2024-01-01 open Expenses:Food USD
 
2024-01-02 * "Salary"
  Assets:Checking    3000.00 USD
  Income:Salary     -3000.00 USD
 
2024-01-03 * "Groceries" #food
  Expenses:Food       400.00 USD
  Assets:Checking    -400.00 USD
 
2024-01-04 balance Assets:Checking 2600.00 USD

Run bea --file ui-demo.beancount check, then fava ui-demo.beancount. The check passes and checking holds 2,600.00 USD. A future-dated transaction with #template is still a real transaction: that tag does not make it an inert reusable form template. Keep hypothetical transactions in a separate scenario ledger.

2. Document Management

Stock Fava can upload documents by dropping them on account names or journal rows. Configure a real document root and keep its account hierarchy consistent with your open accounts.

This optional fragment can be added to ui-demo.beancount. First create a documents directory alongside the ledger. To try discovery, place a real file named 2024-01-03-receipt.pdf inside documents/Expenses/Food/.

option "documents" "documents"
plugin "fava.plugins.link_documents"
plugin "fava.plugins.tag_discovered_documents"

These are real modules shipped in Fava 1.30.16. Beancount discovers dated files in account directories; tag_discovered_documents adds #discovered. link_documents matches document metadata to document entries and links them. It does not infer a transaction association from a receipt's contents. Add this metadata directly under the existing Groceries header, before its postings:

  document: "2024-01-03-receipt.pdf"

That indented line is a metadata fragment, not a standalone ledger. With the file present, the document receives #linked and shares ^dok-2024-01-03 with the transaction. Missing matching documents produce an error. For the exact stock behavior, see the versioned document-linking plugin.

3. Querying and Analysis with BQL

Stock Fava's Query page runs Beancount Query Language. Clear global time/account filters before reproducing these full-ledger results. Those UI filters can remove entries before a query runs.

Results can be downloaded as CSV. Chart support depends on the result types: the stock help describes exactly two columns, with a date or string followed by an inventory. An arbitrary pair of numeric columns does not guarantee a chart.

Practical Query Examples

Run these queries against ui-demo.beancount in Fava's Query page or pass each quoted query to bea --file ui-demo.beancount query "…".

Monthly expense summary:

SELECT account, SUM(position) AS total
FROM postings
WHERE account ~ '^Expenses:'
  AND date >= 2024-01-01 AND date < 2024-02-01
GROUP BY account
ORDER BY account;

Expected result: Expenses:Food, 400.00 USD.

Income vs. expenses by month:

SELECT YEAR(date) AS year, MONTH(date) AS month,
       ROOT(account, 1) AS category, currency,
       SUM(number) AS signed_total
FROM postings
WHERE account ~ '^(Income|Expenses):'
GROUP BY year, month, category, currency
ORDER BY year, month, category, currency;
YearMonthCategoryCurrencySigned total
20241ExpensesUSD400.00
20241IncomeUSD-3000.00

The query preserves Beancount's signs and groups units separately by currency. Income of 3,000.00 USD less expenses of 400.00 USD leaves 2,600.00 USD. It is a units report, not a conversion or cost-basis report. IIF is unavailable on beanquery 0.2.0, and unary -position is unsupported; grouping the two account categories avoids both operations.

4. Customization and Workflow

Customizing the View

Add these Fava directives to the example ledger to hide zero-balance accounts and collapse investment branches:

2000-01-01 custom "fava-option" "show-closed-accounts" "false"
2000-01-01 custom "fava-option" "show-accounts-with-zero-balance" "false"
2000-01-01 custom "fava-option" "collapse-pattern" "^Assets:Investments"

They affect report account trees. Accounts with non-zero balances remain visible. Core forms such as option "show-closed-accounts" "false" fail Beancount validation.

The sample's fava-uptodate-indication: TRUE metadata is on its own indented line under open. Do not put it on the open line or quote the boolean. A latest passing balance check produces green; a failing check produces red; a subsequent transaction produces yellow. The January 4 assertion is green. A separate grey freshness indicator can also appear because these dates are old.

For the stock example titled UI Demo, these complete paths lead to its reports:

2024-01-01 custom "fava-sidebar-link" "January Expenses" "/ui-demo/income_statement/?time=2024-01"
2024-01-01 custom "fava-sidebar-link" "All Documents" "/ui-demo/documents/"

These paths assume stock Fava is mounted at the host root. Replace /ui-demo with your actual ledger slug and include any server mount prefix. See custom sidebar links for tested /jump behavior and the hosted routing boundary.

General Configuration

Starting stock Fava with multiple main files creates separate ledgers in its ledger switcher. Files brought in through include remain part of one ledger and appear as editable sources; they are not separate books.

Use Fava options for language, default-file and use-external-editor. An external editor needs a beancount:// handler and access to the source files. Real stock extension modules also include fava.ext.auto_commit and fava.ext.portfolio_list. Extensions use custom "fava-extension" with their own prerequisites; they are distinct from the plugin directives used above. See Fava's versioned extension help.

5. Performance and Troubleshooting

Handling Large Files

Use includes to organize a ledger by account or period. Beancount still loads the included files, so splitting one book does not itself reduce the report's input. Limit displayed dates and simplify expensive queries when you need a smaller report.

Common Issues and Fixes

  • Ledger errors: Run bea check and inspect Fava's Errors report. A page can render while the loader has errors.
  • Unexpected option behavior: Check the tested runtime and use dated Fava custom directives. bea check cannot detect an unknown Fava option by itself.
  • Unexpected query totals: Clear global filters, include opening history and keep currencies separate.
  • Missing documents: Check the directory exists, the account is open, the filename starts with a valid date and the transaction's metadata matches the document.

For contrast, these are intentional invalid examples. They must not be copied into a working ledger:

option "insert-entry" "Expenses:Food"
custom "fava-sidebar-link" "Label" "/jump?time=month"

The first uses an unknown core option. The second omits the required date. The stock features reference describes the UI behavior for this release.

Source: https://beancount.io/docs/Tips/ui-features