How Balance works, and how to bring your books

One plain-text file, two ways to get to it: start from nothing, or move a journal you already keep.

Balance reads and writes a single plain-text file. That is the whole design, and it means there are only two ways to begin: let Balance make the file, or point it at one you already have.

If plain-text accounting is new to you, read Starting from nothing and skip the second half. If you already keep a ledger-cli or hledger journal, go straight to Bringing a journal you already keep, which covers opening it where it sits and moving it into the journal Balance syncs for you. There is no import button in the app, and the second half explains why you don't need one.

Part one

Starting from nothing

No accounting background assumed, and no terminal needed.

What the file is

Your books are a text file: a few lines per transaction, one transaction after another, that you can read with your own eyes. Not a database, not an export, not a container only this app can open.

The conventions come from ledger-cli and hledger, two command-line tools that read this kind of file. Balance is another reader of the same format, and you never have to install either tool. If you pick one up later, it reads the file Balance writes.

What a transaction looks like

2026-09-03 * Coffee Shop
    Expenses:Coffee    $4.50
    Assets:Checking

The first line is the date, a * meaning the transaction has cleared, and who you paid. The two indented lines are postings: $4.50 arrived in Expenses:Coffee and the same amount left Assets:Checking.

The second amount is missing because it can only be one number: every transaction has at least two postings and they have to add up to zero. That is what double-entry means, and Balance checks it on every entry.

Account names start with one of five roots:

  • Assets: what you have. Checking, savings, cash.
  • Liabilities: what you owe. A credit card, a loan.
  • Equity: where things stood before you started, and the rest.
  • Income: what comes in.
  • Expenses: what it goes on.

Only that first segment means anything to Balance. Everything after a colon is your own hierarchy, so Expenses:Food:Groceries is yours to name, rename or drop.

First launch

The first time you open Balance you get a screen titled Set Up Your Journal: “Balance keeps your books in one plain-text file. Open a journal you already keep, or start from a template chart of accounts you can rename.” Two buttons follow, I Have a Journal… and Start from a Template. No sample data is ever written.

Take the template and you get a few comment lines plus twelve account declarations, and no transactions:

account Assets:Checking
account Assets:Savings
account Assets:Cash
account Liabilities:CreditCard
account Equity:Opening
account Income:Salary
account Expenses:Housing
account Expenses:Utilities
account Expenses:Food:Groceries
account Expenses:Food:Restaurants
account Expenses:Transport
account Expenses:Subscriptions

An account line declares a name and records nothing, so every balance starts at zero. Rename what doesn't fit, delete what you don't use, add what's missing, in the app or in any text editor.

Opening balances

Books that begin today would say you own nothing, so record what each account already holds: one transaction per account, with Equity:Opening on the other side.

2026-01-01 * Opening balances
    Assets:Checking    $1500.00
    Equity:Opening

Do the same for savings, for cash, and for each card. Money leaving an account is a negative amount on that account, so a card you owe $400 on gets $-400.00 on the liability account against the same Equity:Opening.

Recording day to day

The new transaction sheet takes a date, a payee, tags if you want them, and two or more postings. Leave one amount empty and Balance fills it in so the entry balances. While the postings disagree the header says by how much, “Off by +$4.30”, and Add stays disabled.

Mark an entry * once you have seen it on a statement, or ! while it is pending. For the expense you make every day there is also Log Expense, which Siri runs without the app coming to the front: see Siri and Shortcuts.

Where the file is, and what syncs

The file Balance makes for you is called journal.ledger. Settings ▸ Journal has a read-only Storage row naming where it lives, either iCloud Drive or On My Device, with the full path under it and a button: Show in Finder on the Mac, Open in Files on iPhone and iPad. For a journal you opened yourself the row names that file instead.

Which one you get is a system setting rather than an app setting. There is no iCloud switch inside Balance. Signed in with iCloud Drive on, it uses its own iCloud container, which appears as a folder named Balance in iCloud Drive: the Files app on iPhone and iPad, Finder on the Mac. Signed out, or with iCloud Drive off, it uses the app's own Documents folder, which Files shows under On My iPhone ▸ Balance.

Another device on the same Apple Account opens the same file with no set-up screen: it downloads the journal and shows it. If the download takes too long you get Journal Not Downloaded Yet, “Your journal is still downloading from iCloud. Check your network connection and try again.”, and a Try Again button.

The syncing itself is done by iOS and macOS under your own Apple Account. Balance opens no connection of its own, and on the Mac it ships without the network entitlement, which you can check yourself.

On a conflict the last write wins, silently. If two devices are edited while both are offline, one version survives whole and the other is discarded when they sync. Let one device finish syncing before you edit on the other, and keep backups of your own.

It stays a text file throughout: open it in any editor and the running app follows about a second later.

What's free

Browsing, search, every report, account detail and iCloud sync are free forever, and so is reading your journal from Shortcuts.

The full version adds adding, editing and deleting transactions; creating, renaming and deleting accounts; budgets; recurring transactions; reconciling against a statement; exporting CSV, PDF and a copy of your journal; and writing with Siri and Shortcuts. One purchase covers iPhone, iPad and Mac; the price is on the home page.

Part two

Bringing a journal you already keep

For a ledger-cli or hledger journal that already exists. Keep a copy before you start.

Two ways in, and how to choose

Open it where it is

  • Balance edits the file you picked, in place, and never copies it.
  • It stays in its folder, its git working copy, and whatever already syncs it.
  • Budgets and recurring templates for it stay on the device you set them on and don't sync.
  • Its include lines are still not followed.

Move it into the journal Balance keeps

  • The journal, budgets and recurring templates all sync between your devices.
  • It has to be one file, so combine anything you include first.
  • It has to be named journal.ledger and sit in Balance's iCloud folder.
  • Don't keep a git repository inside that folder. Copy the file out to one instead.

If something already syncs and versions your journal, open it where it is. If you want the app's own sync, with budgets and recurring templates on every device, move it in.

Check your file first

Both ways run the same parser, so this list applies to both.

  • Virtual postings, (Account) and [Account]: not supported. Balance reads them as ordinary postings, brackets kept in the account name. One that throws the transaction out of balance takes the whole file down with an unbalanced-transaction error; a set of [Account] postings that adds up to zero on its own loads quietly instead, and you get accounts named [Account] in the sidebar. Remove them or make them real postings first.
  • Comma decimal points: . is the decimal point and , is stripped as a grouping separator, so 1.234,56 is read as 1.23456. Rewrite it as 1234.56 or 1,234.56.
  • include: not followed. The line is preserved and a permanent banner says so: “This journal uses include. Included files aren’t loaded, so figures cover only this file.” Every figure then covers one file.
  • Balance assertions, = AMOUNT: parsed, written back untouched, and never checked. Balance verifies that postings add up to zero, which is a different thing, so a silent assertion here is not a confirmed one.
  • Periodic and automated transactions, ~ and = blocks: kept byte for byte, never run. The same goes for P, alias, year and indented sub-directives. D and commodity are kept the same way, though Balance does read them to decide how an amount you edit is written.
  • Beancount syntax: not supported at all.
  • Dates in another form, like 2026.09.03 or a two-digit year: that transaction is skipped, silently, and drops out of every figure. Rewrite the date first.
  • A root outside the five, like Bank:Checking: the file loads, but the account is unclassified and every report leaves it out. Rename it under Assets, Liabilities, Equity, Income or Expenses.

Understood as you would expect: dates written YYYY-MM-DD or YYYY/MM/DD, an auxiliary =DATE after it, * and ! on the transaction and per posting, codes like (REF-042), one elided amount per transaction, account directives, full-line ; and # comments, and inline ; comments after two spaces, prices with @ and @@ (they take part in balancing), ledger-cli style :tag: tags in a comment, and several commodities at once, each reported separately and never converted into another.

Way one: open it where it is

On Mac and iPad it's File ▸ Open Journal… (⌘O). On iPhone, where there is no menu bar, it's Settings ▸ Journal ▸ Open Journal…, and Settings ▸ Journal has the same entry on Mac and iPad. The I Have a Journal… button on first launch opens the same picker, and the picker doesn't filter by extension, so .ledger, .journal, .dat and .hledger all work.

Balance then edits that file where it found it, never copying it and never seeding it, so a journal in a git working copy stays in it. If the folder is already synced by iCloud Drive or anything like it, that service keeps syncing it and Balance does nothing extra.

Open Recent keeps the last five. On iPhone the Current Journal picker lists the same recents, with Balance’s Journal as the first row.

Two things to expect. Budgets and recurring templates for a journal you opened yourself are kept with Balance's data on that device, so they stay there and don't sync. And if the file later moves or is deleted you get Journal Not Found, “The journal you opened is no longer where Balance left it. Open it again, or go back to the default journal.”, with Open Journal…, Use Default Journal and Try Again.

Way two: move it into the journal Balance syncs

There is no import, no copy step and no “make this my default” in the app, because the place Balance looks is an ordinary folder you can open yourself. Six steps.

  1. Get everything into one file. Balance doesn't follow include, so combine the included files in the order they are included, account directives first. Keep the original.
  2. Run the file past the checks above and fix anything they flag.
  3. Reveal the folder: Settings ▸ Journal ▸ Show in Finder on the Mac, Open in Files on iPhone and iPad. On the Mac, Finder ▸ iCloud Drive ▸ Balance gets there too. If the app has never run, run it once and take Start from a Template so the folder exists.
  4. Quit Balance on every device. Last write wins here as much as anywhere.
  5. Put your file in that folder, named exactly journal.ledger, replacing the one Balance made. Balance never overwrites a journal.ledger it finds there, so what you put in is what it opens.
  6. Wait for the upload badge to clear in Finder or Files, then launch Balance. The Storage row reads iCloud Drive, and your other devices download the file on their next launch.

On the Mac the folder is at a path you can type:

~/Library/Mobile Documents/iCloud~com~mkociola~Balance/Documents/journal.ledger

One footnote on budgets. The app moves budgets.json and recurring.json only when it moves a journal of its own from the device into iCloud. Budgets set against a journal you had opened in place belong to that pick and won't follow the file here, so expect to set those again.

Working alongside your editor

Balance watches the file, so an edit you make elsewhere shows about a second later, with nothing to reload.

Two failure modes, both deliberate. If an edit made while the app is open breaks the file, Balance keeps showing the last good state, and after two failed reloads it raises a Couldn't reload journal alert. If the file is broken when the app launches, the blocking screen Couldn't Open Journal appears with “The journal file exists but could not be read. It may be malformed or inaccessible.”, the path, and the parser's own message, along the lines of Parse error on line 42: … or Transaction is unbalanced in $: off by 50. Fix that line in your editor and open it again. There is no in-memory copy to fall back to: the app refuses to show data it cannot safely write back.

What Balance writes back is narrow: the transactions you edited, and nothing else. Every other line, including every directive it doesn't interpret, goes back exactly as it was, and budgets and recurring templates never enter the journal at all.

For history, the iCloud folder on the Mac is an ordinary folder, so a scheduled cp of journal.ledger into a git repository, then a commit, gives you the versions last-write-wins does not.

Going back, or switching

To leave a journal you opened yourself and return to the one Balance keeps, it's Use Default Journal on the Mac and iPad menu, or Current Journal ▸ Balance’s Journal on iPhone. Picking Balance's own journal.ledger through the file picker does the same thing.

Turning iCloud Drive on later, when the Balance folder in iCloud holds no journal yet, makes Balance move your local journal.ledger into it on the next launch, with budgets.json and recurring.json behind it. Nothing is lost and nothing is duplicated, and the Storage row flips to iCloud Drive. If that folder already holds a journal, that one wins: your local file is left where it is, untouched, and the two are never merged.

Turning iCloud Drive off does the reverse: the next launch uses the local journal, or shows Set Up Your Journal again if there isn't one, and the copy in iCloud is left alone.

Something here not matching what the app does? See Support.