Personal Financial
Dashboard
A self-hosted dashboard that aggregates all your financial accounts in one place. Connect bank accounts via Plaid, track crypto with Coinbase, and maintain complete control over your financial data.

The Problem with Financial Tracking
Managing finances across multiple institutions is fragmented and privacy-invasive.
No Privacy
Cloud-based apps like Mint share your data with advertisers and third parties. Your financial data is their product.
Subscription Fatigue
Premium finance apps charge $10-15/month. That's $120-180/year just to see your own money.
Fragmented View
Bank apps, crypto exchanges, investment platforms—your wealth is scattered across dozens of interfaces.
Self-Hosted Financial Freedom
Your data, your server, your rules. No subscriptions, no data mining, complete visibility.
100% Self-Hosted
Runs on your own hardware. Your financial data never leaves your control.
Multi-Provider
Connect Plaid for banks, Coinbase for crypto, SimpleFIN for credit unions.
Rich Analytics
Net worth tracking, balance history charts, account type breakdowns.
Open Source
Fully auditable code. MIT licensed. Customize to your needs.
Technical Stack
Modern, efficient stack optimized for self-hosting with minimal dependencies.
Frontend
- Next.js 15.1.6 (App Router)
- React 19
- TailwindCSS
- shadcn/ui
- Chart.js + react-chartjs-2
Backend
- Next.js API Routes
- Prisma ORM
- SQLite (file-based)
- TypeScript
Integrations
- Plaid API (Banking)
- Coinbase OAuth (Crypto)
- SimpleFIN (Credit Unions)
- Amazon SES (Email)
Data Models
- Multi-provider accounts
- Balance history tracking
- Transaction categorization
- Investment securities
Features
- Real-time balance sync
- Net worth charts
- Account type grouping
- Daily email reports
Deployment
- Self-hosted anywhere
- Docker support
- Cron job automation
- Zero cloud dependency
System Architecture
A clean, self-contained architecture that prioritizes data ownership and simplicity.
Data Sources
Processing Layer
Presentation
Key Features
Multi-Provider Aggregation
One dashboard for all your financial institutions
The dashboard normalizes data from multiple providers into a unified schema. Each PlaidItem can be either a traditional bank connection or a Coinbase OAuth session, with accounts stored in a common format.
model PlaidItem {
id String @id
provider String // "plaid" | "coinbase"
institutionName String?
accounts Account[]
}
model Account {
type String // checking, savings, crypto
balances AccountBalance[]
}Net Worth Tracking
Historical balance data with Chart.js visualizations
Every balance refresh creates a new AccountBalance record, building a time-series of your wealth. The NetWorthChart component aggregates this data across all accounts to show your financial trajectory over time.
Comprehensive Transactions
Full transaction history with investment details
The Transaction model captures everything from simple purchases to complex investment transactions. Security metadata, location data, and categorization are all preserved for detailed analysis.
- Investment buy/sell with security details
- Location and merchant metadata
- Personal finance categorization
- Download logs for audit trails
Automated Updates
Cron-driven refreshes with email notifications
A shell script refreshes all account balances via cron, optionally sending a daily summary email through Amazon SES. Perfect for hands-off wealth monitoring.
# Daily balance refresh at 6 AM 0 6 * * * /app/scripts/refresh-data.sh # The script: # 1. Fetches latest balances from Plaid # 2. Updates Coinbase holdings # 3. Sends email summary via SES
Privacy Comparison
How self-hosting changes the privacy equation.
| Aspect | Cloud Finance Apps | Personal Financial Dashboard |
|---|---|---|
| Data Storage | Their servers, their rules | Your SQLite file, your machine |
| Data Sharing | Often sold to advertisers | Never leaves your network |
| Cost | $10-15/month subscription | Free + Plaid API costs (~$0) |
| Customization | What they decide to build | Full source code access |
| Shutdown Risk | Company closes, data lost | Runs until you stop it |
| API Access | Locked in their ecosystem | Direct Plaid/Coinbase keys |
Technical Challenges
Interesting problems solved during development.
Multi-Provider Normalization
Plaid and Coinbase return different data structures. Investment transactions have security metadata that regular transactions don't.
Created a unified Account/Transaction schema with optional fields for provider-specific data. The provider field on PlaidItem determines parsing logic.
OAuth Token Refresh
Coinbase OAuth tokens expire. Without refresh handling, users would need to re-authenticate constantly.
Store refresh_token alongside access_token. Background job checks token expiry before API calls and silently refreshes when needed.
Balance History Aggregation
Calculating net worth requires summing balances across accounts that may have been recorded at different times.
Group AccountBalance records by date, fill gaps with previous known values, then aggregate. Chart.js handles the visualization.
Investment Transaction Complexity
Investment transactions include buy/sell, dividends, transfers, fees—each with different required fields.
Expanded Transaction model with nullable security fields (ticker, ISIN, CUSIP, etc.). Type and subtype fields capture transaction semantics.
Results
Take Control of Your Finances
Personal Financial Dashboard is open source and free to use. Deploy it on your own server and own your financial data.