Chapter 1

Introduction

OpenExpense is a privacy-first, open-source expense tracker. There are no accounts, no cloud sync, and no data mining — only an encrypted ledger that lives in your browser.

Most expense apps ask you to trust a company with your spending history. OpenExpense takes the opposite approach: the entire app runs on your device, your ledger is encrypted before it is written to storage, and nothing is uploaded to a server because there is no server.

You are always in control. There is no background service, no AI operator, and no automated agent acting on your behalf — every expense is something you log, edit, or confirm yourself.

What you get

  • Calendar ledger — tap any day to log one or more expenses.
  • Monthly summary — paid vs pending totals, trends, top merchants, and a year chart.
  • Receipt scanning — photograph or upload a receipt or PDF; local OCR suggests fields you review before saving.
  • Encrypted autosave — changes write to encrypted local storage automatically.
  • Encrypted export — download a backup zip you can move to another device.
  • Spending report PDF — export the current month from the sidebar.

Open source & transparent

The full codebase is on GitHub under the MIT license. You can read exactly how encryption, storage, and receipt parsing work. The project is free to use — no subscriptions, ads, or upsells.

Privacy by architecture

Because OpenExpense never calls a backend, your records cannot be harvested in a corporate breach or sold to advertisers. Encryption keys are created on your device and marked non-extractable, so even casual inspection of browser storage shows only ciphertext. On shared or untrusted devices, you can pause autosave from the header disk button so changes stay in memory only for that session.

Chapter 2

Using the app

Everything in OpenExpense is designed around the calendar. This chapter walks through logging expenses, reading your monthly summary, scanning receipts, and managing backups.

Ledger name & status

Name your ledger at the top of the Expenses view (for example, Personal expenses). The name appears in exports and PDF reports. Next to it, a status chip shows whether encryption and autosave are active — green when your ledger is encrypted and saving locally, amber when autosave is paused or encryption is unavailable.

The calendar

The main view is a month calendar. Use the arrows to change months, or tap Today to jump back to the current month. Days with expenses show a total; tap a day to open its detail panel.

Toolbar actions on the calendar:

  • Import — load an encrypted backup zip, separate key/ledger files, or a legacy plaintext .json.
  • Export — download an encrypted .zip backup of your full ledger.
  • Clear — wipe all expenses and the ledger name on this device (with confirmation).
  • Scan — photograph or upload a receipt or PDF for local OCR.

Logging an expense

Tap a calendar day to open the expense panel. For each entry you can set:

  • Title — merchant or description.
  • Cost — amount in dollars.
  • Recurring — when checked on a new entry, copies forward to the same day in future months.
  • Paid — mark whether the charge is settled or still pending.
  • Notes — optional context (line items, invoice numbers, etc.).

Existing entries can be edited inline or deleted. Nothing leaves the panel until you save.

Monthly summary sidebar

On wider screens, the right sidebar shows a spending report for the month you are viewing:

  • Total spent with paid vs pending breakdown.
  • Insights — averages, month-over-month trend, recurring vs one-time spend, and a projected total for the current month.
  • Top spend — your largest merchants by amount.
  • Year overview — bar chart of monthly totals; click a bar to jump to that month.
  • This month — pending and paid entries; click any row to open that day.

Use the PDF button in the sidebar header to download a formatted monthly spending report.

Receipt scanning

Tap Scan on the calendar toolbar or the floating scan button. Choose a photo, image file, or PDF invoice. On first use, the app downloads a local OCR engine (~5 MB) and caches it in your browser — processing never leaves your device.

After scanning, a review sheet shows suggested merchant, amount, date, and notes. Edit anything before saving; nothing is written to your ledger until you tap Save expense. You can also choose Save & scan another to log multiple receipts in a row. Expand View raw scanned text if you want to verify what the parser read.

Receipt parsing is a convenience, not an autopilot. You are always the one who decides what gets saved — the app never auto-logs a scanned receipt without your confirmation.

Header controls

  • Disk button — toggle autosave. When off, changes stay in memory only until you turn autosave back on or export a backup.
  • Sun/moon button — switch between light and dark theme.
  • Open Source — link to the GitHub repository.

Chapter 3

Your data

Because OpenExpense runs entirely in your browser, you are the only person who can access your financial records. This chapter covers how data is stored, backed up, and structured.

How your data is stored

Your ledger is saved in IndexedDB and encrypted with AES-256-GCM before it touches disk. The key is created on this device, marked non-extractable, and stored locally — inspecting browser storage shows only ciphertext.

Autosave writes every change to encrypted local storage automatically (debounced, so rapid edits batch into one write). The disk button in the header pauses autosave for a session where changes stay in memory only.

Encryption requires a secure context (https:// or localhost). Open the app through a local server or HTTPS — not by double-clicking the HTML file — so encryption works. Only non-sensitive UI preferences (theme, autosave on/off, first-visit flag) use localStorage; the ledger itself never does.

Backups & moving between devices

Export is your manual backup. It produces an encrypted .zip containing ledger.enc.json (ciphertext), ledger.key.json (the decryption key), and a short README.txt.

  1. Export — download the encrypted zip from the calendar toolbar.
  2. Split for safety — store the key file separately from the encrypted ledger; neither is useful alone.
  3. Import — load the zip, or the two files in either order, on any device. Legacy plaintext .json exports still import.

There is no cloud sync. Move backups manually — USB drive, encrypted cloud folder, or any method you trust.

Ledger format

Inside the encrypted record, calendar dates are unique keys mapping to arrays of expense objects. This is the same shape used in exports (after decryption) and legacy imports:

{
  "name": "GBA Expenses",
  "events": {
    "2026-06-03": [
      { "title": "API Hosting", "price": 49.99, "recurring": true, "paid": false, "note": "" }
    ]
  }
}

Each expense has a title, price, and optional recurring, paid, and note fields. Dates use YYYY-MM-DD keys.

Security notes

  • Device-bound keys protect against casual inspection, not a compromised browser with full access.
  • Backup often — export your encrypted zip periodically.
  • Split sensitive sets — keep key and ciphertext apart when storing or sending.
  • No syncing — move exports manually between computers.