Customizing Fava - Dashboards and Visualizations

Fava is great but I want to add some custom visualizations that aren’t in the standard reports:

What I want:

  • Monthly spending trends over the last 2 years
  • Net worth growth chart with projections
  • Savings rate visualization
  • Custom budget tracking dashboard
  • Category comparison charts

Questions:

  • Can I create custom Fava extensions?
  • Are there existing plugins I should try first?
  • How hard is it to add custom charts?
  • Any good examples to learn from?

Has anyone built custom Fava dashboards or extensions?

Fava extension system is great!

Built-in:

  • Save custom queries in Fava
  • Query shell for BQL
  • Configurable charts

Extensions: Python classes:

from fava.ext import FavaExtensionBase
class MyDashboard(FavaExtensionBase):
    report_title = "Dashboard"

Docs: https://beancount.github.io/fava/extensions.html

Built savings tracker in a weekend!

Existing extensions:

  • fava-dashboards
  • fava-envelope (budgeting)
  • fava-investor (charts)

For budgets:

2024-01-01 custom "budget" Expenses:Groceries "monthly" 500 USD

Search GitHub for “fava extension”!

I built a custom net worth projection extension! Here’s the approach:

Extension structure:

class NetWorthProjection(FavaExtensionBase):
    report_title = "Net Worth Projection"
    
    def get_data(self):
        # Query historical net worth
        # Calculate growth rate
        # Project forward 12 months
        return projection_data

Key features:

  • Uses historical data to calculate trends
  • Linear and exponential projections
  • Interactive Chart.js visualization
  • Configurable time ranges

Learning resources:

Took a weekend to build but use it daily now!

For budget tracking specifically, here’s what works:

Option 1: Budget directives
Built into Beancount:

2024-01-01 custom "budget" Expenses:Dining "monthly" 400 USD
2024-01-01 custom "budget" Expenses:Transport "monthly" 200 USD

View in Fava under Budget reports.

Option 2: Virtual envelope accounts

2024-01-01 * "Fund envelopes"
  Assets:Envelopes:Dining  400 USD
  Assets:Envelopes:Transport  200 USD
  Assets:Checking  -600 USD

Then spend from envelopes and watch balances.

Option 3: Custom dashboard extension
Query actual vs budget and visualize:

  • Traffic light indicators (green/yellow/red)
  • Progress bars
  • Month-to-date tracking

I use Option 2 + custom queries - works great!

Follow-up question: For those who built custom extensions - how do you handle updates?

When Fava updates, do your custom extensions break? Any best practices for maintaining compatibility?

Here’s a complete working example of a simple Fava extension:

File: fava_savings_rate.py

from fava.ext import FavaExtensionBase
from beancount.query import query

class SavingsRate(FavaExtensionBase):
    report_title = "Savings Rate"
    
    def query_func(self, sql):
        return query.run_query(
            self.ledger.entries,
            self.ledger.options,
            sql
        )
    
    def get_data(self):
        # Query income and expenses
        income_sql = "SELECT sum(position) WHERE account ~ 'Income'"
        expense_sql = "SELECT sum(position) WHERE account ~ 'Expenses'"
        
        income = self.query_func(income_sql)
        expenses = self.query_func(expense_sql)
        
        # Calculate savings rate
        savings_rate = ((income - expenses) / income) * 100
        
        return {
            'income': income,
            'expenses': expenses,
            'savings_rate': savings_rate
        }

Usage in Beancount file:

2024-01-01 custom "fava-extension" "fava_savings_rate" "SavingsRate"

Install:

  1. Put file in same directory as .beancount file
  2. Restart Fava
  3. New “Savings Rate” tab appears!

This is the simplest possible extension - a great starting point!

Troubleshooting common Fava extension issues:

Problem 1: Extension doesn’t appear

  • Check custom directive syntax is correct
  • Restart Fava completely (Ctrl+C, restart)
  • Check for Python errors in terminal
  • Verify file is in correct location

Problem 2: Import errors

# Correct imports:
from fava.ext import FavaExtensionBase
from beancount.query import query

# Not this:
from fava.extensions import Base  # Wrong!

Problem 3: Data doesn’t update

  • Extensions cache data
  • Use Ctrl+Shift+R to hard refresh
  • Or add ?nocache=1 to URL

Problem 4: Query errors

# Use triple quotes for multi-line SQL
sql = """SELECT account, sum(position)
         WHERE account ~ 'Assets'
         GROUP BY account"""

Debugging tips:

  1. Add print statements (appear in terminal)
  2. Start with simple queries
  3. Test queries in bean-query first
  4. Check Fava logs for errors

Pro tip: Copy an existing extension from GitHub and modify it!

Gallery of community Fava extensions worth checking out:

Popular Extensions:

  1. fava-dashboards - Pre-built dashboard components

    • GitHub: beancount/fava-dashboards
    • Easy to configure, looks great
  2. fava-envelope - Envelope budgeting

    • Visualizes budget envelopes
    • Traffic light indicators
  3. fava-investor - Investment tracking

    • Portfolio allocation charts
    • Performance over time
    • Asset class breakdown
  4. fava-miler - Travel rewards tracking

    • Credit card points
    • Miles balances
  5. fava-portfolio-returns - ROI calculations

    • Time-weighted returns
    • Benchmark comparisons

Where to find more:

  • GitHub search: “fava extension”
  • Awesome Beancount list
  • Plain Text Accounting forum

Installation pattern:

pip install fava-extensionname

# Then in .beancount:
2024-01-01 custom "fava-extension" "fava_extensionname"

Pro tip: Read the source code of popular extensions to learn patterns!