Self-hosted, decentralized personal finance & accounting. You are the server.
Quick start · Download · Features · Screenshots · How it works · Docs · Roadmap
MIT OR Apache-2.0 · Rust 1.85+ · Tauri 2 · SQLite · offline-first
The shipped desktop app — Dashboard with net balance, monthly spend, budget remaining, locally-computed nudges, and recent activity. All screenshots show demo data (full tour).
| You are the server No SaaS backend, no aggregator in the middle. Everything runs on your machine or a box you control. |
Write-only secrets Bank & mailbox credentials live in your OS keychain. Set, rotate, revoke, use — never view. |
Share smarts, not data Community knowledge travels as signed classification packs — with noise-protected benchmark statistics designed on the same principle (not yet built). Never your transactions. |
SlipScan gives you what Vault22 / 22seven does for personal finance and what Xero does for small-business accounting — bank transactions, receipts, budgets, categorised spending, double-entry ledger, reconciliation, tax — with one fundamental difference: there is no central server. A Rust core over a plain SQLite file, wrapped in a Tauri desktop app. It is a standalone product: no account, no cloud, no telemetry, and it never depends on any hosted service.
It is also global by default: nothing country-specific is hardcoded — chart-of-accounts seeds, tax rates and return labels, bank CSV presets, and merchant packs all ship as region profiles (data you pick, contract). South Africa is the first region profile; a generic profile covers any country from day one.
Your data lives on your machine, your bank and mailbox credentials stay in your OS keychain, and the only thing the community shares is knowledge — signed classification packs today, with differentially-private benchmark statistics designed but not yet implemented — never data.
| 💰 Personal finance (Vault22 / 22seven class) | 📒 Accounting (Xero class) |
|---|---|
|
|
Infrastructure you can trust
- Get paid by reference (ShapePay) — watch an EFT reference code, and when the matching payment lands in your books (from any source) SlipScan fires an HMAC-signed webhook to endpoints you register. Signing secrets are vault-held and shown exactly once; payloads carry the reference and amount, never account numbers; deliveries retry until your box has network. Inbox in, webhook out, no central infrastructure (guide)
- Movable data folder, your own backup — your books and documents live in one folder you can see, relocate from Settings or
slipscan data move(verified copy + atomic switch), and back up by syncing it with your own cloud (iCloud / Dropbox / Syncthing / NAS). SlipScan ships no backup service, and the keychain key never travels with the folder (data & backup) - Ingestion from your own mailbox — always your accounts, never our infrastructure; generic IMAP polling works today, Gmail/Graph connectors and push are built but not yet wired to a surface
- Open-source, local bank-scraper framework — adapters run in your session, first adapters in progress (framework)
- Write-only credential vault rooted in the OS keychain — secrets can be set, rotated, revoked, and used, never viewed (threat model)
- Opt-in multi-currency FX via OpenRate — self-hosted, provenance-graded rates. Decimal-only rate math (floats never touch money), a local rate cache, and every conversion recording the exact rate, quality grade, and as-of age it used — surfaced on the CLI (
slipscan fx), the HTTP server, and the desktop Settings screen; converted report views are still landing (Phase 4.7). No endpoint configured means zero FX network calls (contract) - Headless self-host server mode for an always-on box (guide)
Note
Status: 0.2.0, under active development. The Rust core, CLI, extraction, ingestion, packs, and server crates are implemented; bank adapters, nudges/benchmarks, and device sync are tracked phase-by-phase in ROADMAP.md.
These are the shipped desktop app, running with demo data. The full annotated set — every screen, plus light mode — is in docs/SCREENSHOTS.md.
Installers for every desktop platform are on the latest release:
| Platform | Grab |
|---|---|
| macOS | .dmg |
| Windows | .msi or -setup.exe |
| Linux | .AppImage or .deb |
Standalone CLI binaries ship alongside the installers in the same release. Builds are unsigned for now — first launch: macOS right-click → Open; Windows SmartScreen → "More info" → "Run anyway".
Prerequisites (Rust stable, Node 20+, Tauri system deps) are listed in docs/GETTING-STARTED.md.
git clone https://github.com/vul-os/slipscan
cd slipscan
# Desktop app
cd apps/desktop && npm install && npm run tauri dev
# Core library + CLI (headless)
cargo build --workspace
cargo run -p slipscan-cli -- init --name "Personal" --kind personal
cargo run -p slipscan-cli -- --help # import, extract, mail-sync, recon, report, pack, vault, serve, listslipscan serve binds 127.0.0.1 unless you explicitly pass --lan — see docs/SELFHOST.md.
Everything runs on your machine. Sources feed one Rust core, the core owns a plain SQLite database holding your books, and the desktop app is a thin shell over the same services. The only network endpoints in the picture are ones you configured — your bank, your mailbox, your LLM provider, and (opt-in, for multi-currency) your own OpenRate instance for provenance-graded FX rates:
flowchart LR
subgraph machine["your machine"]
direction LR
subgraph sources["sources"]
bank["Bank scrapers<br/>(open-source, your session)"]
mail["Email inbound<br/>(your IMAP / Gmail / Graph / Proton)"]
files["Slips & files<br/>(import today; drag-drop & watch planned)"]
end
core["Rust core<br/>(slipscan-core services:<br/>categorise, budget, ledger, recon)"]
db[("SQLite<br/>your books, one file")]
app["Tauri desktop app<br/>(Svelte 5, thin IPC)"]
bank --> core
mail --> core
files --> core
core <--> db
app <-->|"IPC"| core
end
openrate["OpenRate<br/>(your self-hosted FX instance —<br/>opt-in, no URL = no FX calls)"]
openrate -.->|"rates + provenance,<br/>cached locally"| core
Between machines there is no hub — every node is a self-hosted peer. The only things that ever cross the network are signed packs (taxonomies and rules, verified with ed25519 on install) and, for users who opt in, differentially-private aggregates — category-level statistics noised on-device before they leave it. Aggregators are community-run and untrusted by design; transactions, merchants, and credentials never appear on any edge:
flowchart TB
a["Alice's node<br/>(desktop or self-host server)"]
b["Ben's node"]
c["Chris's node"]
m["Pack maintainer<br/>(any node, signs releases)"]
agg["Community aggregator<br/>(anyone can run one — untrusted)"]
a <-->|"signed packs<br/>(git / p2p)"| b
b <-->|"signed packs"| c
a <-->|"signed packs"| c
m -->|"signed classification &<br/>benchmark packs"| a
m --> b
a -.->|"opt-in: DP-noised aggregates,<br/>anonymous transport"| agg
c -.->|"opt-in"| agg
agg -->|"aggregate statistics"| m
Reading benchmark packs is perfectly private — comparison happens locally. Contributing is off by default, anonymous, and lossy by design: docs/BENCHMARKS.md.
Settings live in SQLite, secrets live in the OS keychain, and there is no required config file — the full model, data locations, and every setting key are in docs/CONFIGURATION.md.
| Document | What it covers |
|---|---|
| GETTING-STARTED.md | Clone to first book: build, import, capture a slip, connect a mailbox, pick an LLM provider |
| ARCHITECTURE.md | The binding contract: layout, tech decisions, domain model, vault spec, non-negotiables |
| CONFIGURATION.md | Settings model, data locations, environment |
| API.md | One service surface, two transports — Tauri IPC and the /api/v1 HTTP server |
| EMAIL.md | Email ingestion: IMAP IDLE, Gmail, Microsoft Graph, Proton Bridge — your accounts, no middleman |
| PAYMENTS.md | ShapePay: watch a payment reference, get a signed webhook when the EFT lands — setup, receiver verification, delivery and retry semantics |
| BANK-ADAPTERS.md | The local, open-source bank-scraper framework and how to write an adapter |
| PACKS.md | Signed classification packs: format, signing, verification, distribution |
| BENCHMARKS.md | Nudges and anonymous peer benchmarks: local DP, cohorts, honest limits |
| SELFHOST.md | Running the core headless on a NAS / home server |
| THREAT-MODEL.md | What protects your credentials, what an attacker gets, residual risks |
| SCREENSHOTS.md | Annotated tour of every screen in the shipped app |
| FAQ.md | Straight answers to the questions everyone asks |
Also: ROADMAP.md (phases, with honest partial-status notes; parity matrices are planned there but not yet written), SECURITY.md (vulnerability reporting), CHANGELOG.md.
# Rust workspace
cargo build --workspace
cargo test --workspace
cargo fmt --all -- --check
cargo clippy --workspace --all-targets
# Desktop app
cd apps/desktop
npm install
npm run check # svelte-check
npm run tauri dev # run against the real coreThe workspace denies unsafe_code; money is i64 minor units, never floats; secrets never appear in logs, Debug impls, or IPC responses. Read docs/ARCHITECTURE.md before changing anything structural — it is the contract.
Contributions are welcome — bank adapters, mailbox providers, and classification packs especially. See CONTRIBUTING.md, and docs/BANK-ADAPTERS.md for the adapter checklist.
MIT OR Apache-2.0 — © VulOS. SlipScan is a VulOS project; source and issues at github.com/vul-os/slipscan.
![]()
vulos — open by design







