Skip to content

kbdevops/worthly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Worthly

Self-hosted net worth & portfolio dashboard - multi-currency (AUD/USD), live Yahoo Finance prices, Australian CGT calculations, and dividend/franking tracking. Your data, your server, no third party ever sees it.

Build Python React License

Contents

Features

Dashboard

Customisable, drag-to-reorder widgets - net worth timeline, allocation breakdown, holding performance, monthly change - with 5 color themes and configurable stat cards.

Dashboard.mp4

Holdings

Every position with full transaction history. Click into any holding for per-lot gain/loss, add or delete trades, sector/industry metadata pulled automatically.

Holdings.mp4

Tax (Australian CGT)

CGT calculations with the 50% long-term discount applied automatically, per-parcel breakdown, optimal sell-date suggestions.

Tax.mp4

Dividends

Full dividend history auto-fetched from Yahoo Finance, sized by the units you actually held on each ex-dividend date. Tracks Australian franking credits (manually entered - no feed publishes these) and US treaty withholding tax automatically, with net and grossed-up totals.

Milestones

Goals that track live app data - pick one metric or combine several (e.g. Cash + Portfolio), set a target in AUD or USD (USD targets convert to their live AUD equivalent every time you open the app, so progress moves with the exchange rate). Plus an achievements log for past milestones.

Milestones.mp4

Data Sync

Background sync runs automatically twice a day (after ASX and NYSE/NASDAQ close). The Sync tab surfaces real health - per-symbol errors, staleness warnings, last-run results - instead of a black box.

DataSync.mp4

Quick Start

# Backend
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python app.py   # runs on port 5050
# Frontend (separate terminal, dev mode with hot reload)
cd frontend
npm install
npm run dev     # runs on port 5173, proxies /api → 5050

Open http://localhost:5173 in dev mode (or http://localhost:5050 if you've built the frontend for production - see below).

On first run, go to the Data Sync tab and click Sync All to populate prices and metadata for your holdings.

Production build

cd frontend && npm run build   # outputs to frontend/dist/
cd .. && python app.py         # serves the built frontend directly

Docker

docker build -t worthly -f deploy/Dockerfile .
docker run -d -p 5050:5050 \
  -v worthly-data:/app/data \
  -e DATA_DIR=/app/data \
  --name worthly worthly

Mount a volume at DATA_DIR (defaults to the app directory if unset) - this is where prices.db, your transaction history, and everything else lives. Without a persistent volume, all data is lost when the container is recreated.

Configuration

Env var Default Purpose
DATA_DIR app directory Where prices.db and CSV/Excel imports live

There's no built-in authentication - Worthly assumes it's running somewhere you already trust (a home network, a VPN, behind your own reverse-auth proxy). If you're exposing it beyond that, put an auth layer in front of it (Traefik BasicAuth middleware, Tailscale, OAuth2 Proxy, etc.) before you do.

Tech Stack

  • Backend: Flask, SQLite, yfinance, APScheduler (for the twice-daily background price sync)
  • Frontend: React 19 + TypeScript + Vite, Tailwind, Recharts, @dnd-kit (drag-to-reorder widgets)
  • Data: everything lives in a single prices.db SQLite file - no external database to run

Project Structure

worthly/
├── app.py                   # Flask app - all API routes, sync logic, CGT calc
├── requirements.txt
├── docs/
│   └── media/               # Video assets for documentation (Dashboard, Holdings, etc.)
├── frontend/
│   └── src/
│       ├── components/tabs/ # Dashboard, Holdings, Tax, Dividends, Milestones, Sync
│       ├── hooks/useApi.ts  # React Query hooks - one per API endpoint
│       └── types/           # Shared TypeScript types matching the API responses
├── deploy/
│   ├── Dockerfile
│   └── entrypoint.sh
└── CLAUDE.md                # Full API reference and data schemas

See CLAUDE.md for the complete API reference, database schema, and architectural notes.

Contributing

Issues and PRs welcome. This started as a personal project, so some assumptions (single user, AUD base currency, Australian tax rules) are baked in fairly deep - if you want to use it differently, open an issue to discuss before a large PR.

About

Self-hosted net worth & portfolio dashboard with multi-currency tracking, live prices, and Australian CGT calculations

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors