A blazing-fast Rust implementation of Beancount
Parse and validate your ledger faster than Python beancount.
| 10-30x faster | Parse and validate large ledgers in milliseconds (see benchmarks) |
| No dependencies | No Python runtime, no libraries to install |
| Drop-in replacement | Compatible bean-* CLI commands for easy migration |
| Full compatibility | Parses any valid beancount file |
| Editor support | LSP server for VS Code, Neovim, Helix, and more |
| AI-ready | MCP server for Claude, Cursor, and other AI assistants |
| Runs anywhere | WebAssembly support for browser and Node.js |
| Better errors | Detailed error messages with source locations |
| 20 built-in plugins | Plus Python plugin compatibility via WASI sandbox |
| Platform | Command |
|---|---|
| macOS | brew install rustledger/rustledger/rustledger |
| Windows | scoop bucket add rustledger https://github.com/rustledger/scoop-rustledger && scoop install rustledger |
| Cargo | cargo binstall rustledger or cargo install rustledger |
| Fedora/RHEL | sudo dnf copr enable robcohen/rustledger && sudo dnf install rustledger |
| Nix | nix run github:rustledger/rustledger |
| Docker | docker run --rm -v "$PWD:/data" ghcr.io/rustledger/rustledger /data/ledger.beancount |
| Binaries | GitHub Releases |
| npm (WASM) | npm install @rustledger/wasm |
| npm (MCP) | npx @rustledger/mcp-server (Model Context Protocol server) |
Missing your platform? Open an issue to request it.
rledger check ledger.beancount
rledger query ledger.beancount "SELECT account, SUM(position) GROUP BY account"| Command | Description |
|---|---|
rledger check |
Validate ledger files with detailed error messages |
rledger query |
Run BQL queries (interactive shell or one-shot) |
rledger format |
Auto-format beancount files |
rledger report |
Generate balance, account, and statistics reports |
rledger doctor |
Debugging tools for ledger issues |
rledger extract |
Import transactions from CSV/OFX bank statements |
rledger price |
Fetch commodity prices from online sources |
Python beancount users can also use bean-check, bean-query, etc.
CLI examples
# Validate with plugins
rledger check --native-plugin auto_accounts ledger.beancount
# Interactive query shell
rledger query ledger.beancount
# One-shot query
rledger query ledger.beancount "SELECT date, narration WHERE account ~ 'Expenses:Food'"
# Reports
rledger report ledger.beancount balances
rledger report ledger.beancount stats
# Format in place
rledger format --in-place ledger.beancount| Crate | Description |
|---|---|
rustledger |
CLI tool (rledger check, rledger query, etc.) |
rustledger-core |
Core types: Amount, Position, Inventory |
rustledger-parser |
Lexer and parser with error recovery |
rustledger-loader |
File loading and includes |
rustledger-booking |
Interpolation and 7 booking methods |
rustledger-validate |
27 validation error codes |
rustledger-query |
BQL query engine |
rustledger-plugin |
20 built-in plugins + Python plugin support |
rustledger-importer |
CSV/OFX import framework |
rustledger-lsp |
Language Server Protocol for editor integration |
rustledger-wasm |
WebAssembly bindings for JavaScript/TypeScript |
Booking methods (7)
| Method | Description |
|---|---|
STRICT |
Lots must match exactly (default) |
STRICT_WITH_SIZE |
Exact-size matches accept oldest lot |
FIFO |
First in, first out |
LIFO |
Last in, first out |
HIFO |
Highest cost first |
AVERAGE |
Average cost basis |
NONE |
No cost tracking |
Built-in plugins (20)
| Plugin | Description |
|---|---|
auto_accounts |
Auto-generate Open directives |
auto_tag |
Automatically tag transactions |
check_average_cost |
Validate average cost bookings |
check_closing |
Zero balance assertion on account close |
check_commodity |
Validate commodity declarations |
check_drained |
Ensure accounts are drained before close |
close_tree |
Close descendant accounts |
coherent_cost |
Enforce cost OR price (not both) |
commodity_attr |
Validate commodity attributes |
currency_accounts |
Enforce currency constraints on accounts |
document_discovery |
Auto-discover document files |
implicit_prices |
Generate price entries from transaction costs |
leafonly |
Error on postings to non-leaf accounts |
noduplicates |
Hash-based duplicate transaction detection |
nounused |
Warn on unused accounts |
onecommodity |
Single commodity per account |
pedantic |
Enable all strict validations |
sellgains |
Cross-check capital gains against sales |
unique_prices |
One price per day per commodity pair |
unrealized |
Calculate unrealized gains |
Python plugins: Run existing Python beancount plugins via CPython-WASI sandbox.
Benchmarks run nightly on 10K transaction ledgers. View workflow →
Benchmark details
What's measured:
- Validation: Parse ledger + validate (balance assertions, account opens, etc.)
- Balance Report: Parse + compute all account balances
Memory efficiency: rustledger typically uses 3-5x less memory than Python beancount thanks to Rust's zero-cost abstractions and efficient data structures.
Run locally:
# Quick comparison (requires nix)
nix develop .#bench
./scripts/bench.sh
# Criterion micro-benchmarks
cargo bench -p rustledger-core
cargo bench -p rustledger-parserSee BENCHMARKING.md for detailed benchmark documentation.
See CLAUDE.md for architecture and development setup.
By submitting a pull request, you agree to the Contributor License Agreement.
Commercial licensing available - contact us for proprietary license options.
rustledger is free and open source. If you find it useful, consider supporting development: