As the operations manager for a growing 15-person company, I’ve spent the last 6 months transforming how we handle our finances. We migrated from QuickBooks Online to beancount.io v3, and the team collaboration features have been a game-changer.
Let me share our real-world experience with v3’s team features and how they’ve solved our collaboration headaches.
Our Company Context
We’re a digital marketing agency with:
- 15 employees (mix of remote and in-office)
- $2.5M annual revenue
- ~1,200 transactions/month
- 3 people who need regular access to financials (me, CFO, accountant)
- 5 people who need occasional read-only access (department heads)
- Quarterly board meetings requiring financial reports
The Old Way (QuickBooks Online)
Before v3, our workflow was painful:
Problem 1: Too many cooks in the kitchen
- QuickBooks has “users” but terrible permission controls
- Our accountant accidentally deleted transactions meant for review
- Department heads could see ALL financials (including salaries)
- No way to give “view only for specific accounts” access
Problem 2: Version confusion
- “Which numbers are current?”
- “Did you include the January adjustments?”
- “I’m looking at different numbers than you!”
- No single source of truth
Problem 3: Collaboration = email chaos
- Email threads with Excel attachments
- “Final_v2_ACTUALLY_FINAL.xlsx”
- Someone working on old version
- Manual reconciliation of changes
Problem 4: No audit trail
- Who changed this transaction?
- When was it changed?
- Why was it changed?
- QuickBooks audit log is terrible (cryptic, hard to search)
The New Way (beancount.io v3 Team Features)
v3’s approach is fundamentally different. Instead of a centralized server with user accounts, it uses Git-based collaboration with role-based access controls.
How It Works
1. Git Repository (Single Source of Truth)
All our financial data lives in a Git repository:
company-finances/
├── main.beancount (master ledger)
├── accounts/
│ ├── income.beancount (revenue transactions)
│ ├── expenses.beancount (expense transactions)
│ ├── payroll.beancount (payroll - restricted access)
├── documents/ (linked receipts, invoices)
└── reports/ (generated reports)
2. Team Members with Different Access Levels
We have 3 tiers of access:
Tier 1: Full Access (3 people)
- Me (Operations Manager)
- Sarah (CFO)
- Tom (External Accountant)
Permissions:
- Read and write all ledgers
- Approve transactions (Git merge permissions)
- Generate reports
- Invite new team members
Tier 2: Department Read Access (5 people)
- Marketing Director (sees marketing budget)
- Sales Director (sees sales commissions)
- Engineering Manager (sees R&D expenses)
- HR Manager (sees benefits, NOT individual salaries)
- Operations Lead (sees operational costs)
Permissions:
- Read-only access to specific ledger files
- Can view reports for their departments
- Cannot edit transactions
- Cannot see payroll details
Tier 3: Board Members (4 people)
- Read-only access to summary reports
- Quarterly report access only
- No transaction-level detail
- No access to Git repo (they get PDF exports)
Setting Up Team Access (Step-by-Step)
Here’s exactly how we set this up:
Step 1: Create Git Repository
We use GitHub (private repo) for hosting:
# Initialize repo
git init company-finances
cd company-finances
# Create initial structure
touch main.beancount
mkdir accounts documents reports
# Initial commit
git add .
git commit -m "Initial financial ledger setup"
# Push to GitHub
git remote add origin [email protected]:ourcompany/finances.git
git push -u origin main
Step 2: Invite Team Members via Email
v3 has a web interface for team management:
In v3 dashboard:
- Go to “Team Settings”
- Click “Invite Member”
- Enter email address
- Select role: “Admin”, “Editor”, “Viewer”, “Department Viewer”
- For Department Viewer, select which ledger files they can access
- Click “Send Invitation”
Email sent:
Subject: Invitation to Company Finances (beancount.io v3)
Hi Sarah,
Lisa has invited you to collaborate on Company Finances.
Role: Admin (Full Access)
Access: All ledgers, all reports
Click here to accept: [Accept Invitation]
You'll need a GitHub account to collaborate. If you don't have one,
you can create one for free at github.com.
Once you accept, you'll be able to:
- Clone the repository to your local machine
- View all financial transactions
- Submit changes for approval
- Generate reports
Questions? Contact [email protected]
Step 3: Team Member Accepts Invitation
When Sarah clicks “Accept Invitation”:
- She’s prompted to connect her GitHub account
- She’s added to the GitHub repo with appropriate permissions
- She receives setup instructions:
Welcome to Company Finances!
To get started:
1. Install beancount.io v3:
https://beancount.io/install
2. Clone the repository:
git clone [email protected]:ourcompany/finances.git
cd finances
3. Open in v3 web interface:
beancount-web main.beancount
4. Or use command-line tools:
beancount-query main.beancount
You're all set! Changes you make will be tracked via Git.
Step 4: Role-Based Permissions (GitHub)
We configure GitHub branch protection rules:
Main branch protection:
- Require pull request reviews (2 approvals)
- Require status checks to pass (beancount validation)
- No direct pushes to main
- Only Admins can approve PRs
Who can approve: Me, Sarah (CFO), Tom (Accountant)
Why this matters:
- Prevents accidental changes to main ledger
- Ensures all edits are reviewed
- Creates audit trail of approvals
Step 5: File-Level Access Control
For department viewers, we use Git sparse-checkout:
Example: Marketing Director sees only marketing expenses
# Marketing Director's setup
git clone --no-checkout [email protected]:ourcompany/finances.git
cd finances
git sparse-checkout init --cone
git sparse-checkout set accounts/marketing-expenses.beancount reports/marketing/
# Now they only see:
# accounts/marketing-expenses.beancount
# reports/marketing/
# They CANNOT see:
# accounts/payroll.beancount
# accounts/executive-comp.beancount
Our Team Workflow
Here’s our day-to-day collaboration workflow:
Scenario 1: Monthly Expense Entry (Accountant)
Tom (Accountant) enters monthly expenses:
- Pull latest changes
git pull origin main
- Create a branch for this month’s work
git checkout -b march-2025-expenses
- Add transactions to appropriate files
# Edit accounts/expenses.beancount
# Add 200+ transactions for March
# Link documents (receipts, invoices)
- Commit changes
git add accounts/expenses.beancount documents/
git commit -m "March 2025 expenses - 237 transactions"
- Push to GitHub and create Pull Request
git push origin march-2025-expenses
GitHub sends notification: “Tom has created a PR: March 2025 expenses”
- I review the PR
In GitHub PR interface, I see:
- All 237 transactions added
- Linked documents (receipts)
- Summary: Total expenses $145,320
- beancount validation: PASSED (all entries balance)
I can comment on specific lines:
Line 45: "Office Depot - Supplies $450"
Comment: "This seems high, can you verify the invoice?"
Tom responds, uploads invoice, I verify.
- I approve the PR
Click “Approve and Merge”
- Changes are now in main ledger
Everyone on the team pulls latest:
git pull origin main
Now Sarah (CFO) sees updated numbers in her reports.
Scenario 2: Budget Review (Department Head)
Marketing Director wants to check budget spend:
- Pull latest changes (read-only)
git pull origin main
- Open v3 web interface
beancount-web accounts/marketing-expenses.beancount
- View dashboard
She sees:
- YTD marketing spend: $280,000
- Budget: $350,000
- Remaining: $70,000 (20% of year left, 20% of budget left - on track!)
- Export report for her team
In v3 web UI:
- Click “Reports” → “Marketing Expenses by Category”
- Select date range: Jan 1 - Mar 31, 2025
- Click “Export to PDF”
She emails the PDF to her team (no access to raw financial data needed).
Scenario 3: Board Meeting Prep (CFO)
Sarah (CFO) prepares quarterly board report:
- Generate reports from v3
# Profit & Loss
beancount-query main.beancount "
SELECT account, SUM(position)
WHERE account ~ 'Income|Expenses'
AND year = 2025 AND quarter = 1
GROUP BY account
" > reports/q1-2025-pl.csv
# Balance Sheet
beancount-query main.beancount "
SELECT account, SUM(position)
WHERE account ~ 'Assets|Liabilities|Equity'
AND date <= 2025-03-31
GROUP BY account
" > reports/q1-2025-balance-sheet.csv
- Create visualizations
v3 has built-in charting:
- Revenue trend (monthly)
- Expense breakdown (pie chart)
- Cash flow (waterfall chart)
- Export PDF for board
v3 generates professional PDF:
- Cover page with company logo
- Executive summary
- Charts and graphs
- No transaction-level detail (privacy)
- Commit report to Git
git add reports/q1-2025-board-report.pdf
git commit -m "Q1 2025 board report"
git push
Now the report is version-controlled. If board asks questions next quarter, we can refer back to exact numbers we presented.
Real-Time Collaboration Features
Feature 1: Activity History
v3 web interface shows recent activity:
Activity Feed (Last 7 Days)
Mar 15, 10:30 AM - Tom committed "March expenses batch 1"
→ 87 transactions added to accounts/expenses.beancount
Mar 15, 2:15 PM - Lisa approved PR "March expenses batch 1"
→ Changes merged to main
Mar 16, 9:00 AM - Sarah generated report "Q1 P&L"
→ reports/q1-2025-pl.pdf
Mar 16, 11:45 AM - Tom committed "March payroll"
→ accounts/payroll.beancount updated
→ 15 employees processed
Mar 17, 8:30 AM - Marketing Director viewed "Marketing Expenses YTD"
→ No changes made
Feature 2: Real-Time Sync
When anyone pushes changes, GitHub sends webhook to v3:
- Desktop app shows notification: “New changes available - Pull to update”
- Click notification → auto-runs
git pull - Reports refresh with latest data
No more “which version are you looking at?” confusion!
Feature 3: Commenting and Discussion
GitHub PRs allow inline comments:
Example PR discussion:
Tom (Accountant): "Added March client invoices"
File: accounts/income.beancount
Line 234: 2025-03-15 * "ClientABC - March retainer"
Assets:Receivable 15000.00 USD
Income:Services -15000.00 USD
Sarah (CFO): "Didn't ClientABC increase to $18k/month in March?"
Tom: "Good catch! I'll update. They sent corrected invoice."
[Tom updates transaction]
Tom: "Fixed! Changed to $18,000."
Sarah: "Approved!"
This discussion is preserved forever in PR history.
Feature 4: Conflict Resolution
If two people edit the same file simultaneously:
Scenario:
- Tom adds March expenses (line 500)
- I add March revenue (line 100)
- Both push at same time
Git handles this automatically:
- No conflict (different lines)
- Both changes merge cleanly
If we edit SAME transaction:
<<<<<<< HEAD
2025-03-15 * "Office Depot - Supplies"
Expenses:Supplies 450.00 USD
Liabilities:CreditCard -450.00 USD
=======
2025-03-15 * "Office Depot - Supplies" ^receipt-office-depot.pdf
Expenses:Supplies 450.00 USD
Liabilities:CreditCard -450.00 USD
>>>>>>> tom-march-expenses
Git shows conflict. We discuss (via PR comment) and resolve.
Advanced Team Features
Feature 1: Multi-Ledger Support
We split our ledger into multiple files for team collaboration:
main.beancount: