Self-hosted service
budgetbee/budgetbee avatar
budgetbee/budgetbee

BudgetBee is a self-hosted personal finance manager you deploy with compose

BudgetBee is a finance self hosted app

647 stars27 forksJavaScriptMIT

At a glance

What is it?
BudgetBee is a Laravel and React personal finance application packaged as four Docker Compose services, with transaction tracking, per category budgets, multi user accounts and a REST API. Its own README warns against using it as your only record of finances until a stable 1.0 exists.
Who is it for?
BudgetBee suits a household that wants its financial data on its own hardware and is willing to run a MySQL database and a small stack of containers, and it is a good starting point for a developer who wants to extend a finance application with a familiar Laravel and React stack.
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 JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A finance app whose selling point is where the data lives

BudgetBee is described as an open source, self-hosted personal finance manager built around complete ownership of your financial data. The argument is structural rather than technical: instead of relying on a third party cloud service, the application runs on your own infrastructure through Docker, and the README states plainly that your data never leaves your server. The features it lists are the ones you would expect from a personal finance tool and a few that you would not. There is transaction tracking for income, expenses and transfers across multiple accounts, with customisable categories and sub categories, and budget management where you define a spending budget per category and watch progress in real time. Accounts and net worth cover checking, savings, cash and investments with an at a glance total. Upcoming expenses covers recurring and future bills, reports and charts cover spending patterns and category breakdowns, and multi user support gives family members or housemates separate accounts with their own data and settings. Multi currency, Excel and JSON import, and API access round it out.

Laravel, React and MySQL behind an nginx proxy

The tech stack table is short and conventional. The backend is Laravel in PHP, the frontend is React with Vite and Tailwind CSS, the database is MySQL or MariaDB, and deployment is Docker with Docker Compose. For a reviewer that combination says something useful. Laravel brings migrations, an ORM and an API layer out of the box, and React with Vite and Tailwind is a familiar front end stack, so a developer can extend either half without learning a framework from scratch. MySQL as the store is the one choice with a consequence: your financial records live in a relational database that you now have to back up, secure and upgrade yourself, and the roadmap confirms that the export and backup feature is still planned rather than shipped. The API is described as a REST API secured with API keys, which is the integration point for anything else in your household that wants to read or write your records.

Installation is one compose file with four services and a health check

The installation is a compose file you copy, fill in the environment variables for, and run with docker-compose up -d. The proxy and the API service look like this.

yaml
services:
  nginx:
    image: ghcr.io/budgetbee/budgetbee/proxy:latest
    command: nginx -g "daemon off;"
    ports:
      - "${APP_PORT}:80" # Port exposed on the host, e.g. 80 -> http://localhost
    depends_on:
      - webserver
      - web
    restart: unless-stopped
    networks:
      - skynet
  webserver:
    image: ghcr.io/budgetbee/budgetbee/api:latest
    working_dir: /var/www/html
    command: sh entrypoint.sh

The API service is configured with four database environment variables and waits for the database to report itself healthy before it starts.

yaml
    environment:
      DB_HOST: db
      DB_DATABASE: ${DB_DATABASE}   # Name of the MySQL database (e.g. budgetbee)
      DB_USERNAME: ${DB_USERNAME}   # MySQL user the app connects with (e.g. budgetbee)
      DB_PASSWORD: ${DB_PASSWORD}   # Password for the MySQL app user - use a strong value
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped
    volumes:
      - budgetbee_config:/config
    networks:
      - skynet
  web:

The front end container and the database follow, and the database carries the health check that the API depends on.

yaml
    image: ghcr.io/budgetbee/budgetbee/web:latest
    restart: unless-stopped
    networks:
      - skynet
  db:
    image: mysql:8.2.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} # MySQL root password - keep this secret
      MYSQL_DATABASE: ${DB_DATABASE}           # Must match DB_DATABASE above
      MYSQL_USER: ${DB_USERNAME}               # Must match DB_USERNAME above
      MYSQL_PASSWORD: ${DB_PASSWORD}           # Must match DB_PASSWORD above
    healthcheck:
      test: ["CMD", "/usr/bin/mysql", "--user=${DB_USERNAME}", "--password=${DB_PASSWORD}", "--execute", "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${DB_DATABASE}';"]
      timeout: 20s

The tail of the file sets the retry count, the persistent volumes and the shared network.

yaml
      retries: 100
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - skynet
networks:
  skynet:
volumes:
  budgetbee_config:
  db_data:

Two things to notice in that file. The database health check runs a real query against the information schema with a 20 second timeout and up to 100 retries, so a slow first start on a large disk is tolerated rather than fatal. And every application image is referenced by the latest tag, which means a docker-compose pull tomorrow can give you a different build than the one you tested.

The disclaimer tells you not to trust it with your only copy of the data

The README contains a disclaimer section with three points, and it is the most important paragraph in the document. The project is under very active development, bugs and breaking changes are expected, and the application should not be used as the only record of finances until a stable version 1.0.0 is released. That is a stronger statement than most hobby projects make, and it is worth taking at face value rather than reading as marketing modesty. A personal finance tool that a user trusts with years of records has a different failure profile from a todo list, and a schema change between releases can make an old database unreadable. The release list backs the warning up: v0.15.1 in September 2026, v0.16.1 a few weeks later, and v0.17 in October, with the last push on 2026-10-21. This is a project moving quickly towards a 1.0, which is exactly when the data format is least settled.

The roadmap separates what works today from what does not exist yet

The feature roadmap in the README marks each item as done or planned, and reading the planned column tells you where the gaps are. Import from Excel and JSON is done, as are multi user support, built in currency support, editing categories, budgets per category, the reports page and the upcoming expenses page. Custom currencies, meaning user defined currencies beyond the built in set, are planned, as are automation rules, bank integrations and export or backup. The bank integration entry is the one most people will miss, since without it every transaction is entered by hand, and it is the difference between a diary and a system. The export and backup entry is the one that matters operationally, because without a built in export the only way to get your records out of the application is to query the MySQL volume yourself, and the compose file stores that volume in a named Docker volume. A customisable dashboard is the last item shown, with its status cut off in the visible documentation.

First run creates the admin account, so the first visitor matters

Getting started is a short sequence. Once the containers are up, you open the application in a browser, and if no users exist yet you are redirected to a registration page where you create the first admin account with a name, an email and a password. After registering, you are redirected to the login page to sign in with those credentials. The pattern is the standard one for a self-hosted application, and it carries the standard risk. Because the first account to register becomes the administrator, the instance should not be exposed to the internet until you have created that account, and the compose file publishes the proxy through a host port that is worth mapping to something less obvious than 80 on a shared machine. The repository also ships an install.sh script at the top level alongside api, web and docker directories and a devcontainer configuration, and the CI badges show separate workflows for server tests and for building and pushing the Docker image, so the images in the registry are produced by the project rather than by hand.

Editorial conclusion

BudgetBee suits a household that wants its financial data on its own hardware and is willing to run a MySQL database and a small stack of containers, and it is a good starting point for a developer who wants to extend a finance application with a familiar Laravel and React stack. It is not suited to being the only record of your finances, which is exactly what the project itself says, nor to a deployment where tagged container images matter, because the compose file references the latest tag for all three application images. Verify three things before you import data: that you have a separate backup of the MySQL volume, since the export and backup feature is still marked as planned in the roadmap, that the API keys you hand out through the REST API are scoped the way you intend, and that the first admin account is created by you and not by the first visitor to your instance. The licence is MIT, the newest release is v0.17 from 2026-10-08, and the last push was on 2026-10-21.

Frequently asked questions

How do I install BudgetBee?

Through Docker Compose. You copy the compose snippet, fill in the environment variables for the MySQL root password, database name, user and password, and the host port, then run docker-compose up -d. The stack is four services, an nginx proxy, the Laravel API, the React front end and MySQL 8.2.0, sharing a network and two named volumes.

Is BudgetBee ready to use as my main financial record?

Not yet, according to the project itself. The README states that the project is under very active development, that bugs and breaking changes are expected, and that it should not be used as the only record of finances until a stable v1.0.0 is released.

Which features are not implemented in BudgetBee yet?

The roadmap marks custom currencies, automation rules, bank integrations and export or backup as planned rather than done. Import from Excel and JSON, multi user support, built in currencies, category editing, per category budgets, reports and the upcoming expenses page are listed as done.

Can other applications read my BudgetBee data?

Yes, through a REST API secured with API keys, and through import from Excel or JSON files for migrating existing records. The roadmap indicates that built in bank integrations, which would pull transactions in automatically, are still planned.

Official sources

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

Was this useful?