A private, offline-first money manager with an AI finance assistant, asset & net-worth tracking, budgets, savings goals, debt splitting, and Splitwise import β built with Next.js 16, React 19 & TypeScript.
Own your money data. No ads, no data-selling, no bank connections, no third-party cloud. Self-host your own instance β you sign in to your server, your data lives in your browser first, and sync (optional) goes only to your own database.
Features Β· Why Ledgerly Β· Quick Start Β· AI Assistant Β· Deploy Β· FAQ Β· Keywords
TL;DR β Ledgerly is a free, open-source, self-hostable expense tracker and budgeting app (a privacy-first Mint / YNAB / Splitwise alternative) that runs 100% offline as a PWA. It tracks income, expenses, budgets, savings goals, assets & net worth (gold, silver, stocks, crypto, property, cash with live price rates), and who owes whom. It can import your Splitwise history, read receipts and PDF statements, and includes a built-in AI finance assistant you can chat with to add transactions and answer money questions in plain English.
- Dashboard β net balance, savings rate, cash-flow trend, spending breakdown, budgets, debts, and savings goals for any month, at a glance.
- Income & Expense tracking β fast quick-add, per-ledger views, categories, payment methods, notes, and trends.
- Transactions ledger β searchable & filterable (text, type, category, method, amount, date range) with inline edit/delete + undo, virtualized for thousands of records.
- Categories β create, recolor, re-icon, archive, and safely delete with transaction reassignment.
- Budgets β monthly overall & per-category limits with live progress and near-/over-limit warnings.
- Savings goals β set targets, log contributions/withdrawals, and watch each goal fill up.
- Multi-currency β pick your currency; understands lac / crore / k shorthand on input.
- Chat in plain English: βadd β¨5,000 salaryβ, βhow much can I still spend this month?β, βwhat did I spend on food in July?β
- Reads and writes across the app β add/edit transactions, set budgets, log savings, record assets & debts β with a confirm step before any write.
- Understands receipts and PDF statements (drop in an image/PDF β it extracts the expense).
- Scope-guarded to your finances only, powered by Google Gemini (generous free tier). Bring your own API key.
- Track gold, silver, stocks, crypto, property, and cash with cost basis, current value, and gain/loss.
- Live rates for gold & silver and FX via free, no-key public APIs β or set values manually.
- See your true net worth = assets β debts + balances, updated as prices move.
- People & Debts β track money you lent or borrowed, log repayments, and see per-person balances with a dedicated per-person history page.
- Splitwise import β bring in years of Splitwise history from an exported summary, reconciled to exact balances, with Insights by person, year, month, and place.
- Local-first β data lives in your browser (IndexedDB); the app works fully offline.
- Blur-amounts privacy toggle β hide every number instantly (reveal on focus) for shoulder-surfing safety.
- Account sign-in β email + password via Better Auth, with an optional per-user 4-digit PIN quick-unlock validated server-side. Multi-tenant, with an admin role and a closed (allowlist/invite) sign-up.
- Optional two-way sync β last-write-wins sync to your own Neon Postgres, authenticated by your session. Nothing goes to any third party β ever.
- Import/export β JSON backup/restore + CSV transactions import/export.
- Installable PWA with auto-update, plus light + dark themes and full accessibility.
Every screen ships loading, empty, success, and error states and is fully responsive.
| Ledgerly | Typical cloud finance app | |
|---|---|---|
| Your data stays on your device | β Local-first | β On their servers |
| Works fully offline | β PWA | β Needs connection |
| No bank credentials required | β Manual & import | β Screen-scrapes your bank |
| Self-hostable / free | β MIT, deploy your own | β Subscription |
| Own your sync database | β Your Neon Postgres | β Their cloud |
| AI assistant | β Built-in, BYO key | |
| Assets + net worth + live prices | β | |
| Splitwise import | β | β |
Ledgerly is for you if you want a privacy-first, ad-free, open-source alternative to Mint, YNAB, Splitwise, or a spreadsheet β one you fully control and can host yourself.
Shown with built-in sample data β your real numbers stay on your device.
Requirements: Node 24+ (Next.js 16 does not run on older Node).
git clone https://github.com/codewithowais/expense-tracker.git
cd expense-tracker
npm install
cp .env.example .env # then edit .env (see table below)
npm run devLedgerly uses Better Auth accounts on a Postgres database you control, so the four core vars below are required. The AI assistant is optional.
| Variable | Purpose |
|---|---|
DATABASE_URL |
Neon/Postgres pooled connection string (npx neonctl@latest init). Holds the Better Auth tables and the per-user synced ledger. Required. |
BETTER_AUTH_SECRET |
Session-signing secret. Required. Generate: node -e "console.log(require('crypto').randomBytes(32).toString('base64'))" |
BETTER_AUTH_URL |
The canonical origin the app is served from β http://localhost:3000 in dev, your domain in prod. |
ADMIN_EMAIL |
The email that becomes the super-admin on sign-up (manages the signup allowlist / invites). This makes you the owner of your instance. |
GEMINI_API_KEY |
Google Gemini API key (AIzaβ¦) to enable the AI assistant. Free from Google AI Studio. Leave blank to hide the assistant. |
Then create the database tables (one-time):
node scripts/migrate.mjs --fresh # app tables (user-scoped sync_records)
npx @better-auth/cli@latest migrate # Better Auth tables (user/session/account)Open http://localhost:3000, sign up with your ADMIN_EMAIL (you become the admin of your own instance), then complete a short setup (name, currency, optional PIN, optional sample data).
Self-hosting note: sign-up is closed by default β only the
ADMIN_EMAIL, allow-listed emails, or valid invites can register. This keeps your instance private to you (and anyone you invite).
π Security: treat
DATABASE_URLandBETTER_AUTH_SECRETas secrets. Never commit them β keep them in.env(git-ignored) and your host's dashboard. If a secret leaks, rotate it immediately.
Ledgerly ships an in-app assistant that turns natural language into financial actions:
- Read tools: financial summary, net worth, list/filter transactions, category breakdown, spending trend, budgets, debts, savings, assets.
- Write tools: add/edit/delete transaction, add asset, update asset value, set budget, add savings goal & contribution, add debt β each write asks you to confirm first.
- Receipts & PDFs: attach an image or statement and it extracts the amount, category, and date.
- Big-number aware: understands β1 lacβ, β2.5 croreβ, β5kβ.
It's strictly scoped to personal finance and refuses off-topic requests. Uses Google Gemini's free tier β just add GEMINI_API_KEY.
Privacy note: on Google's free Gemini tier, prompts may be used to improve their models. For maximum privacy, leave the key unset (the assistant simply won't appear) or use a paid, no-retention tier.
- Next.js 16 (App Router, typed routes, Turbopack) Β· React 19 Β· TypeScript (strict)
- Tailwind CSS v4 (OKLCH tokens) + shadcn/ui (Radix)
- Dexie / IndexedDB for local-first persistence Β·
@neondatabase/serverlessfor sync - Zustand (UI/lock/sync state) Β· dexie-react-hooks (reactive queries)
- Recharts 3 Β· Motion Β· date-fns Β· react-hook-form + Zod Β· Sonner Β· next-themes
- unpdf (serverless PDF text extraction) Β· Google Gemini (AI) Β· Vitest (unit tests)
Ledgerly is a standard Next.js App Router app and deploys to Vercel with zero extra config (no vercel.json).
- Push to GitHub and Import the repo in Vercel (framework auto-detected as Next.js).
- In Project β Settings β Environment Variables, add the vars from the table above for Production (and Preview). The local
.envis git-ignored and never uploaded:DATABASE_URLβ the pooled Neon string. Required for accounts & sync.BETTER_AUTH_SECRETβ the session-signing secret. Required (same value across all instances).BETTER_AUTH_URLβ your deployed origin, e.g.https://your-app.vercel.app.ADMIN_EMAILβ the email that becomes the super-admin on sign-up.GEMINI_API_KEYβ enables the AI assistant; unset = assistant hidden.
- Run the migrations once against your production
DATABASE_URL(see Quick Start). - Deploy. Changing an env var later requires a redeploy to take effect.
Also runs anywhere Node 24 does β see the Docker section below.
Ledgerly ships a service worker (src/app/sw.js/route.ts) and a web manifest, so it installs like a native app and keeps working with no connection:
- Online: network-first for pages/assets (always the latest), written back to cache.
- Offline: the same requests fall back to cache; immutable build assets (
/_next/static/*) are served cache-first. - Offline writes save straight to IndexedDB and queue for sync; when you're back online, they push to Neon automatically (also on tab refocus + a periodic safety net).
- API routes (
/api/lock,/api/sync) are never cached and fail gracefully offline.
The worker registers in production only (it would fight HMR in next dev) and auto-updates on load/refocus. Test with npm run build && npx next start.
A multi-stage Dockerfile pinned to Node 24 builds and runs identically regardless of host Node, using Next.js standalone output for a small image.
docker compose up --build
# β http://localhost:3000- Server-only vars (
DATABASE_URL,APP_PIN,GEMINI_API_KEY,SYNC_SECRET) are read at runtime β pass with--env-file .env(compose usesenv_file). NEXT_PUBLIC_*vars are inlined at build time, soNEXT_PUBLIC_SYNC_TOKENis a build arg (wired indocker-compose.yml).
npm run dev # start the dev server
npm run build # production build
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run test # vitest (money / analytics / dates / debts / savings / csv logic)Data is local-first: everything lives in IndexedDB via a single typed Dexie instance, accessed only through repositories (src/lib/repositories/*). The UI reads reactively via hooks in src/lib/hooks/use-data.ts, so any mutation instantly refreshes every view. When DATABASE_URL is set, a background sync engine mirrors changes to Neon using soft-delete tombstones and last-write-wins.
src/
app/(app)/ # authed shell + feature routes (dashboard, transactions,
# budgets, savings, people, assets, analytics, reports, splitwiseβ¦)
app/api/ # sync + lock + assistant + rates + extract server routes
components/
assistant/ # AI chat widget
assets/ # asset tracker + live-rate button
splitwise/ # import + insights
people/ transactions/ charts/ categories/ budgets/ savings/ reports/ settings/ sync/
ui/ # shadcn primitives
lib/
db/ # Dexie schema + seed (per-user namespaced)
repositories/ # settings, categories, transactions, budgets, people, savings, assets, splitwise, meta
assistant/ # tools, executors, chat hook
splitwise/ # parser, report builder, types
sync/ # sync engine + types
rates.ts analytics.ts debts.ts savings.ts # pure derivations
Money is stored in major units; aggregation is float-safe. See docs/ARCHITECTURE.md for the full component and API surface.
All data lives in your browser by default. Cloud sync is opt-in and goes only to your own Neon database via server-side API routes β the connection string is never exposed to the browser. Use Settings β Data to export a backup, and Settings β Cloud sync to enable syncing across devices. The AI assistant is optional and only runs when you provide your own key.
Contributions are welcome! To get started:
- Fork the repo and create a branch:
git checkout -b feat/your-feature. - Run
npm run typecheck && npm run lint && npm run testbefore pushing. - Open a Pull Request describing the change.
Found a bug or have an idea? Open an issue β β star the repo if Ledgerly is useful to you, it genuinely helps others discover it.
Released under the MIT License Β© 2026 Owais Ahmed. Free to use, modify, self-host, and distribute β just keep the license notice.
open source expense tracker Β· personal finance app Β· budgeting app Β· local-first Β· offline PWA finance app Β· self-hosted money manager Β· privacy-first budget tracker Β· Mint alternative Β· YNAB alternative Β· Splitwise alternative Β· Splitwise import Β· net worth tracker Β· asset tracker Β· gold price tracker Β· crypto portfolio tracker Β· savings goal tracker Β· debt tracker Β· who owes whom Β· AI finance assistant Β· Gemini finance chatbot Β· receipt scanner Β· PDF statement parser Β· Next.js 16 finance app Β· React 19 Β· TypeScript Β· Tailwind CSS v4 Β· IndexedDB Β· Dexie Β· Zustand Β· Neon Postgres sync Β· multi-currency expense tracker Β· PIN lock Β· installable PWA Β· money management software Β· income and expense tracker Β· cash flow dashboard
What is the best open-source, self-hosted expense tracker?
Ledgerly is a strong choice: it's a free, open-source, self-hosted personal finance and budgeting app you deploy on your own server and database. It's local-first (works offline as a PWA), tracks income, expenses, budgets, savings, net worth and assets, and who owes whom, imports Splitwise history, and includes an optional AI finance assistant β with no ads and no data-selling.
Is there a free, offline budgeting app that isn't tied to a bank?
Yes β Ledgerly is a free offline budgeting app that never connects to your bank. It runs as an installable PWA, stores data locally in your browser, and lets you add transactions manually, by CSV import, by receipt/PDF scan, by Splitwise import, or by chatting with the AI assistant.
Is Ledgerly free and open source?
Yes. Ledgerly is 100% free and open source under the MIT license. You can use it, modify it, self-host it, and even build commercial products on top of it.
Is my financial data private? Where is it stored?
By default, all your data stays in your browser (IndexedDB) and never leaves your device. Cloud sync is opt-in and goes only to your own Neon Postgres database. Ledgerly has no central server that collects your data.
Does it work offline?
Yes β Ledgerly is an installable PWA that works fully offline. Changes you make offline are saved locally and synced automatically when you reconnect (if you enabled sync).
Is Ledgerly a good Mint, YNAB, or Splitwise alternative?
Yes. It covers budgeting and expense tracking (like Mint/YNAB) and shared/lent-money tracking (like Splitwise) β plus it can import your Splitwise history. Unlike those apps, it's local-first, private, self-hostable, and free.
Do I need to connect my bank account?
No. Ledgerly never asks for bank credentials. You add transactions manually, via the AI assistant, receipt/PDF import, CSV import, or Splitwise import.
How does the AI assistant work and is it private?
It uses Google Gemini with your own API key (free tier available). It can read and write your finance data (with a confirm step for writes) and is scoped to finance only. On Google's free tier, prompts may be used to improve their models β for maximum privacy, leave the key unset or use a no-retention tier.
Can it track assets and net worth (gold, stocks, crypto)?
Yes. Track gold, silver, stocks, crypto, property, and cash with cost basis, current value, and gain/loss. Gold/silver and FX can use live public price APIs (no key needed) or manual values, and your net worth updates as prices move.
What tech stack does it use?
Next.js 16, React 19, TypeScript, Tailwind CSS v4, Dexie/IndexedDB, Zustand, Recharts, and optional Neon Postgres for sync. It deploys to Vercel with zero config or runs anywhere via Docker.