Self-hosted service
oss-apps/split-pro avatar
oss-apps/split-pro

SplitPro: a self-hosted Splitwise alternative for group expenses

Open source alternative to Splitwise

1,474 stars202 forksTypeScriptMIT

At a glance

What is it?
SplitPro is an MIT-licensed, self-hosted expense-sharing application built with TypeScript. It supports detailed balance calculations, multiple split methods, recurring expenses, currency conversion, and local receipt storage, but Splitwise expense import is incomplete.
Who is it for?
SplitPro fits groups that want to operate their own expense service, especially when local receipt storage, database-backed balances, or recurring expenses matter. It is a poor fit for users who require username and password login, complete Splitwise expense import, or guaranteed coverage from every exchange-rate provider.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days 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 October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

SplitPro's scope for shared expense tracking

SplitPro addresses the practical problem of recording expenses shared with friends and tracking who owes whom. It is intended as a self-hosted replacement for Splitwise rather than as a personal finance system with bank-account aggregation as its core purpose. Its primary audience is a group, household, or small community that wants control over its deployment, database, uploaded receipts, and account access.

An expense can involve one friend or a group. The application supports equal, percentage, share, exact, adjustment, and settlement splitting. Categories, currencies, dates, and receipt attachments can be associated with an expense, while balance views provide breakdowns by person and by group. Negative expenses cover refunds and corrections, which is important because recording a refund as a separate positive charge would distort the intended balance.

Groups are the main organizational unit. Invitees can be added by email or selected from existing friends. Optional debt simplification changes the presentation of group obligations, while the detailed balance view retains the underlying calculation. This distinction matters for groups that want a shorter settlement summary without losing visibility into how each balance was reached.

SplitPro supports data export from the balances view and account settings. Its Splitwise import is narrower: friends and groups can be imported, but expenses are not imported yet. A user expecting a complete migration from Splitwise still needs another process for historical expense records.

Database-backed balances and application architecture

The repository identifies Next.js, Prisma, PostgreSQL, tRPC, React Query, and TypeScript as central parts of the application stack. The Dockerfile builds the application with Node.js 22.16.0 and Alpine Linux 3.21. It produces a standalone Next.js deployment, copies Prisma migrations into the release image, and starts the server through `start.sh`.

Balance computation does not depend on a separately maintained balance ledger. According to the README, expenses are the source of truth and balances are computed on demand through database views. Edits and deletions therefore remain connected to the underlying expense records instead of requiring the application to reconcile two independent stores. The README also states that numeric values are stored in PostgreSQL as `BigInt`, without floating-point values, to preserve precision and avoid rounding errors.

The running system has background and scheduled components. Recurring expenses require PostgreSQL with the `pg_cron` extension. The production Compose example uses a prebuilt Postgres image containing that extension, while an externally managed PostgreSQL installation must have `pg_cron` enabled and adjusted appropriately. A non-superuser database role is supported when `pg_cron` is preinstalled. This is an infrastructure dependency rather than a timer implemented only inside the web process.

SplitPro is distributed as a PWA, with push notifications for new expenses and updates. Push delivery needs additional configuration. Receipt files are different again: they are stored on local disk and require a persistent uploads volume. The web application, database, scheduler, authentication provider, and receipt storage consequently form separate operational concerns.

Docker Compose installation and first account

The documented installation path is Docker Compose using `docker/prod/compose.yml`. Setup requires copying `.env.example` to `.env` and configuring authentication, the database, and uploads. The README does not print a literal copy or Compose startup command, so this tutorial does not invent one. Follow `docker/README.md` and `docs/CONFIGURATION.md` for the exact startup procedure associated with that Compose file.

The example environment defines the PostgreSQL container name, credentials, port, database name, and `DATABASE_URL`. It also defines the NextAuth secret and public URL. For a real deployment, replace the example database password and generate a new NextAuth secret. The `.env.example` file gives this command:

bash
openssl rand -base64 32

Place the generated value in `NEXTAUTH_SECRET`. Authentication must have at least one provider configured. SplitPro supports email magic links, Google OAuth, and OIDC providers such as Authentik, Keycloak, or a custom OIDC service. Username and password login is not supported.

After starting the Compose stack, open the configured application URL and create the first account. The `.env.example` file sets `DEFAULT_HOMEPAGE` to `/home`, while its comments note that `/balances` can be used instead. A deployment that closes public registration should configure signup and invite restrictions rather than assuming account creation is limited automatically.

Authentication, currencies, and bank transaction imports

SplitPro's identity design favors external authentication flows. NextAuth handles authentication, and the Prisma adapter appears in the application dependencies. Magic-link email requires working mail configuration, while OAuth and OIDC require correct public URLs, credentials, callbacks, and provider availability. Disabling signups and invites can restrict access to an existing user group, but those controls still need to be combined with a correctly configured provider.

Currency conversion is useful when group members record expenses in different currencies. The application can display balances in one selected currency, convert expense amounts, and convert group balances. However, the configured provider determines coverage, accuracy, and rate limits. The README does not promise identical conversion results across providers, so an adopter should treat historical exchange rates as provider-dependent data.

Bank integration is a separate optional path. According to the README, transactions can be loaded from providers such as Plaid and converted into expenses. That capability is an input mechanism for creating expenses, not a replacement for the core balance engine. The README identifies @alexanderwassbjer as the current maintainer of related bank integration issues, but it does not document provider credentials or setup steps. Those requirements belong in `docs/BANK_TRANSACTIONS.md`.

Splitwise import has another clear boundary. Friends and groups can be imported, but expenses cannot. This makes SplitPro useful for beginning a new shared ledger while importing relationships, not for completing an entire historical migration.

Local receipts and pg_cron deployment constraints

Receipt attachments are stored locally, so an operator must mount the uploads location to persistent storage. Otherwise, container replacement or redeployment could remove files that the application expects to remain available. The Dockerfile creates `/app/uploads` for a non-root container user, but the image alone does not make that directory persistent. Persistent volume configuration belongs in the deployment environment.

Recurring transactions introduce a second constraint. They require PostgreSQL with `pg_cron`, and `pg_cron` does not support cron ranges or lists. The accepted scheduling syntax is therefore narrower than some users may expect. If PostgreSQL is managed externally, the operator must confirm extension availability before enabling recurring expenses. The production Compose configuration offers a prebuilt Postgres image, which reduces setup work for a compatible self-hosted installation but does not remove the PostgreSQL requirement.

The application computes balances on demand using database views. The README says this approach is sufficient for self-hosted deployments, but it also asks users to report performance problems. That is not a capacity guarantee for every dataset, query pattern, or database configuration. Large groups, long histories, external database latency, and poorly tuned storage could produce different aggregation costs. A capacity-sensitive deployment would need to review its own database behavior rather than extrapolate from the general README statement.

Push notifications require additional configuration too. They are therefore a deployment decision rather than a capability that should be assumed to work after a basic Compose startup.

SplitPro compared with spliit.app and hosted services

The README names `spliit.app` as an open-source alternative considered by the project, but states that it is not a complete replacement and did not suit the author's workflow. The meaningful difference is therefore not merely that both applications divide shared expenses. SplitPro presents itself as a fuller replacement with group-oriented balances, multiple split methods, receipt attachments, recurring transactions, currency conversion, and an activity feed. Since the README does not provide a feature-by-feature comparison, it would be inaccurate to claim that SplitPro wins in every workflow.

A hosted Splitwise-style service removes the need for the customer to operate PostgreSQL, authentication, uploads, and upgrades, but its data and account controls are outside that customer's deployment. SplitPro gives the operator control over those components and permits hosting the application under the operator's own domain. That control carries responsibility for backups, secret management, database migrations, provider availability, and persistent storage.

The Docker image installs dependencies with `pnpm install --frozen-lockfile`, runs `pnpm build`, copies the standalone application and Prisma migrations, and starts the production server. Releases are also published as Docker images on DockerHub and GHCR, while building from source is recommended for the newest features. This creates a version choice between release images and source builds. Operators should verify the release tag, migration behavior, and persistence configuration rather than assuming that the latest image and source tree have identical operational requirements.

SplitPro maintenance, upgrades, and MIT licensing

The repository is not archived. Its last push was on 2026-10-14, and the listed releases include v2.1.6 on 2026-10-13, v2.1.5 on 2026-08-01, and v2.1.4 on 2026-06-21. These dates show recent repository activity, but the release list does not establish compatibility guarantees or a fixed maintenance policy for every deployment.

The application uses the MIT license. That license permits use, modification, and redistribution under its conditions, including preservation of the copyright and license notice. Operators still need to review dependencies separately because SplitPro's license does not automatically settle the obligations of every included package or external service.

Upgrading requires more than replacing the web container. The `start` script runs `pnpm prisma:prod` before starting Next.js, and the repository includes Prisma migrations. A deployment should account for schema migrations, environment changes, authentication settings, and receipt storage before updating the image. Rollback behavior is not documented in the README, so an operator should not assume that replacing a container tag with an older one will reverse database migrations.

Based on the repository layout, development includes Jest, Playwright, Prisma Studio, linting, and pnpm scripts. The `package.json` defines commands such as `pnpm dev`, `pnpm build`, `pnpm test`, `pnpm test:integration`, and `pnpm test:e2e`. These are relevant to contributors and operators validating a custom deployment, but the presence of test commands does not replace review of production configuration.

Editorial conclusion

SplitPro fits groups that want to operate their own expense service, especially when local receipt storage, database-backed balances, or recurring expenses matter. It is a poor fit for users who require username and password login, complete Splitwise expense import, or guaranteed coverage from every exchange-rate provider. Before adopting it, verify authentication, persistent upload storage, PostgreSQL compatibility, migration behavior, and each optional integration in the intended deployment.

Frequently asked questions

How do I install SplitPro?

The README directs self-hosted users to Docker Compose using `docker/prod/compose.yml`. Copy `.env.example` to `.env`, configure authentication, the database, and uploads, then consult `docker/README.md` and `docs/CONFIGURATION.md` for the complete setup steps.

Can SplitPro import expenses from Splitwise?

SplitPro supports partial Splitwise import for friends and groups, but the README says expenses themselves are not imported yet. Existing expense history requires a separate migration process.

Does SplitPro support recurring expenses?

Recurring expenses require PostgreSQL with the `pg_cron` extension. The documented Compose setup uses a prebuilt Postgres image containing `pg_cron`, and externally managed PostgreSQL requires the extension to be enabled and configured.

What authentication methods does SplitPro support?

SplitPro uses NextAuth and supports email magic links, Google OAuth, and OIDC providers such as Authentik or Keycloak. Username and password login is not supported.

Where are SplitPro receipts stored?

Receipt attachments are stored on local disk. Deployments must provide persistent uploads storage so files remain available across container replacement or redeployment.

Official sources

  1. License: MIT
  2. oss-apps/split-pro on GitHub
  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/oss-apps-split-pro.svg)](https://hysenlabs.com/projects/oss-apps-split-pro)

Was this useful?