SkillAgentSearch skills...

Wealthfolio

A Beautiful Private and Secure Desktop Investment Tracking Application

Install / Use

/learn @afadil/Wealthfolio
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<div align="center"> <a href="https://github.com/afadil/wealthfolio"> <img src="apps/frontend/public/logo.svg" alt="Logo" width="80" height="80"> </a> <h3 align="center">Wealthfolio</h3> <p align="center"> A Beautiful and Boring Desktop Investment Tracker <br /> <br /> <a href="https://wealthfolio.app">Website</a> · <a href="https://discord.gg/WDMCY6aPWK">Discord</a> · <a href="https://x.com/intent/follow?screen_name=WealthfolioApp">Twitter</a> · <a href="https://github.com/afadil/wealthfolio/releases">Releases</a> </p> </div> <div align="center">

<img src="./apps/frontend/public/button-buy-me-a-coffee.png" width="180" alt="Buy me a coffee button"/>

</div> <div align="center"> <a href="https://news.ycombinator.com/item?id=41465735"> <img alt="Featured on Hacker News" src="https://hackerbadge.now.sh/api?id=41465735" style="width: 250px; height: 55px;" width="250" height="55" /> </a> <a href="https://www.producthunt.com/posts/wealthfolio?embed=true&amp;utm_source=badge-featured&amp;utm_medium=badge&amp;utm_souce=badge-wealthfolio" target="_blank"><img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=461640&amp;theme=light" alt="Wealthfolio - A boring, Local first, desktop Investment Tracking app | Product Hunt" class="h-[55px] w-[250px]" width="250" height="55"></a> <a href="https://trendshift.io/repositories/11701" target="_blank"> <img src="https://trendshift.io/api/badge/repositories/11701" alt="afadil%2Fwealthfolio | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a> </div>

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.

Screenshot

✨ 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

Quick Links

Getting Started

Prerequisites

Ensure you have the following installed on your machine:

Building from Source

  1. Clone the repository:

    git clone https://github.com/afadil/wealthfolio.git
    cd wealthfolio
    
  2. Install dependencies using pnpm:

    pnpm install
    
  3. Setup environment configuration:

    Copy the environment template and configure it for your setup:

    cp .env.example .env
    

    Update the .env file with your database path and other configuration as needed:

    # Database location
    DATABASE_URL=../db/wealthfolio.db
    
  4. 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.

  1. 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

  1. Setup environment (optional but recommended):

    Copy the example environment file and customize it for your setup:

    cp .env.web.example .env.web
    

    Edit .env.web to configure database path, ports, and other settings as needed.

  2. Start both backend and Vite dev server:

    pnpm run dev:web
    

    The Vite dev server runs at http://localhost:1420 and 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.db will be used inside it
  • 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
  • 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
  • WF_AUTH_PASSWORD_HASH - Argon2id PHC string enabling password-only authentication for web mode
  • WF_AUTH_TOKEN_TTL_MINUTES - Optional JWT access token expiry in minutes (default 60)
  • WF_AUTH_REQUIRED - Set to false to allow starting on non-loopback addresses without authentication (e.g. when a reverse proxy handles auth)
  • WF_COOKIE_SECURE - Controls the Secure attribute on session cookies (default: auto)
    • auto - set Secure only when X-Forwarded-Proto: https is present (recommended for most reverse-proxy setups)
    • true - always set Secure (use when TLS is guaranteed but the header is absent)
    • false - never set Secure (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_HASH to 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-utils package):

    printf 'your-password' | argon2 yoursalt16chars! -id -e
    

    Tips:

    • The first argument is the salt (use 16+ characters); the password is read from stdin.
    • Use printf instead of echo -n to 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 | | ---------------------------- | ------------------------------------- | ------------------------------------------------ | | .env file | 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

View on GitHub
GitHub Stars7.2k
CategoryDevelopment
Updated3h ago
Forks452

Languages

Rust

Security Score

100/100

Audited on Mar 31, 2026

No findings