Every cost its own rule
Fixed quota or proportional to income — chosen per item, never assumed. The household default only pre-fills the form.
Two incomes, one household, one clear plan.
The household planner for people who share costs unevenly — and want the maths to be right. Rent by income, electricity down the middle, the gym only one of you uses. Every item gets its own rule, and both of you see what it costs while you type.
The problem
Splitting apps assume one rule for everything. Spreadsheets can express it — until one cell slips and the formula is quietly wrong for months. KassenKnoten makes the split a deliberate choice per item, computes it to the cent, and shows you the result while you type.
Fixed quota or proportional to income — chosen per item, never assumed. The household default only pre-fills the form.
Amounts are whole cents, shares are basis points. 39,99 € down the middle becomes 20,00 € and 19,99 € — never 39,98 €. The calculation engine is a pure, tested module.
Every entry carries the months it applies to. A raise in September leaves August reporting August — and the app asks whether a change is new from now on or was always true.
Groceries, fuel, going out: either the plan counts — or every receipt with its date, and the plan becomes the budget you measure against.
Photograph it and the total, the date and the shop are filled in. Read on your own server — the photo is never uploaded anywhere and never stored.
Twelve months in one chart. Drag along it and each month's income, costs, savings and free cash follow — no navigation, no page load.
A 132,00 € yearly insurance sits next to everything else as 11,00 € a month. Nobody divides by twelve in their head again.
Savings pots with a monthly rate, a balance and an optional target — owned by one person or by the household.
Negative free cash, a savings rate above income, an overspent budget — as a calm banner, not a modal. Deleting offers “Undo” instead of asking “are you sure?”.
A household password with an optional one-time code, Authentik or any other OpenID Connect provider — or both, switched in the settings.
Own icon on the home screen, opens without an address bar. Browsers that cannot install a web app are told where the option lives in their own menu.
Chosen when you set up and changed whenever you like. The language belongs to the household, not to a browser — the tablet in the kitchen speaks the same one as the laptop.
Upload an extension and it contributes cards to the overview. It runs on your server with full access — install only what you have read, or what comes from someone you trust.
One SQLite file on a volume you control. The server keeps the last fourteen states of your data beside it — download one, restore it in one step.
Shared fixed costs
Every shared item shows both shares in euros and percent, and which rule produced them. The split is previewed as you type, by the same function that later saves it — a preview that calculates a second way is a preview that can disagree with the result.
Month by month
Every entry knows the months it applies to, so every month can be shown as it really was. The overview draws the last twelve — drag along the chart, or use the arrow keys, and that month's figures follow.
Variable costs
Anything that is not the same every month gets a budget — and you decide per budget how it is kept. Plan counts the figure you set and asks nothing more. Detailed counts what was actually booked, every expense with its date.
Receipts
Scan receipt opens the camera, and the total, the date and the shop come back filled in. The one question left is which budget it belongs to — the budget carries the split, so that stays your decision.
Savings
Pots with a rate, a balance and an optional target. Progress is a bar rather than mental arithmetic — and when a pot passes its target, the overview says so kindly.
Settings
Language and appearance, the default split and categories, sign-in, backups and extensions — each on its own page, all listed on one overview. On a wide screen the list stays beside you.
On a phone
A household plan gets opened in the kitchen, not at a desk. Same features, navigation within thumb reach, an amount field that brings up the number pad, and a design that follows the system theme.
Security
One household password, hashed with argon2id and read from the environment — a copy of the database is not a copy of the password. Optionally a code from any authenticator app (TOTP, RFC 6238). A code that has been used is refused.
OpenID Connect with PKCE, the ID token checked against the provider's keys, and only addresses on an allowlist kept in the app get in. Taking someone off the list ends their session on the next click.
The session cookie is encrypted, not merely signed (JWE, A256GCM), httpOnly, SameSite=Lax and Secure over HTTPS.
Every route but the login and the health check requires a session — deny by default, so a new page cannot accidentally be public. Server actions check again themselves.
A Content-Security-Policy with a per-request nonce, self-hosted fonts, no CDNs, no telemetry. The container runs as an unprivileged user.
No image is published before the tests pass and a real browser has signed in, set up a household and checked a split on the phone layout — against the very server the image runs.
Self-hosting
No checkout, no Node, no build. The image is published for amd64 and arm64 and runs wherever Docker runs Linux containers: a Linux server or NAS, a Raspberry Pi 4 or 5 with a 64-bit OS, a Mac, or Windows with Docker Desktop. Both images are started and tested in a browser before every release. Download two files, generate the secrets — the scripts for that run inside the image — and start.
Linux and macOS
mkdir kassenknoten && cd kassenknoten
curl -LO https://github.com/jankln/KassenKnoten/releases/latest/download/docker-compose.yml
curl -L -o .env https://github.com/jankln/KassenKnoten/releases/latest/download/env.example
# a session secret, appended to .env
docker run --rm ghcr.io/jankln/kassenknoten:latest \
node scripts/session-secret.ts >> .env
# your household password, hashed — paste the printed line into .env
docker run -it --rm ghcr.io/jankln/kassenknoten:latest \
node scripts/hash-password.ts
# optional: a second factor, prints a QR code into your terminal
docker run -it --rm ghcr.io/jankln/kassenknoten:latest \
node scripts/totp-secret.ts
# optional: sign in with Authentik — fill in the OIDC_* lines of .env
docker compose up -d
Windows · PowerShell
mkdir kassenknoten; cd kassenknoten
curl.exe -LO https://github.com/jankln/KassenKnoten/releases/latest/download/docker-compose.yml
curl.exe -L -o .env https://github.com/jankln/KassenKnoten/releases/latest/download/env.example
# a session secret, appended to .env
docker run --rm ghcr.io/jankln/kassenknoten:latest `
node scripts/session-secret.ts | Add-Content .env
# your household password, hashed — paste the printed line into .env (notepad .env)
docker run -it --rm ghcr.io/jankln/kassenknoten:latest `
node scripts/hash-password.ts
docker compose up -d
Windows needs Docker Desktop with WSL 2. Then open http://127.0.0.1:3000 — a three-step wizard sets up the household. For access from outside the machine, put a reverse proxy with TLS in front.