Whisper Money: a self-hosted Laravel and React budget tracker with a pluggable AI provider
Understand your personal finances. Forget Excels, try Whisper Money.
At a glance
- What is it?
- Whisper Money is an open source personal finance app built on Laravel 12 and React 19, distributed as a Docker Compose stack and installable through a `whispermoney` CLI. Its main design decision is that transaction categorization can run against a local Ollama model instead of a hosted API.
- Who is it for?
- Whisper Money fits someone who already runs Docker or Coolify, wants account and transaction tracking on their own hardware, and is willing to accept the licence terms. It does not fit anyone who needs automatic bank feeds, because the README describes account management and categorization but no aggregator integration, and it does not fit commercial resale because the licence is non-commercial.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The spreadsheet problem Whisper Money is aimed at
The pitch in the repository description is blunt: understand your personal finances, forget Excels. That places it against the manual spreadsheet workflow, where a person exports statements, pastes rows into a sheet, and assigns categories by hand every month. Whisper Money replaces that with a database-backed application: accounts, transactions, categories, and rules that assign categories automatically. The README lists bank account management, transaction categorization, automation rules and financial insights as the feature set.
The intended user is someone who wants that workflow without handing transaction history to a commercial aggregator. The README states the project does not sell data and does not profile users for ads, and the entire codebase is public. The topics list on the repository includes self-hosted and privacy, which matches the deployment story more than the feature story. If you are comfortable with Docker and want the categorization step automated, this is the target reader. If you want a hosted product with zero setup, the README also points at a demo account at whisper.money/login?demo=1, which is the honest way to evaluate it before installing anything.
Laravel 12 backend, Inertia frontend, MySQL and Redis underneath
The stack is conventional for a modern Laravel application. Backend is Laravel 12 on PHP 8.4. Frontend is React 19 with Inertia.js v3 and TypeScript, styled with Tailwind CSS v4. MySQL is the database and Redis handles cache and queue. Tests use Pest v4.
The presence of Redis as a queue backend is the detail that tells you how the automation works. Categorization and rule evaluation are not synchronous request work; they are queued jobs. That matters operationally, because a self-hosted install needs the queue worker running or transactions will sit uncategorized. The README's development command, `composer run dev`, makes this explicit by starting four things concurrently: the PHP development server behind a Portless HTTPS proxy, the queue worker, the Pail log viewer, and the Vite dev server. The queue worker is not optional infrastructure here.
The AI layer sits on `laravel/ai`, which the README links directly. Categorization and automation-rule suggestions are the two named AI features. The provider is configured separately from the model, which is the design choice that makes the local-model story possible: the same feature code can talk to Gemini, OpenAI, Anthropic, Azure, Groq, xAI, DeepSeek, Mistral, a self-hosted Ollama server, or any endpoint speaking the OpenAI API through the `openai-compatible` provider. The README does not describe the prompt, the category taxonomy, or what happens when the model returns something outside the expected set. That is a gap worth noting rather than glossing over.
Installing it: the setup script, the whispermoney CLI and the Docker path
There are three documented installation routes. The quick start is a single shell command that pipes a remote script into bash: `bash <(curl -fsSL https://whisper.money/setup.sh)`. After it finishes, the README says the app is reachable at https://whisper.money.localhost.
The manual route clones the repository and then runs `whispermoney install` from inside the checkout. The README carries an explicit warning about ordering: you must run `whispermoney install` before any other command, and skipping it means commands such as `start` will not work. Once installed, the CLI covers the lifecycle: `whispermoney start`, `whispermoney stop`, `whispermoney upgrade`, and a bare `whispermoney` for an interactive menu.
For production images, the documented path is to copy `.env.production.example` to `.env` and run `docker compose -f docker-compose.production.yml up -d`, which serves the app on port 8080. `APP_PORT` overrides that, for example `APP_PORT=3000 docker compose -f docker-compose.production.yml up -d`. Coolify users can paste the template from templates/coolify/whisper-money.yaml, which bundles the application container, MySQL 8.0 with health checks, persistent volumes, and auto-generated database credentials.
Configuration keys are where the deployment decisions live. `RESEND_API_KEY` is the only variable the README marks required, needed for password resets and notifications. `APP_KEY` and `APP_URL` are auto-configured, and the container generates an `APP_KEY` on first startup if one is not supplied. Optional keys include `DRIP_EMAILS_ENABLED` (default true), `REGISTRATION_ENABLED` (default true, set to false to make /register routes return 403 while /login stays open), `SUBSCRIPTIONS_ENABLED` (default false), the three Stripe keys, and `AI_PROVIDER`, which defaults to gemini. Each AI provider needs its own credentials, such as `GEMINI_API_KEY`, `OPENAI_API_KEY`, `ANTHROPIC_API_KEY`, or `OLLAMA_URL`. The README text is truncated mid-sentence at the point where it starts describing what happens with an unknown provider, so the failure behaviour for a misconfigured `AI_PROVIDER` is not documented in the material available.
Where the AI provider abstraction actually helps
The privacy claim in this project rests on one concrete mechanism rather than on policy language. Because `AI_PROVIDER` accepts `ollama` and the Ollama credentials are a URL, a self-hoster can keep categorization on their own network. The README calls Ollama the headline case for exactly this reason: data never leaves your infrastructure. That is a real architectural property, not a marketing position, and it is the strongest argument for choosing this project over a hosted budgeting app.
The same switch is generic, so the reverse also holds. If you want Gemini's quality and do not mind sending transaction descriptions to Google, you set `AI_PROVIDER=gemini` and supply `GEMINI_API_KEY`. If you already run an OpenAI-compatible gateway internally, the `openai-compatible` provider covers it. The separation of provider from model means you are not locked to one vendor's SDK shape in your configuration.
What the README does not tell you is how good local categorization is. There is no accuracy figure, no model recommendation, and no guidance on which Ollama model handles short merchant strings well. Anyone evaluating this for real use has to test that themselves against their own transaction descriptions. That is the honest state of the documentation.
No bank sync, and the licence is not what the badge suggests
The most consequential limitation is what the feature list does not contain. Bank account management means tracking accounts inside the app. There is no mention of an aggregator, no Plaid or GoCardless or similar integration, and no import format documented in the README excerpt. In practice that means transaction data has to arrive some other way, and the documentation does not say how. If your requirement is logging into your bank once and having everything appear, this is the wrong tool, and no amount of AI categorization fixes that.
The licence situation needs care. The repository metadata reports NOASSERTION, while the README carries a CC BY-NC 4.0 badge and links to that licence. CC BY-NC 4.0 is a content licence with a non-commercial restriction, which is an unusual fit for an application codebase and creates real ambiguity for anyone who wants to run it inside a business or offer it as a service. The repository metadata and the README badge disagree, and the material available does not resolve which governs. Treat the licence file in the repository as the thing to read before any commercial use, and get your own legal advice rather than relying on a badge.
The other limitation is operational. This is a multi-service deployment: MySQL, Redis, a queue worker, and the Laravel app, with email depending on a Resend key. The Coolify template bundles the database and volumes, but you are still responsible for backups, upgrades and the queue. `whispermoney upgrade` exists, but the README does not describe a rollback path or migration behaviour between releases. Releases have been landing roughly every two to three weeks based on the v0.2.8 through v0.2.10 dates, which is frequent enough that an unattended instance will drift.
How it compares to Firefly III
Firefly III is the obvious comparison point for a self-hosted personal finance application, and the difference is in the AI layer rather than in the accounting model. Firefly III is a mature double-entry bookkeeping system built on PHP with its own data importer, and it has historically relied on rule-based categorization and import tooling rather than on a language model. Its emphasis is on ledger correctness: accounts, journals, transfers, reconciliation.
Whisper Money takes a different route. It is a Laravel 12 and React 19 application built around Inertia, and its automation feature is model-driven categorization plus suggestions for automation rules, sitting on `laravel/ai` with a swappable provider. The trade is roughly this: Firefly III gives you a deeper accounting model and a separate importer project, while Whisper Money gives you a modern SPA frontend and an AI categorization path you can point at a local model. If your priority is bookkeeping rigour, Firefly III is the more established answer. If your priority is getting merchant strings categorized without writing regex rules, and you want that to happen on your own hardware, Whisper Money's provider configuration is the more direct fit. Neither README excerpt claims the other is unnecessary, and the choice comes down to whether you want a ledger or a categorizer.
Maintenance cost and what to verify before you commit
Running Whisper Money means operating four moving parts: MySQL, Redis, the queue worker, and the application container. The Coolify template handles the database and volume wiring, and the container generates an `APP_KEY` on first start, so the initial deployment is not the hard part. The recurring cost is the queue. If the worker stops, transactions stop being categorized and nothing in the README suggests a fallback or alert for that condition. Plan for it as a supervised process, not a background detail.
Upgrades are the second cost. `whispermoney upgrade` is the documented path, and releases are frequent, so an instance left alone for a few months will be several versions behind. The README does not describe database migration behaviour or whether downgrades are supported, which means backups before an upgrade are your own responsibility and not something the documentation walks you through.
Email is a hard dependency if you want password resets. `RESEND_API_KEY` is the only variable marked required, and it is tied to a specific provider. Substituting another mail service is not covered in the material available.
On licensing, the practical position is that the repository reports NOASSERTION and the README advertises CC BY-NC 4.0. Those are different claims with different consequences, and the non-commercial term in the latter would affect anyone running this for a business or as a paid service. Read the licence file in the repository and take your own advice on it. The relevant verification steps before adopting are narrow and concrete: run `whispermoney install`, confirm the queue worker is alive after `whispermoney start`, set `AI_PROVIDER=ollama` with a reachable `OLLAMA_URL` and check categorization output against your own transaction descriptions, and read the licence file rather than the badge.
Editorial conclusion
Whisper Money fits someone who already runs Docker or Coolify, wants account and transaction tracking on their own hardware, and is willing to accept the licence terms. It does not fit anyone who needs automatic bank feeds, because the README describes account management and categorization but no aggregator integration, and it does not fit commercial resale because the licence is non-commercial. Before committing, run `whispermoney install`, then check whether `AI_PROVIDER=ollama` with a reachable `OLLAMA_URL` gives categorization quality you accept, and read the actual licence file rather than the badge, since the repository reports NOASSERTION while the README links CC BY-NC 4.0.
Community notes