https://github.com/breezinstein/future-sight
Self-hosted, household-shared investment & wealth scenario planner β project net worth, model what-if events, compare scenarios. React 19 + Express 5 + SQLite, single Docker container.
https://github.com/breezinstein/future-sight
docker finance homelab household personal-finance react scenario-planning self-hosted sqlite typescript wealth-planner
Last synced: 28 days ago
JSON representation
Self-hosted, household-shared investment & wealth scenario planner β project net worth, model what-if events, compare scenarios. React 19 + Express 5 + SQLite, single Docker container.
- Host: GitHub
- URL: https://github.com/breezinstein/future-sight
- Owner: breezinstein
- License: mit
- Created: 2026-05-20T05:02:33.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-05-20T10:08:21.000Z (about 1 month ago)
- Last Synced: 2026-05-20T12:47:27.459Z (about 1 month ago)
- Topics: docker, finance, homelab, household, personal-finance, react, scenario-planning, self-hosted, sqlite, typescript, wealth-planner
- Language: TypeScript
- Size: 211 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# π Future Sight
A self-hosted, household-shared **investment and wealth scenario planner**. Project net worth over time, model "what-if" events (lump sums, withdrawals, rate changes), and compare alternative scenarios side-by-side. Built for couples and families who've outgrown spreadsheets.
> Inspired by the [`homedash`](https://github.com/breezinstein/homedash) project for self-hosted homelab UX.
---
## β¨ Features
### π Household collaboration
- Multi-user with role-based access (**owner**, **editor**, **viewer**)
- Shared plans, activity log of who changed what
- Lightweight email + password auth, sessions stored in SQLite
### π Scenario planning
- One **base** scenario per household + unlimited "what-if" clones
- Clone any scenario to fork your future
- Side-by-side **comparison view** with overlay charts and diff tables at 5/10/20-year horizons
### π° Buckets & contributions
- Investment "pots" with configurable expected return, currency, target amount, and target date
- Variable contribution schedules over time (monthly / quarterly / annual)
- 16 Lucide icons for visual identification
### π
Event-driven modelling
- **Cash-flow events**: one-off deposits, withdrawals, contribution changes
- **Rate-change events**: override a bucket's return from a date forward
- **Recurring events** with cadence + end date
- Toggle events on/off for sensitivity testing without deleting
### π Historical tracking
- Record actual balances per bucket over time
- Compare projected vs. actual on the dashboard with drift indicator
- CSV import of historical actuals
### π Multi-currency
- Each bucket has its own currency
- Live FX conversion to the plan's base currency via **[frankfurter.app](https://frankfurter.app)** (ECB-backed, no API key)
- Local cache with 6-hour TTL on latest rates; historical rates cached forever
### π¨ Design
- Dark-first, Linear-inspired aesthetic
- Inter typography with tabular figures throughout
- Generated UI from a Stitch design brief; tokens locked in `src/index.css`
---
## π Quick start
### Option 1: Pre-built image from GitHub Container Registry (recommended)
```bash
docker run -d \
--name future-sight \
-p 3002:3002 \
-v future-sight-data:/app/data \
-e SESSION_SECRET="$(openssl rand -hex 32)" \
--restart unless-stopped \
ghcr.io/breezinstein/future-sight:latest
```
Or with Docker Compose:
```yaml
services:
future-sight:
image: ghcr.io/breezinstein/future-sight:latest
container_name: future-sight
restart: unless-stopped
ports:
- "3002:3002"
volumes:
- future-sight-data:/app/data
environment:
- NODE_ENV=production
- SESSION_SECRET=change-me-to-a-random-string
- ALLOW_REGISTRATION=true
volumes:
future-sight-data:
driver: local
```
Open and create your first account.
Images are published for **linux/amd64** and **linux/arm64** (Raspberry Pi 4+, Apple Silicon, etc.).
### Option 2: Build from source
```bash
git clone https://github.com/breezinstein/future-sight.git
cd future-sight
docker compose up -d --build
```
### Option 3: Local development
```bash
npm install
npm run dev
```
This starts both:
- Backend API on http://localhost:3002
- Vite dev server on http://localhost:5174 (with proxy to the API)
Open .
### Option 4: Production build (no Docker)
```bash
npm install
npm run build
NODE_ENV=production PORT=3002 SESSION_SECRET= npm start
```
Open .
---
## π Tech stack
| Layer | Choice |
|---|---|
| Frontend | React 19, TypeScript, Tailwind CSS 4, Vite |
| Charts | Recharts |
| Forms | react-hook-form + zod |
| Icons | lucide-react |
| Dates | date-fns |
| Backend | Node 20, Express 5 (ESM) |
| Database | SQLite via `better-sqlite3` (WAL mode) |
| Auth | bcrypt + express-session + connect-sqlite3 |
| FX | [frankfurter.app](https://frankfurter.app) (ECB-backed) |
| Testing | Vitest |
| Deploy | Single Docker container, multi-stage build |
---
## ποΈ Data model
```
users
plans (created_by) βββ¬ββ plan_members (role)
βββ scenarios (is_base, cloned_from)
βββ buckets (currency, return, target)
β βββ contribution_schedules
β βββ actuals
βββ events (cash-flow & rate-change)
fx_cache audit_log
```
All updates to plan / scenario data bump a `version` counter on the plan for cheap polling-based sync between household members (homedash-style).
---
## π Security notes
- Passwords hashed with **bcrypt** (cost 12).
- Sessions stored server-side in `data/sessions.db`. The cookie holds only an opaque session ID.
- Set `TRUST_PROXY=true` when running behind a TLS-terminating reverse proxy so secure cookies are issued.
- Lock down new account registration with `ALLOW_REGISTRATION=false` (the bootstrap user can still be created when the user table is empty).
- The frankfurter.app API is the only external dependency. Disable network egress if you don't need multi-currency.
---
## π§ͺ Tests
```bash
npm test # run the projection engine tests
npm run test:watch # watch mode
```
The projection engine has 11 tests covering compounding, contributions, deposits, withdrawals, rate changes, and milestone detection.
---
## π API reference (selected)
```
POST /api/auth/signup # create user + default plan + base scenario
POST /api/auth/login
POST /api/auth/logout
GET /api/auth/me
GET /api/plans # list my plans
POST /api/plans # create plan
GET /api/plans/:id # plan + members + scenarios
GET /api/plans/:id/activity # audit log
GET /api/plans/:id/members
POST /api/plans/:id/members
POST /api/plans/:id/compare # multi-scenario comparison
GET /api/plans/:id/scenarios
POST /api/plans/:id/scenarios
GET /api/scenarios/:id
PATCH /api/scenarios/:id
DELETE /api/scenarios/:id
POST /api/scenarios/:id/clone
GET /api/scenarios/:id/projection
GET /api/scenarios/:id/export?type=actuals|events|contributions
POST /api/scenarios/:id/buckets
GET /api/buckets/:id
PATCH /api/buckets/:id
DELETE /api/buckets/:id
POST /api/buckets/:id/contributions
POST /api/buckets/:id/actuals
POST /api/buckets/:id/actuals/import
POST /api/scenarios/:id/events
PATCH /api/events/:id
DELETE /api/events/:id
GET /api/fx/currencies
GET /api/fx/rate?base=USD"e=EUR
```
---
## π Project layout
```
future-sight/
βββ server/
β βββ index.js # Express entry
β βββ db/
β β βββ database.js # better-sqlite3 setup + WAL
β β βββ schema.sql # tables, indexes, triggers
β βββ lib/
β β βββ auth.js # bcrypt, session middleware
β β βββ audit.js # audit log writer
β β βββ projection.js # projection engine
β β βββ fx.js # frankfurter.app + cache
β β βββ csv.js # tiny CSV parser/emitter
β βββ routes/ # auth, plans, scenarios, buckets, events, ...
βββ src/
β βββ App.tsx # router
β βββ main.tsx # ReactDOM + providers
β βββ index.css # Tailwind 4 @theme tokens
β βββ api/ # typed fetch client
β βββ components/ # AppLayout, Sidebar, BucketEditor, EventEditor, ...
β βββ context/ # AuthContext, ToastContext
β βββ hooks/
β βββ lib/format.ts # currency/date helpers
β βββ pages/ # Dashboard, ScenarioDetail, ScenarioCompare, ...
β βββ types.ts # shared types
βββ tests/
β βββ projection.test.js # projection engine tests
βββ data/ # SQLite DB + sessions DB (mounted volume in Docker)
βββ Dockerfile
βββ docker-compose.yml
βββ entrypoint.sh
```
---
## πΊοΈ Roadmap / nice-to-haves
These are intentionally out of scope for v1 but would be useful next steps:
- [ ] Email-based household invites (vs. requiring the member to sign up first)
- [ ] CSV column-mapping wizard (currently expects fixed column names)
- [ ] Server-Sent Events for live sync between concurrent editors
- [ ] Daily-snapshot backups with retention policy
- [ ] Inflation toggle (real vs. nominal projections)
- [ ] Tax modelling
- [ ] Bank/brokerage account sync (explicitly out of scope per design)
---
## π License
MIT.