splitbon

splitbon

Docker app from cyborcc's Repository

Overview

Splitbon is an open-source, self-hosted Splitwise alternative with AI-powered receipt scanning. All-in-one container: PostgreSQL is bundled inside — no external database required. Features: - Group expense tracking with multiple split modes - AI receipt scanning: photograph a receipt, extract items, assign to friends - Claim sessions: share a receipt link so everyone claims their own items - Guest bill splitting with no account needed - Multi-currency expenses with automatic exchange-rate conversion - Venmo pay links (optional, admin toggle, USD only) - Pluggable AI providers: OpenAI, OpenAI-Codex (ChatGPT OAuth), Claude, Meridian (Claude Max), Ollama - Cross-group dashboard with debt simplification - 9 languages - PWA installable on mobile - Sign-in options: email/password, magic link email, and OIDC single sign-on (Authentik, Authelia, Keycloak, ...); a Google provider can also be configured, but the login page has no Google button This template runs the :stable image, which can lag the newest features described in the README.

Splitbon logo

Splitbon

Split trip costs with friends. On your own server.
Photograph a receipt, let AI read and translate it, tap who had what, settle up in one currency.

License: MIT GitHub stars Last commit Support on Ko-fi

Get started · What it does · Comparison · Screenshots · Docs

Scanning a receipt, assigning items to people    Adding an expense in another currency


Why Splitbon

You come back from a trip with a pile of receipts in three currencies and no wish to hand your spending history to a company. Splitbon is a small web app you host yourself (Docker, Unraid, any Linux box) that turns that pile into a short list of who pays whom.

  • Yours. Your server, your database, no ads, no daily limit on expenses.
  • Built for travel. Pay in any currency; every amount is also shown in the group currency, and the trip's currency is offered first.
  • Reads foreign receipts. A bill in Thai, Arabic or Japanese comes back in your language, with the shop name left as printed.
  • Fair to the cent. Assign single line items, or split equally, by amount, percentage or shares. Tax and tip are spread in proportion.
  • No lock-in. MIT licensed, plain PostgreSQL, full data export in the admin area.

Get started

Splitbon runs as one Docker container with PostgreSQL included.

git clone https://github.com/cyborcc/splitbon.git
cd splitbon/docker
cp ../.env.example .env

Open .env and set NEXTAUTH_SECRET and AUTH_SECRET (generate each with openssl rand -base64 32), then:

docker compose up -d --build

Splitbon is now running at http://localhost:3000. To scan receipts, connect an AI provider in .env or in the admin dashboard; see Configuration.

On Unraid

Add the template by hand (a Community Apps listing is in the works): paste

https://raw.githubusercontent.com/cyborcc/splitbon/main/unraid/splitbon.xml

into the template field of Docker → Add Container and fill in AUTH_SECRET and NEXTAUTH_SECRET. The template pulls ghcr.io/cyborcc/splitbon:stable; updates arrive through Check for Updates.

Backups, upgrades and prebuilt image tags are covered in Upgrading and backups.

What it does

🧾 Receipt scanning Photo in, line items out. Rescan with a correction hint, pick the model per receipt, review AI corrections before they are applied.
🌍 Multi-currency ECB exchange rates for the day of the expense, or enter your own. Receipts keep the rate with its source and date.
🙋 Everyone picks One tap asks the whole group: everyone gets a push, opens the receipt and ticks their own items, all at the same time.
🤝 Claim links Share a scanned receipt; everyone picks their own items, split dishes between people, join as a couple. No account needed for guests.
📍 Places & maps Add where you paid: OpenStreetMap search, GPS, places nearby, a mini map on every expense.
📊 Trip statistics Totals, categories, timeline, people, map, budget and a daily-cost forecast.
🔔 Notifications In-app bell plus web push when you are part of a new expense, a price or your share changes, or someone pays you back.
🗑️ Trash Deleted an expense by mistake? It stays in the group's trash for 30 days and can be restored with all its shares.
🔒 Private expenses Only the payer sees title and amount.
🧮 Settle up Debts are simplified to as few payments as possible; paying records the settlement. Optional Venmo links for US groups.
🌐 9 languages English, Spanish, Swedish, French, German, Portuguese (BR), Japanese, Chinese, Korean. Dark mode included.
🛠️ Admin & sign-in Users, groups, audit log, announcements, server logs, data export. Email/password, magic link, or SSO through Authentik, Keycloak and co.
📱 Installable Works as a PWA on your phone's home screen.
🧩 Pluggable AI OpenAI, ChatGPT subscription, Claude, Meridian (Claude subscription), Swisscom myAI, or local Ollama.

Splitbon also has a built-in How it works page with short videos, and a feedback page that turns a report into a prefilled GitHub issue.

How it compares

✅ yes · ⚠️ partly, paid, or needs setup · ❌ no · ➖ not documented

Splitbon Splitwise Tricount Splid Spliit SplitPro
Self-hosted ✅ ❌ ❌ ❌ ✅ ✅
Open source ✅ ❌ ❌ ❌ ✅ ✅
Free without limits ✅ ⚠️ ✅ ✅ ✅ ✅
AI receipt scan ✅ ⚠️ ➖ ➖ ⚠️ ➖
Translates receipts ✅ ➖ ➖ ➖ ➖ ➖
Several currencies ✅ ⚠️ ✅ ✅ ➖ ✅
Push notifications ✅ ➖ ➖ ➖ ➖ ✅
Native mobile app ❌ ✅ ✅ ✅ ❌ ❌

Splitwise's free plan has a daily expense limit and ads, and keeps receipt scanning and currency conversion in Pro. Spliit scans receipts only after you set up S3 storage and an OpenAI key. Splitbon, Spliit and SplitPro are web apps (installable as a PWA); the rest ship native apps.

If you just need to split one bill right now, a hosted app is quicker. If you want to keep the data, scan with your own AI key, or run it for friends and family at home, that is what Splitbon is for. The table follows each project's own site or README as of October 2026; these things change, so please check before deciding, and send a pull request if something is off.

See it in action

Dashboard
Dashboard
Add an expense
Add an expense
Split modes
Split modes
Settle up
Settle up
Guest split
Guest split, no account
Invite members
Invite by link
Create a group
Create a group
Group settings
Group settings
Dark mode
Dark mode
Language switcher
9 languages
Venmo pay links
Venmo links (optional)
Admin dashboard
Admin dashboard

Documentation

Guide What is in it
Configuration Every environment variable: AI providers, SSO/OIDC, magic link, SMTP, rate limits.
Upgrading and backups Backing up, updating, prebuilt image tags (stable / latest), database notes.
Development Tech stack, local setup, tests, how releases work.
Contributing Pull request guidelines and code style.
Security How to report a vulnerability.

Found a bug or have an idea? Open an issue, or use the feedback page inside the app.

Support

Splitbon is free and stays free. If it saved your trip budget, you can buy me a beer on Ko-fi 🍻, or just star the repo.

Credits and license

Splitbon grew out of ShareTab by sw-carlos-cristobal and contributors, and keeps its MIT license. On top of it come trip currencies, receipt translation, places and maps, statistics, notifications and more. Released under the MIT License.

Related apps

Details

Repository
ghcr.io/cyborcc/splitbon:stable
Last Updated2026-10-11
First Seen2026-10-11

Runtime arguments

Web UI
http://[IP]:[PORT:3000]
Network
bridge
Privileged
false
Extra Params
--restart=unless-stopped

Template configuration

Web UI PortPorttcp

Host port to expose Splitbon on

Target
3000
Default
3000
Value
3000
Database DataPath

Path to store PostgreSQL data (persists across restarts)

Target
/var/lib/postgresql/data
Default
/mnt/user/appdata/splitbon/db
Value
/mnt/user/appdata/splitbon/db
Receipt UploadsPath

Path to store uploaded receipt images

Target
/app/uploads
Default
/mnt/user/appdata/splitbon/uploads
Value
/mnt/user/appdata/splitbon/uploads
Claude Data (meridian)Path

Persistent storage for Claude login data used by the meridian AI provider. Optional unless meridian is in AI_PROVIDER_PRIORITY.

Target
/app/claude
Default
/mnt/user/appdata/splitbon/claude
Value
/mnt/user/appdata/splitbon/claude
ChatGPT OAuth Data (openai-codex)Path

Persistent storage for ChatGPT OAuth login data used by the openai-codex AI provider. Optional unless openai-codex is in AI_PROVIDER_PRIORITY.

Target
/app/chatgpt
Default
/mnt/user/appdata/splitbon/chatgpt
Value
/mnt/user/appdata/splitbon/chatgpt
NextAuth URLVariable

The URL where Splitbon is accessible (e.g., http://your-server-ip:3000). Split and personal links are copied from the browser address bar, not built from this, so open Splitbon at this URL before sharing one.

Target
NEXTAUTH_URL
Default
http://192.168.1.x:3000
Value
http://192.168.1.x:3000
Auth SecretVariable

Secret key for session encryption. Generate with: openssl rand -base64 32

Target
AUTH_SECRET
NextAuth SecretVariable

Same value as Auth Secret (required by NextAuth)

Target
NEXTAUTH_SECRET
Auth Trust HostVariable

Set to true when running on a local network or behind a reverse proxy

Target
AUTH_TRUST_HOST
Default
true
Value
true
DB PasswordVariable

Password for the bundled PostgreSQL user

Target
DB_PASSWORD
Default
sharetab
Value
sharetab
DB UserVariable

Username for the bundled PostgreSQL database

Target
DB_USER
Default
sharetab
Value
sharetab
DB NameVariable

Name of the bundled PostgreSQL database

Target
DB_NAME
Default
sharetab
Value
sharetab
AI Provider PriorityVariable

Comma-separated provider priority chain, for example: openai-codex,meridian,openai. Splitbon uses the first available provider and falls back to the next provider if extraction fails.

Target
AI_PROVIDER_PRIORITY
Default
openai
Value
openai
OpenAI API KeyVariable

API key for OpenAI (required when openai is in AI_PROVIDER_PRIORITY)

Target
OPENAI_API_KEY
OpenAI ModelVariable

OpenAI model for receipt scanning. Defaults to gpt-4o.

Target
OPENAI_MODEL
Default
gpt-4o
Value
gpt-4o
OpenAI Codex ModelVariable

Model for receipt scanning when openai-codex is in AI_PROVIDER_PRIORITY. Defaults to gpt-5.5.

Target
OPENAI_CODEX_MODEL
Default
gpt-5.5
Value
gpt-5.5
Anthropic API KeyVariable

API key for Claude (required when claude is in AI_PROVIDER_PRIORITY)

Target
ANTHROPIC_API_KEY
Anthropic ModelVariable

Claude model for receipt scanning (claude/meridian providers). Defaults to claude-sonnet-5. Options include claude-sonnet-5, claude-opus-5, claude-haiku-4-5

Target
ANTHROPIC_MODEL
Default
claude-sonnet-5
Value
claude-sonnet-5
Anthropic Health ModelVariable

Lightweight model used by the Meridian health poller to verify auth tokens. Defaults to Haiku to minimize token usage.

Target
ANTHROPIC_HEALTH_MODEL
Default
claude-haiku-4-5-20251001
Value
claude-haiku-4-5-20251001
Meridian PortVariable

Port for the embedded Meridian proxy (used when meridian is in AI_PROVIDER_PRIORITY). Change if port 3457 conflicts with another service.

Target
MERIDIAN_PORT
Default
3457
Value
3457
Ollama URLVariable

Ollama server URL (required when ollama is in AI_PROVIDER_PRIORITY)

Target
OLLAMA_BASE_URL
Default
http://192.168.1.x:11434
Value
http://192.168.1.x:11434
Ollama ModelVariable

Ollama vision model for receipt scanning

Target
OLLAMA_MODEL
Default
llava
Value
llava
Email SMTP HostVariable

SMTP server for outgoing emails. Used for magic link sign-in and OAuth auth expiry alerts (Meridian / ChatGPT OAuth). Leave blank to disable email sending.

Target
EMAIL_SERVER_HOST
Email SMTP PortVariable

SMTP port (465 for implicit TLS, 587 for STARTTLS)

Target
EMAIL_SERVER_PORT
Default
465
Value
465
Email SMTP UserVariable

SMTP username / email address

Target
EMAIL_SERVER_USER
Email SMTP PasswordVariable

SMTP password or app password

Target
EMAIL_SERVER_PASSWORD
Email FromVariable

From address for sent emails

Target
EMAIL_FROM
Google OAuth Client IDVariable

Google OAuth client ID (optional). The login page has no Google button, but sign-ins sent to the provider directly still work and create accounts for any Google user; see the README security notes.

Target
GOOGLE_CLIENT_ID
Google OAuth Client SecretVariable

Google OAuth client secret

Target
GOOGLE_CLIENT_SECRET
OIDC IssuerVariable

OIDC issuer URL (optional — enables SSO via Authentik, Authelia, Keycloak, ...). Must match the issuer in the IdP's .well-known/openid-configuration exactly (Authentik: trailing slash). Redirect URI: [NEXTAUTH_URL]/api/auth/callback/oidc

Target
OIDC_ISSUER
OIDC Client IDVariable

OIDC client ID

Target
OIDC_CLIENT_ID
OIDC Client SecretVariable

OIDC client secret

Target
OIDC_CLIENT_SECRET
OIDC Display NameVariable

Login button label: Sign in with [name]

Target
OIDC_DISPLAY_NAME
Default
SSO
OIDC Auto RegisterVariable

Create a Splitbon account the first time a new IdP user signs in (true/false)

Target
OIDC_AUTO_REGISTER
Default
true
OIDC Allow Email LinkingVariable

Link a first-time IdP login to an existing Splitbon user with the same email (true/false). Only enable if your IdP doesn't let users set arbitrary, unverified emails. Refused while anyone can sign up with a password (Registration Mode: Open).

Target
OIDC_ALLOW_EMAIL_LINKING
Default
false
OIDC Token Auth MethodVariable

How the client secret is sent to the token endpoint: client_secret_basic or client_secret_post

Target
OIDC_TOKEN_AUTH_METHOD
Default
client_secret_basic
Disable Password LoginVariable

Hide the email/password form and close registration (true/false). Ignored unless OIDC or magic link sign-in is configured. With SSO only, link existing accounts first or their owners cannot sign in.

Target
DISABLE_PASSWORD_LOGIN
Default
false
Disable Guest UploadsVariable

Lock guest (no account) receipt uploads and AI scans off, overriding the admin toggle (true/false). Signed-in users with an active account keep Quick Split, so also limit who can create an account: Registration Control only covers password sign-up; magic link, Google and OIDC auto-registration still create accounts.

Target
DISABLE_GUEST_UPLOADS
Default
false
Admin EmailVariable

Email address of the admin user. Grants access to the /admin dashboard for managing users, groups, and storage, and receives OAuth auth expiry alerts when email is configured. Leave blank to disable admin features.

Target
ADMIN_EMAIL
Login Rate LimitVariable

Max login attempts per email address per 15 minutes. Increase for testing.

Target
AUTH_RATE_LIMIT_MAX
Default
5
Value
5
Registration Rate LimitVariable

Max registration attempts per client IP per hour.

Target
REGISTER_RATE_LIMIT_MAX
Default
10
Value
10
Login Rate Limit per IPVariable

Max login attempts per client IP per 15 minutes. The client IP comes from the cf-connecting-ip, x-real-ip, or first x-forwarded-for header. Clients can forge these unless your reverse proxy overwrites all three; see the README Rate Limiting section.

Target
AUTH_IP_RATE_LIMIT_MAX
Default
30
Value
30
Guest Rate LimitVariable

Per client IP per hour, applied separately to guest receipt uploads, guest splits, and claim sessions.

Target
GUEST_RATE_LIMIT_MAX
Default
10
Value
10
Guest Upload Global LimitVariable

Max guest receipt uploads per hour across all guests combined.

Target
GUEST_UPLOAD_GLOBAL_LIMIT
Default
100
Value
100
Guest AI Scan Global LimitVariable

Max guest AI receipt scans per hour across all guests combined.

Target
GUEST_AI_GLOBAL_LIMIT
Default
100
Value
100
Max Upload Size (MB)Variable

Maximum receipt image upload size in megabytes

Target
MAX_UPLOAD_SIZE_MB
Default
10
Value
10
Log LevelVariable

Server log verbosity: debug | info | warn | error. Defaults to info.

Target
LOG_LEVEL
Default
info
Value
info