A self-hosted, multi-user spendings & incomes tracker built for groups who actually split things β roommates, couples, travel crews, small teams.
π Quick Start Β· β¨ Features Β· π¦ Install Β· π οΈ Stack Β· π API Docs Β· π€ Contributing
Ever tried to split a trip with 4 friends using a spreadsheet? Painful. Tried a SaaS tracker that suddenly wants $9/mo and owns your data? Worse.
Gift is the middle path: spin it up on your own box, invite your people, and start tracking. No subscriptions, no data sharing, no surprises. Cross-platform binaries for Linux, macOS and Windows β amd64 and arm64 β built on every tag.
π‘ Self-host in 5 minutes. Invite your crew in 5 seconds. Track forever.
Create a group for anything you split: "Bali 2026", "Apartment 3B", "Sunday poker". Invite users, track shared expenses against it, see who's contributing what.
- Create / rename / delete groups
- Owner-managed membership β invite by user search, remove members anytime
- A spending can be personal or group-scoped β one unified API, one unified feed
- Query "groups I own" vs "groups I'm a member of" independently
Log expenses with the fields that actually matter.
| Field | Notes |
|---|---|
amount |
Decimal, any precision |
currency |
Multi-currency ready |
category |
Free-form, powers the donut chart |
description |
Because "Starbucks $14" deserves context |
date |
Time-range queries supported |
group_id |
Optional β omit for personal spending |
Filter by user, group, category, date range with pagination (limit / offset) baked into the API.
Salary, freelance, dividends, a tip jar β log it, see it, net it against spendings.
- Budgets β cap spending per category / group / period
- Goals β "Save $3k for Bali by August" β progress-tracked
- Alerts β opinionated nudges when things go sideways
- First thing the web app asks: "Where's your server?" Point it at
localhost, a Tailscale IP, a domain β whatever. No hardcoded backend. One frontend build can talk to any Gift instance.
- mise (handles Go, Node, air, swag, etc. automatically)
- MongoDB running somewhere reachable β local, Atlas, or a container:
docker run -d --name gift-mongo -p 27017:27017 mongo:latest
git clone https://github.com/aslon1213/gift.git
cd gift
mise install # pulls Go 1.26, Node 25, air, swag, goreleaser, golangci-lintβ¦Create server/.env:
DB_URL=mongodb://localhost:27017
DB_AUTH=false
AUTH_JWT_SECRET=change-me-to-a-long-random-string
AUTH_JWT_REFRESH_SECRET=change-me-too
AUTH_JWT_EXPIRES_IN=15m
AUTH_JWT_REFRESH_EXPIRES_IN=720hOpen two terminals:
# Terminal 1 β API on :3000 (hot-reloading)
mise run api:dev# Terminal 2 β Vue dev server on :5173 (proxies /api β :3000)
mise run web:devOpen http://localhost:5173, point the server setup at http://localhost:3000, register your first user β you're now the admin of your own finance tracker. π
# Pick your platform from the releases page
curl -L -o gift-api.tar.gz \
https://github.com/aslon1213/gift/releases/latest/download/gift-api_<VERSION>_Linux_x86_64.tar.gz
tar -xzf gift-api.tar.gz
./gift-apiReleases include:
gift-api_*β server binary for Linux / macOS / Windows,amd64+arm64gift-web_*β static frontend bundle (serve with Nginx, Caddy, S3, anywhere)docs/swagger.json+docs/swagger.yamlβ OpenAPI specgift_*_checksums.txtβ SHA256 sums
docker build -f deployment/Dockerfile.server -t gift-api .
docker build -f deployment/Dockerfile.web -t gift-web .mise run api:build # β server/bin/api_gateway
cd client/gift-web && npm ci && npm run build # β client/gift-web/distPRs welcome
- Fork + branch
mise install && mise run api:devβ make sure it runs locally- Install pre-commit hooks:
pre-commit install - Open a PR with a clear description
Found a bug? Open an issue.
Built with β, Go, and a healthy suspicion of subscription finance apps.
β Star the repo if Gift saved you from a spreadsheet.



