The Problem
Rotki aggregates crypto‑portfolio data across exchanges and blockchains while keeping the data encrypted and stored locally. Users who need a self‑hosted alternative to SaaS trackers face a code base that is split into six independent projects, each with its own language, build system and deployment model. The fragmentation makes it unclear how data flows from the UI to the database and which components hold the greatest operational risk.
What This Does
Rotki consists of six self‑contained repositories that together provide portfolio tracking, analytics and accounting.
- rotkehlchen (2172 files, 2071 code files, 91 data files) is the Python core that owns the main data model, accounting logic and PnL reports. It lives under
rotkehlchen/and is the primary source of truth for balances, transaction decoding and historical visualisations. - frontend (2140 files, 992 code files, 41 data files) is a Vue/React Electron application (
frontend/app/) that renders the UI, communicates with the back‑end via IPC handlers (frontend/app/electron/main/ipc-handlers/) and stores user preferences infrontend/app/.env. - colibri (36 files, 32 code files, 1 data file) is a Rust binary (
colibri/src/main.rs) that exposes a REST‑style API (colibri/src/api/), handles blockchain ABIs, coingecko price fetches and database operations (colibri/src/database/). It is the only component that directly touches the filesystem and external services. - tools (50 files, 38 code files, 2 data files) and packaging (6 files, 1 code file) contain build scripts, Docker helpers and release tooling.
- rotkehlchen_mock (2 files) and colibri’s minimal test fixtures are used for unit‑testing the core functions.
The data pipeline typically starts in the Electron renderer, sends a request through an IPC handler to the Rust backend, which then queries the Python rotkehlchen model via a subprocess or shared state, persists results to a local SQLite database and returns the payload to the UI.
How It Is Wired
Execution follows a small, well‑defined call graph:
- Entry points – the Electron main process (
frontend/app/electron/main/index.ts) starts the UI and registers IPC listeners; the Rust binary is launched viacolibri/src/main.rs. - IPC handling –
frontend/app/electron/main/ipc-handlers/forwards UI actions (e.g., “load portfolio”) to the Rust backend. - Rust API –
colibri/src/api.rsandcolibri/src/api/database.rsexpose endpoints that rotkehlchen calls; blockchain ABIs are stored undercolibri/src/blockchain/abis/. - Python core – rotkehlchen’s
rotkehlchen/package performs the actual accounting, PnL calculation and data‑export logic; it is invoked from the Rust side through asubprocesscall or an internal Python bridge. - External touch points – the Rust code contacts coingecko (
colibri/src/coingecko.rs), reads/writes the SQLite database (colibri/src/database/mod.rs) and, when needed, accesses the local filesystem for export files.
The hub is colibri/src/api.rs – every UI request passes through it, so changes to the API surface ripple across both the Rust and Python layers. The cycle exists between the Rust API and the Python model (subprocess round‑trip), which adds a small latency but isolates the core accounting logic.
How To Use It
| Step | Command (evidence from repo) |
|---|---|
| Clone | git clone https://github.com/moses-y/rotki (use verbatim URL) |
| Build Docker image | docker build -t rotki . (Dockerfile present at repo root) |
| Start container | docker run -p 8080:8080 rotki (Dockerfile exposes port 8080) |
| Install Node deps | cd frontend/app && npm install (package.json present) |
| Run Electron UI | npm run dev (script defined in frontend/app/package.json) |
| Run Rust backend | cargo run -p colibri (colibri/Cargo.toml is the package manifest) |
| Configure | Edit frontend/app/.env – this file contains secret‑shaped paths that the health audit flagged; do not commit it to version control. |
The Docker image bundles both the Rust binary and the Python environment, so a single docker run starts the full stack (UI + API + database). If only the backend is needed, cargo run -p colibri launches the API on http://127.0.0.1:8080.
Real‑World Use
A trader runs docker compose up (or the single‑container commands above) on a personal laptop. The UI opens at http://localhost:8080, where they add exchange API keys (stored encrypted in the local SQLite DB). rotkehlchen then fetches balances, decodes recent transactions, and presents profit/loss graphs. Because all data stays on‑device, the user avoids sending sensitive portfolio information to third‑party SaaS services.
Code Health & Issues
- Measured static‑analysis findings (deterministic, not opinion):
- 878 test files found across the six projects.
- 22 documentation files present.
- CI is active (GitHub Actions workflows under
.github/workflows/). - Dockerfile and lockfile (
colibri/Cargo.lock,frontend/app/package-lock.json) are committed. - License file
LICENSE.mdis present. - Committed secrets detected:
frontend/app/.envcontains secret‑shaped paths – the code‑health audit flags this as a low‑security issue.
- Dependency freshness (19 packages behind current major version):
electrondeclared40.1.0, current43.4.0(3 major behind)bignumber.jsdeclared9.3.1, current11.1.5(2 major behind)@types/nodedeclared24.10.10, current26.2.0(2 major behind)c8declared10.1.3, current12.0.0(2 major behind)typescriptdeclared5.9.3, current7.0.2(2 major behind)@vueuse/core,@vueuse/math,@vueuse/sharedeach declared13.9.0, current14.4.0(1 major behind)
These outdated declarations do not block operation but may expose known CVEs; updating them is recommended.
The Bottom Line
Rotki is a privacy‑first, self‑hosted portfolio manager built from six separate code bases—Rotkehlchen (Python core), a Vue/React Electron frontend, a Rust colibri backend, and smaller tooling projects. The architecture is clear: UI → IPC → Rust API → Python model → SQLite. Strengths include strong privacy guarantees, comprehensive test coverage and a solid CI pipeline. Weak points are the fragmented repository structure (requiring coordination across languages/build systems) and an outdated set of front‑end dependencies, plus a committed .env file that should be excluded from version control. It is well‑suited for teams or individuals who need full control over their crypto‑portfolio data and are comfortable maintaining a multi‑language stack.