Freenary is an open-source personal finance and wealth-management platform that you host yourself. It connects your banks, imports your accounts and transactions, categorises them, and shows you where your money goes. Your financial data stays in your own PostgreSQL database, with one exception: each question you ask the assistant sends financial data to the model endpoint the operator configured. See Assistant.
Freenary is under active development. The Budget area works end to end. Three areas — Portfolio, Analysis and Goals — appear in the sidebar with a Planned badge and hold no data yet.
- Your money sits in many bank apps, and no app shows the complete picture.
- A proprietary aggregator holds your financial data on its own servers.
- A spreadsheet needs manual work every month, and it goes stale.
Freenary puts the accounts, the transactions and the categories in one place that you control.
| Capability | State | Documentation |
|---|---|---|
| Connect a bank through one bank provider (Powens or Enable Banking) | Built | Bank connections |
| Import bank accounts, balances and transactions; import holdings with Powens | Built | Bank providers |
| Categorise transactions with deterministic rules and a merchant dictionary | Built | Categorisation |
| Budget: periods, cash flow, spending breakdown, fixed against variable, budget against actual, transaction list | Built | Budget |
| Budgeting profile and custom categories | Built | Categories and budget lines |
| Assistant on Home: ask about your money and read an answer from your own data, when the operator configures a model | Built | Assistant |
| Sign in with a password, an emailed one-time code, a passkey, Google, Apple or single sign-on, plus two-factor authentication | Built | Signing in |
| English and French interface, light and dark appearance | Built | Language and appearance |
| Programmatic access over RPC and OpenAPI | Built | API |
| Portfolio, Analysis, Goals | Planned | Introduction |
Freenary ships no Model Context Protocol server today. Read MCP and AI tools for the API path that replaces it.
| Item | Version | Note |
|---|---|---|
| Docker Engine and Docker Compose | Compose v2 or later | The install path: the stack runs published images |
| PostgreSQL | 18 | The Compose stack runs it for you |
| Bun | 1.3.14 | Only to build the images from source, or to develop |
| Bank provider account | — | Optional. Without one, Freenary runs and imports no bank data. |
| Email provider account | — | Optional. Without one, Freenary sends no one-time code. |
These commands give you a local instance from the published images. They need Docker and no source code:
curl -O https://raw.githubusercontent.com/suiramdev/freenary/main/docker-compose.yml
curl -O https://raw.githubusercontent.com/suiramdev/freenary/main/.env.exampleTo read the code as well, run git clone https://github.com/suiramdev/freenary.git and work in that directory instead: the same two files sit at its root.
Write the two required values into .env. docker compose up refuses to start while either one is empty:
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 16)
BETTER_AUTH_SECRET=$(openssl rand -hex 32)
EOF.env.example lists every other setting, with its default, in the same format.
Start the stack:
docker compose up -dThe migrate service applies the database migrations before the API server starts, on this up and on every later one. You run no migration command yourself.
Now check the two services:
curl http://localhost:3000/ # the API server answers: OK
curl -o /dev/null -w '%{http_code}\n' http://localhost:3001/ # the web app answers: 200Open http://localhost:3001 and create the first account. Then follow First steps.
The defaults reach localhost and nowhere else: PostgreSQL publishes on 127.0.0.1 only, and both public URLs point at the machine that runs the stack. Read Install with Docker Compose before you serve this instance to anybody else.
The complete documentation lives in apps/fumadocs. Run it with cd apps/fumadocs && bun run dev, then open http://localhost:4000.
| Section | Read it for |
|---|---|
| Introduction | What Freenary is, and what it does today |
| Concepts | The vocabulary the rest of the documentation uses |
| Using Freenary | Sign in, connect a bank, read the Budget area |
| Self-hosting | Install, configure, update, back up and monitor an instance |
| Configuration reference | Every environment variable, with its default |
| Troubleshooting | A symptom, its cause and its fix |
| Integrations | The API, the procedure reference and MCP |
| Development | Set up the code, run the checks, open a pull request |
| Architecture | Workspaces, request flow and build |
bun install
bun run dev:up # the containerised stack: PostgreSQL, migrations, API server, web app, docsdev:up needs OrbStack because the dev stack publishes no host port and reaches you through OrbStack hostnames. Without OrbStack, run the local path:
cp .env.example .env # `db:start` reads it: docker-compose.yml requires the two secrets
bun run db:start # PostgreSQL in a container
bun run db:push # apply the Prisma schema
bun run dev # web app on 3001, API server on 3000, docs on 4000Run the same checks as continuous integration before you open a pull request:
bun run check # Oxlint and Oxfmt through Ultracite
bun run check-types # TypeScript
bun run build # every appMore detail: Development and Local development stack.
Pull requests target the dev branch. main holds released code. Every push to either branch publishes ghcr.io/suiramdev/freenary-server and ghcr.io/suiramdev/freenary-web under that branch name, and a maintainer cuts a release with the Release workflow from main: it tags vX.Y.Z and publishes the same two images as X.Y.Z, X.Y, X and latest. FREENARY_VERSION in .env selects the tag your instance runs. Detail: Releasing.
freenary/
├── apps/
│ ├── web/ # web app (React, TanStack Start)
│ ├── server/ # API server (Elysia, oRPC)
│ └── fumadocs/ # documentation website
├── packages/
│ ├── api/ # procedures, bank providers, categorisation
│ ├── auth/ # Better Auth configuration and policy
│ ├── db/ # Prisma schema, migrations, client
│ ├── email/ # email adapters: log, Resend, SMTP
│ ├── env/ # environment-variable schemas
│ ├── ui/ # shared interface primitives
│ └── config/ # shared TypeScript configuration
Read .github/CONTRIBUTING.md first, then CONTEXT.md for the product vocabulary and AGENTS.md for the code standards. Every pull request uses the template.
- Report a problem or ask for a feature: GitHub issues.
- Read Troubleshooting before you open an issue about a deployment.
This repository does not include a license file yet. Open an issue if you need the reuse terms.