Start a journal

by hand

(power users)

The simplest possible journal is just an empty file:
echo >2017.journal

The name doesn't matter much and can be changed later. One file per year is common, and so is a .journal or .hledger extension.

Record a transaction, using journal format:

$ cat >>2017.journal
  expenses:food     $10

Account names can be anything and you can change them later by search and replace. If you don't know what to choose, start with these five:
expenses, income, assets, liabilities, and equity,
perhaps with one extra subcategory as above.

by text editor

Write transactions in a text editor and save the file.

by add

Use the add command:
hledger add -f 2017.journal
enter one or more transactions


To avoid typing -f FILE every time, set the LEDGER_FILE environment variable. Eg:
echo "export LEDGER_FILE=~/finance/2017.journal" >> ~/.bash_profile && source ~/.bash_profile

Most examples here assume you have done this.

by hledger-iadd

ensure $LEDGER_FILE exists
hledger iadd
enter one or more transactions

by hledger-web

ensure $LEDGER_FILE exists
hledger web
wait for web browser to open
click "add transaction" or press "a"
enter a transaction, click ok or press enter

Track changes with version control

You don't need to do this, but it's a nice way to keep track of changes to your data.


Start tracking changes:
git init && git add 2017.journal && git commit 2017.journal -m "first commit"

View uncommitted changes: git status, git diff

Commit changes: git commit 2017.journal -m "updates"

View past commits: git log


darcs init && darcs add 2017.journal && darcs record 2017.journal -m "first commit"

darcs whatsnew, darcs diff

darcs record 2017.journal -m "updates"

darcs log


Example journal entries

Example hledger journal entries for various kinds of transaction.

A purchase:

2017/1/26 market
  expenses:food    $10

Convert CSV files

Here's a quick example of converting a CSV file.

Say we have downloaded checking.csv from a bank for the first time:

"2012/3/23","TRANSFER TO SAVINGS","-10.00"

We tell hledger how to intepret this with a file named checking.csv.rules, using the CSV rules syntax. Eg:

# skip the first CSV line (headings)
skip 1

# use the first three fields in each CSV record as transaction date, description and amount respectively
fields   date, description, amount

# prepend $ to CSV amounts
currency $

# always set the first account to assets:bank:checking
account1 assets:bank:checking

# if the CSV record contains ‘SAVINGS’, set the second account to assets:bank:savings
# (if not set, it will be expenses:unknown or income:unknown)
  account2 assets:bank:savings

Now hledger can read this CSV file as journal data:

$ hledger -f checking.csv print
using conversion rules file checking.csv.rules
2012/03/22 DEPOSIT
    income:unknown             $-50.00
    assets:bank:checking        $50.00

    assets:bank:savings         $10.00
    assets:bank:checking       $-10.00

We might save this output as checking.journal, and/or merge it (manually) into the main journal file. We could also run other commands:

$ hledger -f checking.csv balance
using conversion rules file checking.csv.rules
              $50.00  assets:bank
              $40.00    checking
              $10.00    savings
             $-50.00  income:unknown

Here are more CSV rules examples.

Rewrite account names

Here's an example of using account aliases.

Say a sole proprietor has a personal.journal:

    expenses:food  $1

and a business.journal:

    expenses:office supplies  $1
    assets:business checking

So each entity (the business owner, and the business) has their own file with its own simple chart of accounts. However, at tax reporting time we need to view these as a single entity (at least in the US). In unified.journal, we include both files, and rewrite the personal account names to fit into the business chart of accounts,

alias expenses    = equity:draw:personal
alias assets:cash = assets:personal cash
include personal.journal
end aliases

include business.journal

Now we can see the data from both files at once, and the personal account names have changed:

$ hledger -f unified.journal print
2014/01/01                                    # from business.journal - no aliases applied
    expenses:office supplies            $1
    assets:business checking           $-1

2014/01/02                                    # from personal.journal
    equity:draw:personal:food            $1   # <- was expenses:food
    assets:personal cash                $-1   # <- was assets:cash

You can also specify aliases on the command line. This could be useful to quickly rewrite account names when sharing a report with someone else, such as your accountant:

$ hledger --alias 'my earning=income:business' ...

See also How to use another account separator character.

Use another account separator character

Timedot format makes me want to use dots (.) for separating account components, instead of colon (:). For example, instead of fos:hledger:timedot I'd like to write fos.hledger.timedot. We can use the powerful account aliases feature to rewrite account names before hledger's account name parser sees them.

In journal files, we can use an alias directive. Note the backslash which tells the regular expression engine it's a literal . not a wildcard:

alias /\./=:

2008/01/01 income  $1

Check that subaccounts are recognised:

$ hledger -f t.journal bal --no-elide
                  $1  assets
                  $1    bank
                  $1      checking
                 $-1  income
                 $-1    salary

Alias directives aren't supported in the timedot format,

fos.hledger.timedot  2
fos.ledger           1

so we would use the --alias command line option instead. The second backslash tells the shell that's a literal backslash, not a shell escape sequence:

$ hledger --alias /\\./=: -f t.timedot bal --no-elide
                3.00  fos
                2.00    hledger
                2.00      timedot
                1.00    ledger

Track investments

A simple example using prices:

2017/1/1 opening balances
  (assets:depot)  $3000

2017/1/2 buy shares at $200
  ; let's assume no fees
  assets:shares   10 TSLA @ $200  ; transaction/purchase price

; market price, has jumped since yesterday's purchase!
P 2017/1/3 TSLA $250

Some reports. We start with $3000. After the 1/2 purchase, we have $1000 remaining and 10 TSLA shares:

$ hledger -f t.j bal assets --flat -HD
Ending balances (historical) in 2017/01/01-2017/01/02:

               ||  2017/01/01     2017/01/02 
 assets:depot  ||       $3000          $1000 
 assets:shares ||           0        10 TSLA 
               ||       $3000 $1000, 10 TSLA 

Show the shares's value at cost, with -B/--cost:

$ hledger -f t.j bal assets --flat -HD -B
Ending balances (historical) in 2017/01/01-2017/01/02:

               ||  2017/01/01  2017/01/02 
 assets:depot  ||       $3000       $1000 
 assets:shares ||           0       $2000 
               ||       $3000       $3000 

Show the shares's value using the latest applicable market price, with -V/--value. A $500 capital gain is apparent in the totals:

$ hledger -f t.j bal assets --flat -HD -V
Ending balances (historical) in 2017/01/01-2017/01/02:

               ||  2017/01/01  2017/01/02 
 assets:depot  ||       $3000       $1000 
 assets:shares ||           0       $2500 
               ||       $3000       $3500 

This is about the limit of hledger's value-reporting abilities, currently.