Architecture & Queries
This plugin is powered by bean-query, the Beancount Query Language (BQL) engine. Every piece of data you see in the dashboard comes from direct BQL queries against your Beancount files.
This page documents the exact queries used throughout the plugin, so you can understand, modify, or replicate them in your own workflows.
🏗️ Architecture Overview
How it works:
- Plugin reads your
.beancountfiles - Executes BQL queries via
bean-querycommand-line tool - Parses CSV results
- Renders data in dashboard or note views
Key principle: All data retrieval happens through BQL - there's no proprietary API or database. You can run any of these queries manually in your terminal.
📊 Overview Tab Queries
Net Worth Components
Total Assets:
SELECT convert(sum(position), 'USD') WHERE account ~ '^Assets'
Total Liabilities:
SELECT convert(sum(position), 'USD') WHERE account ~ '^Liabilities'
Note: Net Worth = Assets - |Liabilities|
Monthly Income & Expenses
Current Month Income:
SELECT convert(sum(position), 'USD') WHERE account ~ '^Income' AND date >= 2026-02-01 AND date <= 2026-02-28
Current Month Expenses:
SELECT convert(sum(position), 'USD') WHERE account ~ '^Expenses' AND date >= 2026-02-01 AND date <= 2026-02-28
Dates are dynamically calculated based on current month
Historical Net Worth Chart
Net Worth Over Time:
SELECT year, month, only('USD', convert(last(balance), 'USD', last(date))) WHERE account ~ '^(Assets|Liabilities)' ORDER BY year, month
This query:
- Groups data by year and month
- Gets the last balance for each month
- Converts to your operating currency
- Includes both Assets and Liabilities for net worth calculation
💰 Transactions Tab Queries
Transaction List with Filters
Base Query (all transactions):
SELECT date, payee, narration, position, balance ORDER BY date DESC, lineno DESC LIMIT 1000
With Account Filter:
SELECT date, payee, narration, position, balance WHERE account ~ '^Assets:Checking' ORDER BY date DESC, lineno DESC LIMIT 1000
With Date Range:
SELECT date, payee, narration, position, balance WHERE date >= 2026-01-01 AND date <= 2026-12-31 ORDER BY date DESC, lineno DESC LIMIT 1000
With Payee Filter:
SELECT date, payee, narration, position, balance WHERE payee ~ 'Amazon' ORDER BY date DESC, lineno DESC LIMIT 1000
With Tag Filter:
SELECT date, payee, narration, position, balance WHERE 'vacation' IN tags ORDER BY date DESC, lineno DESC LIMIT 1000
Combined Filters:
Multiple conditions are joined with AND:
SELECT date, payee, narration, position, balance WHERE account ~ '^Expenses:Food' AND date >= 2026-01-01 AND date <= 2026-01-31 ORDER BY date DESC, lineno DESC LIMIT 1000
📋 Journal Tab Queries
The Journal tab combines three types of entries:
Transaction Entries
SELECT id, date, flag, payee, narration, tags, links, filename, lineno, account, number, currency, cost_number, cost_currency, cost_date, price, entry.meta as entry_meta FROM postings WHERE <filters> ORDER BY date DESC, id, account
This query:
- Retrieves all postings from the
postingstable - Groups by transaction ID client-side
- Includes metadata and file location for editing
Balance Assertions
SELECT date, account, amount, tolerance, discrepancy FROM #balances WHERE <filters> ORDER BY date DESC, account
Note Entries
SELECT date, account, comment, tags, links, meta FROM #notes WHERE <filters> ORDER BY date DESC, account
🏦 Balance Sheet Tab Queries
Market Value (Default)
SELECT account, convert(sum(position), 'USD') WHERE account ~ '^(Assets|Liabilities|Equity)' AND NOT close_date(account) GROUP BY account ORDER BY account
This converts all holdings to your operating currency at current market prices.
Historical Cost
SELECT account, cost(sum(position)) WHERE account ~ '^(Assets|Liabilities|Equity)' AND NOT close_date(account) GROUP BY account ORDER BY account
Shows original purchase prices - useful for tax calculations.
Units (Raw Holdings)
SELECT account, units(sum(position)) WHERE account ~ '^(Assets|Liabilities|Equity)' AND NOT close_date(account) GROUP BY account ORDER BY account
Shows actual quantities held (e.g., "50 AAPL", "1.5 BTC").
🪙 Commodities Tab Queries
List All Commodities
SELECT name AS name_ FROM #commodities GROUP BY name
Commodity Price Data
SELECT last(date) AS date_, last(currency) AS currency_, round(getprice(last(currency), 'USD'),2) AS price_, currency_meta(last(currency), 'logo') AS logo_, bool(today()-1<last(date)) AS islatest_ FROM #prices GROUP BY currency
This query:
- Gets the most recent price for each commodity
- Converts to operating currency
- Retrieves logo metadata
- Flags prices updated within last day as "latest"
Commodity Details
SELECT name AS name_, last(meta) AS meta_, currency_meta(last(name),'logo') AS logo_, currency_meta(last(name), 'price') AS pricemetadata_, meta('filename') AS filename_, meta('lineno') AS lineno_ FROM #commodities WHERE name='AAPL'
Retrieves full metadata including:
- Logo URL
- Price source (e.g., "yahoo/AAPL")
- File location for editing
🔍 Helper Queries
Get All Open Accounts
SELECT account
Post-processed to get unique list of open accounts
Get All Unique Tags
SELECT tags
Post-processed to extract unique tags from all transactions
File Validation
SELECT TRUE LIMIT 0
This validates Beancount file syntax without returning data - used by the connection test.
🛠️ Using These Queries
In Terminal
Run any query manually:
bean-query /path/to/your.beancount "SELECT account, sum(position) WHERE account ~ '^Assets' GROUP BY account"
In Your Notes
Use BQL code blocks:
SELECT account, sum(position) WHERE account ~ '^Assets' GROUP BY account
Inline in Text
Embed live values:
My current net worth: `bql:SELECT convert(sum(position), 'USD') WHERE account ~ '^(Assets|Liabilities)'`
📝 Query Syntax Notes
Important: All queries must be written on a single line in code blocks. Multi-line queries will only execute the first line.
Currency Placeholders: In the queries above, 'USD' is used as an example. The plugin substitutes your configured operating currency from settings.
Date Formats: Dates in BQL use YYYY-MM-DD format without quotes (e.g., date >= 2026-01-01)
Regular Expressions: The ~ operator performs regex matching:
account ~ '^Assets'- matches accounts starting with "Assets"payee ~ 'Amazon'- matches payees containing "Amazon"
🔗 Learn More
- Official BQL Documentation: Beancount Query Language
- Query Examples: See our BQL Queries page for more examples
- Source Code: All query definitions are in
src/queries/index.ts