Skip to content
EraPartnerPublic

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Latest commit

Β 

History

2,278 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Vision

Self-hosted personal finance for people who care about privacy, clarity, and control.
Track transactions, plan cash flow, manage investments, and prepare your Belgian taxes, all on your own Mac.

CI License: AGPL-3.0-only Platform: macOS (Apple Silicon) Frontend: React + TypeScript Backend: Express on Bun Database: SQLite Languages: EN | NL


What is Vision?

Vision is a desktop finance manager. It imports your bank exports, categorizes and analyses your spending, tracks your portfolio and net worth, and computes Belgian personal income tax. Your data lives in one SQLite database file in the app's own data folder on your Mac. There is no database server.

  • Private by default. No account and no cloud service. AI chat and investigations run on a local Ollama model (AI data access).
  • One app. Transactions, budgets, planned payments, forecasts, investments, research, and tax in one place.
  • Built to last. A strict TypeScript monorepo with an OpenAPI contract, a SQLite schema under versioned migrations, and tests against a real database.

Vision is a native macOS app for Apple Silicon. There are no Windows, Linux, or browser builds (ADR-219).


Features

πŸ’³ Transactions and imports

  • CSV import from Belfius, Revolut, KBC, SABB, Wise, ING, BNP Paribas Fortis, a Vision backup, or a generic CSV mapper
  • Deduplication, categorization rules, transfer detection between your own accounts, splits, tags, attachments, and bulk actions across many rows at once
  • Accounts with running balances and reconciliation
  • Export to CSV or the Vision backup format

πŸ“… Budgeting and planning

  • Categories and recipients with rules, merging, and exclusions
  • Planned and recurring transactions with execution history
  • Cash-flow forecast from planned transactions or statistical methods, with confidence bands
  • Statistics: year-over-year comparisons, pivot tables with drill-through, a Sankey flow chart, rolling averages, and saved custom charts
  • Analysis workspace over approved datasets, with saved analyses and scheduled monitors

πŸ“ˆ Portfolio and net worth

  • Stocks, ETFs, crypto, precious metals, real estate, savings, and bonds
  • Price providers: Yahoo Finance, Binance, Kinesis, and custom JSON endpoints
  • Currency conversion from stored rates (ECB, with open.er-api for currencies ECB does not publish)
  • Daily net-worth snapshots and performance over time
  • Portfolio statement import, market lookup, watchlist, and research dossiers

πŸ‡§πŸ‡ͺ Belgian tax

  • Personal income tax calculator with regional rules, deductions, and cadastral income
  • Portfolio tax tracking (including the Reynders rule)
  • The server computes all tax figures (ADR-217)

πŸ€– AI chat

  • Local assistant on Ollama that answers questions about your transactions and categories with tool-backed result cards

🧩 App

  • English and Dutch
  • PDF reports for finances, portfolio, and tax
  • Backup and restore, with optional AES-256-GCM encryption (per-backup random salt)
  • In-app updates for the packaged app, with a backup and rollback path

Feature details live in docs/features/.


Quick start

Install the macOS app

Install the release DMG. It contains Bun, the migrations, the backend and the frontend, and uses the SQLite library that ships with macOS. PDF reports print with the desktop app's own Electron Chromium.

Vision creates its database, database/vision.sqlite3, under its macOS application-data directory on first launch. See docs/guides/native-macos-runtime.md for the data layout and rollback.

Coming from Vision 2.0? Its data was in PostgreSQL, which this version does not read. Convert a Vision 2.0 backup with bun run transition:v2 -- <backup file> from a checkout of commit dd4cc71, the last one with the transition script.

Build the app from source

You need Bun and Node.js. No database server is needed.

git clone https://github.com/EraPartner/Vision.git
cd Vision
./install.sh
open /Applications/Vision.app

Try the demo

Vision Demo is a separate app with deterministic synthetic data. It uses its own database below ~/Library/Application Support/Vision Demo/database/ and cannot reach the real Vision database.

./install-demo.sh
open "/Applications/Vision Demo.app"
bun run demo:reset-native   # restore the canonical dataset, then reopen the Demo app

Both installers build the frontend in a private temporary directory and do not touch the repository's dist directory.

Development mode

bun install --frozen-lockfile
bun run dev              # watched backend on its own development database + Vite
Service URL
Frontend http://127.0.0.1:8080 (picks the next port if taken)
Backend API http://localhost:3002

More setup detail: docs/getting-started.md.


Architecture

flowchart LR
  subgraph Electron["Electron shell (macOS)"]
    UI["React 19 frontend<br/>TanStack Query"]
  end
  UI -- "REST (openapi.yaml)" --> API["Express backend on Bun<br/>routes β†’ services β†’ repositories"]
  API -- "Kysely" --> DB[("SQLite file<br/>in-process, app data folder")]
  API --> Ext["Price, FX and research providers"]
  API --> AI["Ollama (local)"]
Loading
  • The server computes, the browser displays. Totals, FX conversion, gains, forecasts, and tax are computed by the backend (ADR-216).
  • Database access goes through Kysely with types generated from the migrated schema (ADR-226).
  • Migrations are numbered .sql files in db/migrations/, applied on boot in one transaction, after an automatic copy of a database that already holds data (ADR-263).
  • Ids, currency codes and money are branded types (ADR-220).

Read more in docs/architecture/ and the ADRs.

Monorepo layout

Vision/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ frontend/          # React 19 + TypeScript + Vite (features/, components/, hooks/, stores/)
β”‚   └── node-backend/      # Express API on Bun (routes/, services/, repositories/, integrations/)
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ shared-utils/      # Pure helpers shared by backend and frontend (money, CSV, Belgian tax engine)
β”‚   └── types/             # Shared TypeScript types and branded ids
β”œβ”€β”€ packaging/electron/    # Desktop shell and native runtime
β”œβ”€β”€ db/migrations/         # SQLite migrations
β”œβ”€β”€ i18n/source/           # Locale sources, compiled to apps/frontend/src/locales/
β”œβ”€β”€ scripts/               # Repository tooling (locales, checks)
β”œβ”€β”€ config/                # Shared tool configuration
β”œβ”€β”€ docs/                  # Obsidian knowledge base (ADRs, features, guides, reference)
└── openapi.yaml           # REST API contract

Tech stack

Layer Technology
Frontend React 19, TypeScript, Vite, Tailwind CSS, Radix UI, shadcn/ui, TanStack Query
Backend Express on Bun, Zod, decimal.ts
Database SQLite (system library, 3.39 or later) with Kysely
Desktop Electron, Apple Silicon DMG and ZIP
AI Ollama (local)
Testing Vitest, with backend tests against real SQLite database files
API spec OpenAPI 3 (openapi.yaml)

Development

Common scripts

# Run
bun run dev                  # watched backend on its own development database + Vite
bun run electron:dev         # desktop shell with isolated development data

# Check
bun run lint                 # frontend, backend and projects ESLint + import boundaries (depcruise) + dead code (knip)
bun run lint:backend         # backend ESLint
bun run typecheck            # frontend; typecheck:backend, typecheck:packages, typecheck:electron for the rest
bun run check                # every lint, typecheck and test gate in sequence

# Test
bun run test                 # backend Vitest suite
bun run test:frontend        # frontend suite with live API contracts against a temporary database
bun run test:all             # backend + frontend suites

# Database
bun run db:migrate           # apply pending migrations
bun run db:status            # list applied and pending migrations
bun run db:new -- <name>     # create db/migrations/NNNN_<name>.sql
bun run db:codegen           # regenerate the Kysely database types

# API and locales
bun run generate:types       # regenerate apps/frontend/src/types/generated.ts from openapi.yaml
bun run check-endpoint-matrix # check docs/reference/api-endpoint-matrix.md against openapi.yaml
bun run validate-locales     # check en/nl key parity

# Package
bun run dist                 # build and package the Electron app

The full list, with what each script needs, is in docs/reference/scripts.md.

Configuration

The packaged app chooses its own database file and keeps its settings in a restricted runtime.env in its application-data directory. Do not set a database path for it.

For source development, copy .env.example to .env only when you need provider API keys or overrides. The template documents every optional setting (database file, logging, Ollama, AI web research, research providers). See docs/reference/environment-variables.md.

Contributing

  1. Create a branch from main.
  2. Write tests at stable boundaries: API contracts, real SQLite state, and pure domain functions (ADR-215).
  3. Run bun run lint, bun run lint:backend, bun run typecheck, and the relevant tests.
  4. Use Conventional Commits. main requires signed commits, linear history, and a passing CI Complete check.
  5. When you change an endpoint, update openapi.yaml, regenerate types, and update the endpoint matrix. When you change behaviour, update docs/.

See docs/guides/contributing.md and docs/guides/cicd-pipelines.md.

Coding agents

AGENTS.md is the shared guide for coding agents. Claude Code also gets edit-time checks, a read-only SQLite MCP server, a TypeScript navigation MCP server, and structural search with bun run search:ast (ADR-227, ADR-228).


Releases

Pushing a vX.Y.Z tag runs release.yml, which builds the Apple Silicon app and DMG and publishes a GitHub Release. It does not re-run the test suites: the tagged commit must be on main with a passing CI Complete check. It re-runs the secrets scan and dependency audits on the release tree before packaging.


Security and privacy

  • Your data stays in one SQLite file in Vision's data folder on your Mac. No database server listens on any port.
  • Never commit real .env files or secrets.
  • The Electron shell runs with context isolation and the sandbox on, and Node integration off.
  • Backups can be encrypted with AES-256-GCM (per-backup random salt).
  • Ollama runs locally by default. If you point it at a remote endpoint, that endpoint receives your prompts and tool results.

See docs/security/.


License

Licensed under AGPL-3.0-only. See LICENSE.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages