Self-hosted service
ghostfolio/ghostfolio avatar
ghostfolio/ghostfolio

Ghostfolio: self-hosted portfolio tracking for stocks, ETFs and crypto

Open Source Wealth Management Software. Angular + NestJS + Prisma + Nx + TypeScript 🤍

9,388 stars1,343 forksTypeScriptAGPL-3.0

At a glance

What is it?
Ghostfolio is an AGPL-3.0 wealth management app built on Angular, NestJS, Prisma and Redis. It is aimed at people who hold assets across several brokers and want their portfolio data on their own infrastructure rather than in a broker's dashboard.
Who is it for?
Adopt Ghostfolio if you hold stocks, ETFs or crypto across several platforms, want a buy and hold view, and are willing to run PostgreSQL and Redis yourself. Do not adopt it as a brokerage, as a tax filing tool, or if you expect the repository to stay quiet for months at a time: releases 3.70.1, 3.71.0 and 3.72.0 all landed within the week before 2026-09-20, so a pinned image ages quickly.
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 last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

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

Editorial analysis

The spreadsheet problem Ghostfolio is built around

The README states the software is designed for personal use in continuous operation, and that sentence explains most of the design. A portfolio held across several brokers does not fit in one account view. Positions are bought on different dates, in different currencies, sometimes as fractional shares, and the broker statements arrive as CSV files with incompatible column names. The usual answer is a spreadsheet, and the usual failure is that the spreadsheet is only correct on the day it was last edited.

Ghostfolio targets the buy and hold investor rather than the active trader. Its own list of who it is for names people trading stocks, ETFs or cryptocurrencies on multiple platforms, people pursuing a buy and hold strategy, and people who value data ownership. The multi account management feature exists precisely because a single portfolio is spread over several custodians. Performance is reported as Return on Average Investment across fixed windows (Today, WTD, MTD, YTD, 1Y, 5Y, Max), which is a holding-period measure, not a trading signal.

The privacy angle is structural rather than a marketing line. When you self-host, transactions sit in your own PostgreSQL database. The project also ships a hosted Premium cloud offering, and the README is direct that this is the easiest way to start and will be the best option for most people, because it removes the operational work. That is an honest framing: the open source build and the paid build are the same application, and the money covers hosting, professional data providers and development.

Angular, NestJS, Prisma and Redis: how the pieces fit

The repository is an Nx workspace written in TypeScript, with the frontend and backend split into separate applications under apps/ and shared code under libs/. The backend is NestJS, PostgreSQL is the database, Prisma is the ORM and migration tool, and Redis handles caching. The frontend is Angular with Angular Material and Bootstrap utility classes.

That stack matters for two practical reasons. First, the database schema lives in prisma/schema.prisma, so migrations are versioned files applied with the Prisma CLI. Second, the environment file separates two connection URLs. DATABASE_URL is the connection the application uses and the README says to put the pooled connection URL there if you run a connection pooler. DIRECT_URL is optional, is used by the Prisma CLI for schema migrations and seeding, and bypasses poolers, falling back to DATABASE_URL when unset. Getting that pair wrong is the most common way a self-hosted deployment breaks during an upgrade rather than at first boot.

Redis is not optional in the compose setup: .env.example defines REDIS_HOST, REDIS_PORT and REDIS_PASSWORD alongside the Postgres variables. The cache sits in front of market data lookups, which is why the API key variables are named for a specific provider. API_KEY_COINGECKO_DEMO and API_KEY_COINGECKO_PRO are both optional, and the README does not state what happens to crypto pricing when neither is set. Treat that as an open question to test on your own instance rather than something the documentation answers.

The build itself is heavier than the runtime. The Dockerfile uses a multi-stage build on node:22-slim, installs g++, git, make, openssl and python3 in the builder stage, and runs npm run build:production with NX_DAEMON disabled. The final image only carries curl and openssl. If you build from source rather than pulling the published image, expect a long first build.

Installing Ghostfolio with Docker Compose

The README points self-hosters at the official container images on Docker Hub, published for linux/amd64, linux/arm/v7 and linux/arm64, and at the self-hosting FAQ page for common questions. The repository also carries a docker/ directory and a .env.example at the top level, which is the file the compose setup reads.

Start by copying the example environment file and filling in the placeholders. Every value below appears in .env.example; the angle-bracket entries are the ones you must replace with your own secrets.

Where Ghostfolio stops being the right tool

Ghostfolio is a tracker, not a broker and not an accountant. Nothing in the README describes order execution, tax lot reporting, dividend withholding reconciliation or regulatory reporting. If your requirement is a document your accountant can file, this is the wrong layer.

The import path is the sharpest edge. The README lists import and export transactions as a feature, but it does not document the accepted column schema, the date formats, or how duplicate rows are handled on a second import. That silence is the risk: a portfolio tracker is only as good as the history loaded into it, and a partial import produces performance figures that look plausible and are wrong. Anyone migrating years of statements should test the mapping on a small file first and compare the resulting transaction count against the source before importing everything.

The other boundary is operational. The application requires PostgreSQL and Redis, and the README describes it as designed for continuous operation. That means backups, upgrades and a database you are responsible for. The AGPL-3.0 licence is also worth reading before you expose an instance to other people: the licence's network clause applies to modified versions offered to users over a network, and nothing here is legal advice. Running it privately for yourself and running a modified public service are different situations.

Finally, the release cadence cuts both ways. Versions 3.70.1, 3.71.0 and 3.72.0 were published between 2026-09-14 and 2026-09-20, and the last push to the default branch was on 2026-09-21. That is a fast-moving project, which means fixes arrive quickly and so do schema migrations. Pin your image tag rather than tracking latest, and read the changelog before applying a migration to a database you care about.

Ghostfolio compared with Portfolio Performance and Actual Budget

The most common comparison is Portfolio Performance, a desktop application. The difference is architectural, not cosmetic. Portfolio Performance is a local program working on a file you keep on your machine; Ghostfolio is a client-server web application with a database, a cache and a browser frontend. The desktop model means no server to maintain and no Redis to run, but it also means no access from a phone browser and no Progressive Web App, which Ghostfolio explicitly ships with a mobile-first design.

Actual Budget sits at a different level entirely. It is envelope budgeting: you allocate income to categories and track spending against them. Ghostfolio does not model budgets or cash flow. It models securities transactions and computes portfolio performance and composition. If your question is where did my salary go, Actual Budget answers it and Ghostfolio does not. If your question is how did my ETF allocation drift over five years, the reverse is true.

The hosted Ghostfolio Premium option is the third path, and the README treats it as the default recommendation for most people. The trade is straightforward: you give up running your own PostgreSQL and Redis, and you accept that your transactions live on someone else's infrastructure. The self-hosting route exists for people who will not make that trade.

Upgrade cost and licence obligations

Upgrading a self-hosted instance is a database migration, not a file swap. The package scripts show the intended order: database:generate-typings runs prisma generate, database:migrate runs prisma migrate deploy, and database:push runs prisma db push. For a production instance the migration path is the one to use, and it needs DIRECT_URL or a DATABASE_URL that can reach the database without a pooler in the way.

The Dockerfile gives a clue about how much the maintainers care about reproducible builds. It copies package-lock.json into the dist directory specifically so the generated package.json does not pull different dependency versions, and it regenerates Prisma typings inside the image. That is a build designed to be deterministic, which helps you, but it does not remove the need to read CHANGELOG.md before each version bump.

On licensing: Ghostfolio is AGPL-3.0, stated in both the README badge and package.json. The practical implication for a private self-hosted instance run for yourself is minimal. The implication changes if you modify the code and let other people use it over a network, because that is the scenario the AGPL addresses. Review the licence text with someone qualified if that is your plan; this article is not legal advice.

Editorial conclusion

Adopt Ghostfolio if you hold stocks, ETFs or crypto across several platforms, want a buy and hold view, and are willing to run PostgreSQL and Redis yourself. Do not adopt it as a brokerage, as a tax filing tool, or if you expect the repository to stay quiet for months at a time: releases 3.70.1, 3.71.0 and 3.72.0 all landed within the week before 2026-09-20, so a pinned image ages quickly. Before committing, check that your broker's export columns map onto the import format, confirm whether you need API_KEY_COINGECKO_PRO for the crypto assets you hold, and read the AGPL-3.0 network clause against how you intend to expose the instance.

Frequently asked questions

How does Ghostfolio work?

It is a web application with an Angular frontend and a NestJS backend, storing transactions in PostgreSQL through Prisma and using Redis for caching. You record buys and sells across multiple accounts, and it computes portfolio composition and Return on Average Investment over fixed periods such as YTD, 1Y and Max.

How do I install Ghostfolio with Docker?

The README points self-hosters at the official container images on Docker Hub, published for linux/amd64, linux/arm/v7 and linux/arm64, and at the self-hosting FAQ page. The repository includes a docker/ directory and a .env.example that defines the PostgreSQL, Redis and secret variables the compose setup needs.

Is Ghostfolio free?

The source code is available under AGPL-3.0 and can be self-hosted at your own infrastructure cost. There is also a paid Ghostfolio Premium cloud offering, which the README describes as the easiest way to get started and the best option for most people because it removes the hosting and data-provider work.

Is Ghostfolio safe to use?

When you self-host, your transactions stay in your own PostgreSQL database, which is the data ownership argument the README makes. The README does not describe a security audit or certification, so the honest position is that safety depends on how you secure your own deployment and secrets.

Which is better, Wealthfolio or Ghostfolio?

Wealthfolio is not described in the README, so no comparison can be made from it. What can be said is that Ghostfolio is a client-server web application requiring PostgreSQL and Redis, whereas Portfolio Performance is a desktop application working on a local file, and Actual Budget solves budgeting rather than portfolio performance.

Official sources

  1. ghostfolio/ghostfolio on GitHub
  2. License: AGPL-3.0
  3. Project website
  4. README
  5. Releases
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/ghostfolio-ghostfolio.svg)](https://hysenlabs.com/projects/ghostfolio-ghostfolio)