Include Directive¶
Overview¶
The include directive imports the contents of another file into the current ledger. This enables organizing large ledgers across multiple files.
Syntax¶
include = "include" WHITESPACE path
path = string
Components¶
Path¶
A string containing the file path to include: - Relative paths resolve from the including file's directory - Absolute paths are used as-is
Examples¶
Basic Include¶
; main.beancount
include "accounts.beancount"
include "2024/january.beancount"
include "2024/february.beancount"
Directory Structure¶
ledger/
├── main.beancount
├── accounts.beancount
├── commodities.beancount
├── 2024/
│ ├── q1.beancount
│ ├── q2.beancount
│ ├── q3.beancount
│ └── q4.beancount
└── config/
└── options.beancount
; main.beancount
include "config/options.beancount"
include "accounts.beancount"
include "commodities.beancount"
include "2024/q1.beancount"
include "2024/q2.beancount"
include "2024/q3.beancount"
include "2024/q4.beancount"
Nested Includes¶
; main.beancount
include "2024/all.beancount"
; 2024/all.beancount
include "q1.beancount"
include "q2.beancount"
include "q3.beancount"
include "q4.beancount"
Path Resolution¶
Relative Paths¶
Relative paths resolve from the including file's directory:
/home/user/finances/
├── main.beancount ; include "yearly/2024.beancount"
└── yearly/
└── 2024.beancount ; include "q1.beancount"
└── q1.beancount
In main.beancount:
include "yearly/2024.beancount" ; → /home/user/finances/yearly/2024.beancount
In yearly/2024.beancount:
include "q1.beancount" ; → /home/user/finances/yearly/q1.beancount
Absolute Paths¶
include "/shared/ledgers/common/accounts.beancount"
Path Normalization¶
Paths are normalized before resolution:
- ./file.beancount → file.beancount
- dir/../file.beancount → file.beancount
Include Behavior¶
Merging¶
Included files are merged into the main file:
- All directives are combined
- Directives are sorted chronologically
- Options from the main file take precedence
Processing Order¶
- Parse main file
- For each
include, recursively parse included file - Merge all directives
- Sort by date
- Apply plugins
Validation¶
The following conditions produce errors:
| Condition | Error Type |
|---|---|
| Include file not found | LoadError ("File glob ... does not match any files") |
| Circular include detected | LoadError |
File Not Found¶
LoadError: File glob "missing.beancount" does not match any files
Circular Include¶
error: Circular include detected
--> b.beancount:3:1
|
3 | include "a.beancount"
| ^^^^^^^^^^^^^^^^^^^^^ creates cycle
|
= cycle: a.beancount → b.beancount → a.beancount
Option Scoping¶
Options are scoped to the top-level file:
; main.beancount
option "title" "Main Ledger"
include "other.beancount"
; Title is "Main Ledger"
; other.beancount
option "title" "Other Ledger" ; Ignored for final ledger
Only options from the main file apply to the final result.
Security¶
Path Traversal Prevention¶
Include paths MUST NOT escape the allowed directory:
; REJECTED: Escapes ledger directory
include "../../../etc/passwd"
include "/etc/passwd"
See security/includes/path-traversal.md.
Symlink Handling¶
The behavior regarding symlinks is implementation-dependent. The Python beancount reference implementation follows symlinks by default.
Best Practices¶
File Organization¶
ledger/
├── main.beancount ; Entry point, includes everything
├── accounts.beancount ; Account definitions (open/close)
├── commodities.beancount ; Commodity declarations
├── prices.beancount ; Historical prices
├── config/
│ └── options.beancount ; Options and plugins
└── transactions/
├── 2024/
│ ├── 01-january.beancount
│ ├── 02-february.beancount
│ └── ...
└── 2023/
└── ...
Main File Structure¶
; main.beancount
;
; Personal Finance Ledger
; =======================
; Configuration
include "config/options.beancount"
; Account structure
include "accounts.beancount"
include "commodities.beancount"
; Historical prices
include "prices.beancount"
; Transactions by year
include "transactions/2023/all.beancount"
include "transactions/2024/all.beancount"
Year File¶
; transactions/2024/all.beancount
include "01-january.beancount"
include "02-february.beancount"
include "03-march.beancount"
include "04-april.beancount"
include "05-may.beancount"
include "06-june.beancount"
include "07-july.beancount"
include "08-august.beancount"
include "09-september.beancount"
include "10-october.beancount"
include "11-november.beancount"
include "12-december.beancount"
Glob Patterns¶
Standard Beancount does NOT support glob patterns:
; NOT SUPPORTED in standard Beancount
include "2024/*.beancount"
Some implementations may support globs as an extension.
Conditional Includes¶
Not directly supported. Use plugins or external tools for conditional logic:
; Standard approach: include different files for different environments
; Use separate main files that include the appropriate environment-specific files:
; main-production.beancount:
include "common.beancount"
include "production.beancount"
; main-development.beancount:
include "common.beancount"
include "development.beancount"
Note: There is no
environmentoption in beancount. Use separate entry-point files or conditional includes via custom plugins.
Implementation Notes¶
- Resolve paths relative to including file
- Track include chain for cycle detection
- Normalize paths before checking cycles
- Apply security checks (path traversal, symlinks)
- Merge directives after all includes processed
- Report errors with full include chain context