Wealthfolio
A Beautiful Private and Secure Desktop Investment Tracking Application
Install / Use
/learn @afadil/WealthfolioREADME
Introduction
Wealthfolio App is a Beautiful and Boring Investment Tracker, with Local Data Storage. No Subscriptions, No Cloud.
Visit the app website at Wealthfolio App.

✨ Key Features
- 📊 Portfolio Tracking - Track your investments across multiple accounts and asset types
- 📈 Performance Analytics - Detailed performance metrics and historical analysis
- 💰 Activity Management - Import and manage all your trading activities
- 🎯 Goal Planning - Set and track financial goals with allocation management
- 🔒 Local Data - All data stored locally with no cloud dependencies
- 🧩 Extensible - Powerful addon system for custom functionality
- 🌍 Multi-Currency - Support for multiple currencies with exchange rate management
- 📱 Cross-Platform - Available on Windows, macOS, and Linux
🧩 Addon System
Wealthfolio features a powerful addon system that allows developers to extend functionality:
- 🔌 Easy Development - TypeScript SDK with full type safety and hot reload
- 🔒 Secure - Comprehensive permission system with user consent
- ⚡ High Performance - Optimized for speed with minimal overhead
- 🎨 UI Integration - Add custom pages, navigation items, and components
- 📡 Real-time Events - Listen to portfolio updates, market sync, and user actions
- 🗄️ Full Data Access - Access to accounts, holdings, activities, and market data
- 🔐 Secrets Management - Secure storage for API keys and sensitive data
Get started building addons: See the Addon Documentation Hub
Documentation for all Activity types, including the required form fields, is available in docs/activities/activity-types.md.
Roadmap
See ROADMAP.md.
📖 Documentation
Core Application
- Activity Types - Complete guide to all supported activity types and their required fields
- Roadmap - Future plans and development roadmap
Architecture
- Adapter System - Compile-time environment detection for Desktop/Web builds
Addon Development
- Addon Documentation Hub - Main entry point for addon development
- Getting Started - Guide to get started with addon development
- API Reference - Complete API documentation with examples
- Architecture - Design patterns and architecture guide
Quick Links
- 💡 Example Addons - Browse sample addons in the repository
- 🛠️ Development Tools - CLI tools for addon development
Getting Started
Prerequisites
Ensure you have the following installed on your machine:
Building from Source
-
Clone the repository:
git clone https://github.com/afadil/wealthfolio.git cd wealthfolio -
Install dependencies using pnpm:
pnpm install -
Setup environment configuration:
Copy the environment template and configure it for your setup:
cp .env.example .envUpdate the
.envfile with your database path and other configuration as needed:# Database location DATABASE_URL=../db/wealthfolio.db -
Run in Development Mode:
Build and run the desktop application using Tauri:
pnpm tauri dev
Addon Development Mode
Addon hot reload servers now start only when you explicitly opt in.
For desktop development with Tauri:
VITE_ENABLE_ADDON_DEV_MODE=true pnpm tauri dev
For browser-only development (Vite only, no Tauri):
pnpm dev:addons
You can also set VITE_ENABLE_ADDON_DEV_MODE=true in your .env file to
persist the setting.
- Build for Production:
Build the application for production:
pnpm tauri build
Web Mode (Browser + REST API server)
Run the web UI with a local Axum server with one command.
Quick Start
-
Setup environment (optional but recommended):
Copy the example environment file and customize it for your setup:
cp .env.web.example .env.webEdit
.env.webto configure database path, ports, and other settings as needed. -
Start both backend and Vite dev server:
pnpm run dev:webThe Vite dev server runs at
http://localhost:1420and proxies API calls to the Axum backend server.
Configuration
All configuration is done via environment variables in .env.web.
Server Configuration (WF_* variables):
WF_LISTEN_ADDR- Server bind address (default:0.0.0.0:8080)WF_DB_PATH- SQLite database path or directory (default:./db/app.db)- If a directory is provided,
app.dbwill be used inside it
- If a directory is provided,
WF_CORS_ALLOW_ORIGINS- Comma-separated list of allowed CORS origins (default:*). Required when auth is enabled — wildcard*is rejected.- Example:
https://wealthfolio.example.com
- Example:
WF_REQUEST_TIMEOUT_MS- Request timeout in milliseconds (default:30000)WF_STATIC_DIR- Directory for serving static frontend assets (default:dist)WF_SECRET_KEY- Required 32-byte key used for secrets encryption and JWT signing- Generate with:
openssl rand -base64 32
- Generate with:
WF_AUTH_PASSWORD_HASH- Argon2id PHC string enabling password-only authentication for web modeWF_AUTH_TOKEN_TTL_MINUTES- Optional JWT access token expiry in minutes (default60)WF_AUTH_REQUIRED- Set tofalseto allow starting on non-loopback addresses without authentication (e.g. when a reverse proxy handles auth)WF_COOKIE_SECURE- Controls theSecureattribute on session cookies (default:auto)auto- setSecureonly whenX-Forwarded-Proto: httpsis present (recommended for most reverse-proxy setups)true- always setSecure(use when TLS is guaranteed but the header is absent)false- never setSecure(plain HTTP without a reverse proxy)
WF_SECRET_FILE- Optional path to secrets storage file (default:<data-root>/secrets.json)WF_ADDONS_DIR- Optional path to addons directory (default: derived from database path)
Vite Configuration:
VITE_API_TARGET- Backend API URL for Vite proxy (default:http://127.0.0.1:8080)
Authentication (Web Mode)
-
Set
WF_AUTH_PASSWORD_HASHto an Argon2id PHC string to require a password before accessing the Web App.You can generate the hash with online tools like argon2.online or the CLI (
argon2-utilspackage):printf 'your-password' | argon2 yoursalt16chars! -id -eTips:
- The first argument is the salt (use 16+ characters); the password is read from stdin.
- Use
printfinstead ofecho -nto avoid hidden newline issues. - For Docker Compose, double every
$in the hash ($$argon2id$$...).
Copy the full output (starting with
$argon2id$...) into.env.web.Dollar-sign (
$) escaping cheat-sheet — Argon2 hashes contain$characters that shells and Compose interpret as variable references:| Context | Syntax | Notes | | ---------------------------- | ------------------------------------- | ------------------------------------------------ | |
.envfile |WF_AUTH_PASSWORD_HASH=$argon2id$...| No quotes, no escaping needed | | Docker Compose YAML inline |HASH: '$$argon2id$$v=19$$...'| Double every$to escape Compose interpolation | |docker run(single quotes) |-e HASH='$argon2id$...'| Single quotes prevent shell expansion | |docker run(double quotes) |-e HASH="\$argon2id\$..."| Backslash-escape each$| -
Sessions are cookie-b
