A personal finance management application for aggregating transactions from multiple financial institutions, with automated categorization and spending analysis.
- π¦ Multi-Institution Support - Connect accounts via Plaid (12,000+ institutions), plus CSV import, manual entry, and lunchflow
- π Transaction Management - View, filter, sort, split, and categorize transactions
- π Transfer Tracking - Match transfers between accounts and hide them from spending
- π·οΈ Smart Categorization - Manual and automated transaction categorization
- π Spending Analysis - Track spending by category and time period
- π Secure - Encrypted secrets, user-scoped data isolation
See DEVELOPMENT.md for complete setup instructions.
# Install required tools
brew install borkdude/brew/babashka # Task runner + secrets management
brew install age # Encryption
brew install node # Frontend deps (npm: islands + e2e)
brew install borkdude/brew/clj-kondo # Clojure linting (bb lint)
# Install Jabba (Java version manager)
curl -sL https://github.com/shyiko/jabba/raw/master/install.sh | bash
jabba install zulu@25.0.3
jabba use zulu@25.0.3# 1. Install frontend dependencies (islands/ + e2e/)
bb install
# 2. Configure secrets (interactive)
bb secrets keygen
bb secrets new
# Add your Plaid credentials in the editor
# 3. Start the app (server-authoritative: single backend, no separate web server)
bb devAccess the application at http://localhost:8080.
Modern functional architecture using:
- Integrant - Component lifecycle management
- Datalevin - Embedded Datalog database
- Plaid API - Financial data aggregation
- HTTP-Kit - High-performance HTTP server
See Backend README for details.
The backend renders the UI directly β there is no separate frontend app:
- hiccup2 SSR - HTML rendered on the JVM
- Datastar - reactivity + SSE-patched fragments over the wire
- TS islands - small esbuild-bundled widgets (Zag) for pointer/latency-heavy interactions, served from the backend
- Playwright - real-Chromium browser checks in
e2e/
See islands/README.md and e2e/README.md.
finance-aggregator/
βββ backend/ # Clojure backend (SSR + Datastar, serves frontend assets)
β βββ src/ # Source code
β βββ test/ # Tests
β βββ env/ # Per-environment config + dev/e2e source
β βββ resources/ # Config, secrets, public assets (CSS + built JS)
β βββ README.md # Backend documentation
βββ islands/ # Vanilla TS islands (Zag widgets), esbuild β backend assets
βββ e2e/ # Playwright browser checks (TypeScript)
βββ doc/ # Architecture documentation
β βββ adr/ # Architecture Decision Records
β βββ plans/ # Design notes and feature backlog
βββ scripts/ # Development scripts (bb secrets)
βββ bb.edn # Babashka dev tasks (dev/build/test/lint/e2e/secrets)
βββ DEVELOPMENT.md # Development setup guide
βββ README.md # This file
- Development Setup - Complete development environment setup
- Backend README - Backend architecture and API
- Islands / Browser checks - Frontend assets and e2e
- ADR-001: Category Management Prototype (superseded)
- ADR-002: Modern React Frontend (superseded β React removed 2026-06)
- ADR-003: Clojure Backend Architecture
- ADR-004: Plaid Integration
# Start the app (builds + watches islands, runs the backend dev server)
bb dev
# Or drive the backend from a REPL:
bb build # build frontend assets first
cd backend
jabba use zulu@25.0.3
clojure -M:repl -m nrepl.cmdline
# Then: (go)bb test # backend (kaocha) + islands (vitest)
bb lint # clj-kondo + tsc typechecks
bb e2e # Playwright browser checks against a seeded serverRun bb tasks to list all available dev tasks.
cd backend
jabba use zulu@25.0.3
clojure -M:repl -m nrepl.cmdlineThen in your REPL:
(dev) ; Load dev environment
(go) ; Start the system
(reset) ; Reload and restart after code changes
(halt) ; Stop the systemSee REPL Quick Reference for more commands.
- Server-authoritative UI (hiccup2 SSR + Datastar + TS islands) β replaced the former React/Remix frontend (removed 2026-06)
- Backend infrastructure with Integrant
- Category management system, including a parent/child hierarchy
- Transaction table β filtering, sorting, pagination, transaction splits, and resizable/hideable columns (view state persisted in the URL)
- Transfer tracking β auto-matching, manual match, and a hide-transfers toggle
- Secrets management with age encryption
- REPL-driven development workflow
- Plaid integration - client, encrypted credentials, data transformation, and sync orchestration & persistence (multi-item)
- Additional providers via a provider seam (CSV import, manual entry, lunchflow)
- Reconciliation + account sync hardening (production push)
- User authentication and multi-user support
- Automated transaction categorization
- Spending analytics dashboard
- Budget tracking
Backend:
- Clojure 1.12
- Integrant (system management)
- Datalevin (database)
- HTTP-Kit (web server)
- Reitit (routing)
- Plaid Java SDK (financial data)
Frontend (server-authoritative):
- hiccup2 (JVM-side HTML rendering)
- Datastar (reactivity + SSE)
- TypeScript + esbuild + Zag (islands)
- Playwright (e2e browser checks)
Infrastructure:
- Babashka (dev tasks + scripting)
- age (encryption)
- Jabba (Java version management)
- npm (frontend deps: islands + e2e)
This is a personal project, but the architecture and patterns may be useful for reference.
Private project