Self-hosted service
rotki/rotki avatar
rotki/rotki

The rotki Python package is called rotkehlchen and pins Python 3.14 exactly

A portfolio tracking, analytics, accounting and management application that protects your privacy.

4,091 stars790 forksPythonAGPL-3.0

At a glance

What is it?
rotki is a self-hosted crypto portfolio manager, accounting and analytics tool whose privacy claim is architectural rather than aspirational: the data stays encrypted on your machine, and the dependency list shows how. The repository is also three toolchains at once, a Python package, a Rust workspace of four crates and a Vue frontend.
Who is it for?
rotki fits you if you want portfolio tracking, transaction history and profit and loss reporting for crypto without handing your addresses to somebody else's server, and you are willing to run the thing yourself. Three things to decide before you start.
Can I use it commercially?
Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • rotki/rotki4,091 ★ · +129
Star history
Repository2026-07-282026-11-14
rotki/rotki4k4.1k

129 Stars in the last 109 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The package is rotkehlchen, and Python 3.14 is not a suggestion

The project is called rotki and the Python distribution is called rotkehlchen, which is the first thing to reconcile when you read pyproject.toml. The build backend is setuptools with setuptools-scm for the version and wheel, and the version field is dynamic rather than written into the file. The interesting line is requires-python, which is pinned to ==3.14.*, so anything but a 3.14 interpreter is refused at install time rather than warned about at runtime. The readme's requirements list agrees: Node.js, npm, Python 3.14, uv and Docker, with uv as the Python package manager. One oddity worth knowing: the project classifiers still say Development Status :: 1 - Planning, which is a packaging metadata field left over from long ago and says nothing about the release history, where the recent tags are 1.43.2, 1.44.0 and 1.44.1.

Local encryption is a vendored SQLCipher build, not a promise

The overview claims that rotki keeps your data encrypted and stored locally, and the dependency list is where you can see what that means in practice. Two of the pinned dependencies are rotki's own forks: rotki-pysqlcipher3 at 2026.8.3, which is the Python binding for SQLCipher, an encrypted SQLite, and rotki-sqlite at 2026.07.2, which is the SQLite build that binding sits on. So the at-rest encryption is not a setting you toggle on top of a stock database; it is the database driver itself, maintained by the same people who ship the application. That is also why py-machineid is in the list, since a machine identifier is the kind of thing an encrypted local store still needs, and it is why the readme's contrast with closed-source SaaS competitors reads as an architectural claim rather than a marketing one.

A Rust workspace of four crates sits inside the Python project

The tree has Cargo.toml and Cargo.lock next to pyproject.toml and uv.lock, because rotki is two languages in one build. The Rust workspace declares four members: colibri, crates/starling, crates/starling-core and crates/starling-proxy, and excludes tools/find-duplicate-constants. The workspace inherits a single version, 1.44.1, which a comment says is kept in lockstep with the rotki release version by tools/scripts/bump.sh, with every member taking it through version.workspace = true so the bump has one place to touch. The Rust edition is 2021 and the minimum is 1.86.0, the licence field reads AGPL-3.0-only, and the release profile strips symbols and uses thin LTO. What the crates are for is not spelled out in the manifests; the dependency set, with tokio, axum, tower and tower-http, reads like a server and a proxy rather than a numerical library.

Every dependency is pinned with an equals sign

Both manifests pin exactly, and the Rust one says why in a comment: reproducible builds, and a dependency bump is always a deliberate reviewable diff rather than something that drifts in on the next lockfile refresh. On the Python side every dependency is an exact version too, from web3 at 7.16.0 and eth-typing at 5.2.1 through gql at 3.5.2 and scalecodec at 1.2.11, and one dependency is not a version at all but a git URL pinned to a commit, the substrate-interface from rotki's own py-polkadot-sdk fork. Three of the Python pins carry comments explaining a constraint that cost somebody time: cryptography at 48.0.1 because newer releases dropped x86_64 macOS wheels whose source builds conflict with the libssl PyInstaller bundles, and cytoolz at 1.1.0 because 1.0.1's native extension re-enables the GIL under Python 3.14t. Those comments are the most useful documentation in the file.

The Docker build is three stages, node then rust then python

The Dockerfile is a three-stage build and the stage order tells you what the application is. The frontend stage starts from node:24.20.0-bookworm with the Cypress binary download switched off and the node heap capped at 4096 MB, copies only frontend/, enables corepack and installs with pnpm using a frozen lockfile and a cached store, then runs pnpm run docker:build. The Rust stage starts from rust:1.91-bookworm, copies the manifests plus colibri/ and crates/, and builds both shipped binaries, colibri and starling, in one cargo invocation so they reuse common artifacts, keeping the registry and target caches because they hold an expensive vendored OpenSSL and SQLCipher build. The Python stage starts from python:3.14-bookworm and copies uv in from the astral-sh image, and the comment there explains that the non-amd64 PyInstaller bootloader is built from source.

The lint target runs four linters, two of them in parallel

The Makefile is short and its lint target is the interesting part, because it coordinates four type and style checkers plus three project-specific scripts. ruff runs over the application, the mock package, package.py and the docs config, then double-indent runs in dry-run mode, then a shell script under tools/find-duplicate-constants. mypy runs with --install-types --non-interactive, which means a lint pass can install type stubs rather than failing on a missing one. pyright and pylint then run at the same time, in background jobs with their exit statuses collected and combined, and the target fails if either does. Only after that do the project rules run, as python tools/lint_checksum_addresses.py and python tools/lint_new_logging_fstrings.py. The test targets are uv wrappers around pytest, and the cassette one is worth noting:

sh
RECORD_CASSETTES=true uv run pytest -m vcr rotkehlchen/tests

That is how the network-dependent tests are re-recorded.

The AGPL is the pitch, and there is a commercial licence behind it

rotki is distributed under the AGPLv3 Licence, with the text in LICENSE.md on the develop branch and the Rust workspace repeating it as AGPL-3.0-only. The readme then spends a paragraph on the cases where that licence gets in the way: if your intended use of rotki or parts of it would trigger AGPL obligations, for example embedding it in a proprietary product, redistributing it as part of a commercial offering, or offering a hosted or SaaS version, a commercial licence can be offered instead, and inquiries go to [email protected]. That paragraph is the honest version of a licensing story, and it pairs with the donation section, which gives a Bitcoin address and rotki.eth for people who would rather not buy a subscription. For advanced features the readme points at a Pro version and an integrations page, so the free tier and the paid tier are separate from the licence question.

Releases are named after birds, and the default branch is develop

Two things about the release process are worth reading off the repository before you clone it. The recent tags are v1.44.1 Cleaned Eyestripe, v1.44.0 Eyestripe and v1.43.2 Pristine Emargination, so the release names are bird names and the version numbers are ordinary semver ones, which makes a changelog easy to follow and a tag easy to parse. And the default branch is develop, not master, while several of the readme's own badges still point at commit/master URLs, so a badge and the branch you clone can disagree. Alongside that, .bumpversion.cfg records the version bump that has to stay in step across the Python package, the Cargo workspace and the release notes, and releases_sponsors.md is a file whose existence suggests release sponsorship is tracked per release.

Editorial conclusion

rotki fits you if you want portfolio tracking, transaction history and profit and loss reporting for crypto without handing your addresses to somebody else's server, and you are willing to run the thing yourself. Three things to decide before you start. The privacy model is a real one, a locally encrypted database through rotki's own pysqlcipher3 build rather than a policy promise, but that also means the data is yours to back up and yours to lose. The AGPLv3 licence is the second decision, and the readme is unusually direct about it: uses that would trigger AGPL obligations, including embedding in a proprietary product or offering a hosted version, are directed to a commercial licence at [email protected]. Third, the toolchain is demanding, with Node.js, npm, Python 3.14, uv and Docker all named as requirements, a package that pins requires-python to exactly 3.14, and a Rust workspace requiring 1.86. Check what your data export path looks like before you commit, because the readme points to a documentation site and an issue tracker rather than describing a backup format.

Frequently asked questions

What do I need to install rotki?

The readme names Node.js, npm, Python 3.14, uv and Docker. The Python package itself pins requires-python to exactly 3.14, and rotki supports Windows, macOS and Linux, with pre-packaged binaries as the recommended route and a build-from-source path for developers.

How is rotki different from other crypto portfolio trackers?

The overview contrasts it with closed-source SaaS platforms that require you to hand over sensitive financial data. rotki is open source and self-hosted, keeps your data encrypted and stored locally, and ships under the AGPLv3 Licence.

Is rotki free to use?

rotki is open source and distributed under the AGPLv3 Licence. If your use would trigger AGPL obligations, such as embedding it in a proprietary product or offering a hosted version, a commercial licence can be offered instead, with inquiries to [email protected]. Donations in BTC and ETH are also accepted.

What can rotki track and report?

Balances across multiple platforms, blockchains and exchanges, historical data visualization, a readable breakdown of blockchain transactions and exchange events, customization of the interface, main currency and language, and profit and loss reports using customizable accounting settings.

How do I get help with rotki?

Support and discussion run through the project's Discord server and GitHub Discussions, with GitHub issues for bugs. The readme also points at the documentation site and a usage guide, and contributions start with CONTRIBUTING.md, the developer guide and the open issues.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rotki-rotki.svg)](https://hysenlabs.com/projects/rotki-rotki)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/rotki-rotki.svg)](https://hysenlabs.com/projects/rotki-rotki)

Was this useful?