Double-Entry Bookkeeping 101 for Software Engineers
Tags: accounting, bookkeeping
Published: 2023-09-03 00:46:20

Accounting plays a big role in lots of applications out there and likely in your's too, otherwise I bet you wouldn't be here.

This post is a straight to the point shallow introduction to the subject, but I go a bit deeper at the end. Hopefully it's enough to get you started.

These are the core concepts I'll cover:
- Account;
- Ledger;
- Journal Entry;
- Debit and Credit; and
- The double-entry part of it;

> Note: there's a TL;DR at the end.


## Shallow introduction

![pink piggy bank](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0h1oagbx068or7871yq4.jpg "pink piggy bank")

### Account

Think of an account like a pink piggy bank (image above) where you can store money. The coins get mixed up inside it so if want to hold money for more than one purpose, you should probably have a piggy for each one. Don't forget to label them.

### Ledger

Ledger is like a drawer where you keep all your piggy banks. You have your own drawer that's just for your piggies. Your partner/relatives have their drawers, that way those piggies won't get mixed by mistake.

### Journal Entry

Since you're a well organized person, every time you want to deposit (or withdrawal) money from a piggy, you keep a record of how much you added/removed from it.

Those records are pretty much like git diffs. They indicate the accounts that changed and by how much (delta amount), what is analogous to lines of code changed and in which files. They don't represent a state, instead, they represent a change in state.

### Debit and Credit

Those mean nothing but a label. For those familiar with the `Either` type, debit and credit a simply the two possible constructors of an Either type. They are just labels.

```ts
type Operation =
     Debit<Account, Amount>
   | Credit<Account, Amount>
```
_(Pseudocode in TypeScript representing the Either type for Debit or Credit.)_

But why though, right? Well, you see, Accounting is something that goes way back in history, way before the “discovery” of negative numbers. Folks back then had to find a way to account for amounts that should decrease an account's balance. The way they found was to label their operations against an account with either Debit or Credit.

But that isn't as straight forward as "debit means positive number and credit means negative number". No, that'd be too easy. For now, just let the idea of them being labels sink in.

### Double-Entry

Say you're not satisfied with the accuracy of a single entry to keep track of you money because it’d take you one single silly mistake to invalidate all your records, and you’d be lost trying to figure out when your balances started to drift off from the actual money you have in your piggy bank.

Since you’re obsessed with precision, you now want to have two entries tracking a change in balance, where one can offset the other. This will give you some peace of mind knowing that it'd take you at least two mistakes in the same record (journal entry) to cause you a problem, and that’s less likely to happen.

Imagine you're taking some money from a piggy to place it into another piggy — maybe you're reallocating money from vacation to savings for a new computer (I'm not judging you): instead of having a single entry saying "moved $100 from piggy A to B", you'd have two entries in the same record representing "-$100 on piggy A" and "+$100 on piggy B".


## A bit less shallow now

_(Pun intended.)_

The essence of double-entry bookkeeping lies on having two (or more) equally-opposite entries/accounts that cancel each other. If they aren't canceling each other it means something's off, after all, that's the whole point in having double-entries.

Say I want to keep tabs on the money in my wallet and I want to know where that money came from. I could do that by having the following accounts:

```
Cash in my wallet:   $3000
Salary:              $2500
Garage sales income: $500
```
> Consider this block as a way to visualize a ledger.

If you read that as I having $6000, that's not it. The first account is the one that tells me how much money I have while the other two are meant to break down where that money came from. And that's by design, you might arrange yours differently to suit your needs.

That arrangement isn't totally arbitrary though. To understand it, you should know a thing or two about account classes. Some common account classes are "Assets", "Expenses" and "Income".

Let's keep going on the wallet example and, now, let's introduce paid rent. My ledger would look like this:

```
Cash in my wallet:    $2000
Rent:                 $1000
Salary:               $2500
Garage sales income:  $500
```

It's getting a bit confusing to read that. Did someone pay rent to me or was I the one who paid the rent?

To make that less confusing I could change the account's name but introducing accounts classes will do a better job here:

```
(Assets)   Cash in my wallet:   $2000
(Expenses) Rent:                $1000
(Income)   Salary:              $2500
(Income)   Garage sales income: $500
```

There you go, should be easier to read that now.

I won't get deeper into classes in this article but you should be able to Google it to learn more about Account Classes and about Account Groups. The important thing I want to highlight from classes for now is their **natural balance**.

You see, classes have this "direction" in which their accounts grows balance. For example, "Assets" accounts always grows their balance with **Debit** operations while "Income" accounts grows with **Credit** operations. That’s called **Natural Balance**.

That means:
- if you **Debit** an amount to an **Assets** account, its balance will **increase** because Assets accounts grows balance with Debit;
- if you **Credit** an amount to an **Assets** account, its balance will **decrease**;
- if you **Debit** an amount to an **Income** account, its balance will **decrease**; and
- if you **Credit** an amount to an **Income** account, its balance will **increase** because Income accounts grows balance with Credit.

You may have noticed that you need both the "Operation's direction" (Debit or Credit) and the natural balance from the account's class (also Debit or Credit) so that you know whether you're adding or subtracting balance to/from an account.

## Journalizing

So far we've seen the written representation for a ledger, now we'll introduce the representation for journal entries. But first things first, "journalizing" is the act of coming up with a journal entry — it's a design process.

Let's say the month has just began and I'm broke (fact [kkkkry](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRVWN1yUZfHjYyzF3eBi-ETubMWP9IVlDMPNw&usqp=CAU)). Here's what my ledger for the current month looks like:

```
(Assets)  Cash in my wallet: $0
```

I get paid my salary and, of course, I'll create a **Journal Entry** to record that:

```
Dr. Cash in my wallet   (+A)  $2500
  Cr. Salary            (+I)        $2500
```
> Consider this block as a written representation of a Journal Entry.
>
> Decomposing the journal entry, we first have:
> * **"Dr."**: it’s a conventional short form for Debit;
> * **"Cash in my wallet"**: the name of the account I'm debiting;
> * **"(+A)"** (optional): “A” is short for Assets, the "+" sign indicates I’m increasing Assets; and
> * **"$2500"**: the amount I'm debiting to the account.
>
> Then we have:
> * **"Cr."**: it’s short for Credit;
> * **"Salary"**: the name of the account I'm crediting;
> * **“(+I)”**: “I” is short for Income, the "+" sign indicates I’m increasing Income;
> * **"$2500"**: the amount I'm crediting to the account.
>
> Credit entries are always indented and, as for convention, they should come after all Debit entries.

> Note how the Credit operations in the journal entry offsets the Debit operations. That means my journal entry is balanced.

Now the balance in my accounts look like this:

```
(Assets)  Cash in my wallet:  $2500
(Income)  Salary:                   $2500
```

> Note how the sum of balance from accounts that increase with Debit ("Cash in my wallet" account) are offset by the sum of balance from accounts that increase balance with Credit ("Salary" account). That means my ledger is balanced.

> Note that I'm now indenting the balance of Credit accounts — the ones that have a class with Credit as natural balance.

Say I made a garage sale and got $500 bucks from it, we can record it as an increase in Assets (cash in) that is offset (explained by) an increase in Income:

```
Dr. Cash in my wallet   (+A)   $500
  Cr. Garage sales      (+I)        $500
```

```
(Assets)  Cash in my wallet:  $3000
(Income)  Salary:                   $2500
(Income)  Garage sales:             $500
```

Now we pay the rent:

```
Dr. Rent                  (+E)  $1000
  Cr. Cash in my wallet   (-A)        $1000
```

```
(Assets)   Cash in my wallet:  $2000
(Expenses) Rent:               $1000
(Income)   Salary:                   $2500
(Income)   Garage sales:             $500
```

Lastly, I want to give you an example demonstrating that a journal entry isn't limited to have only two operations. So let's say you went out for groceries shopping and, since you're compulsively organized, you want to track how much you spent on each shop:

```
Dr. Grocery Shop A        (+E)  $300
Dr. Grocery Shop B        (+E)  $200
  Cr. Cash in my wallet   (-A)        $500
```

```
(Assets)   Cash in my wallet:  $1500
(Expenses) Rent:               $1000
(Expenses) Grocery Shop A:     $300
(Expenses) Grocery Shop B:     $200
(Income)   Salary:                   $2500
(Income)   Garage sales:             $500
```

> Note that, despite the journal entry having more than two operations, its credits offsets its debits. And, in the Ledger, the sum debit accounts is still offset by the sum of credit accounts.


## Recap / TL;DR:

* We've seen that **accounts are dumb buckets** that stores a measurable amount of something, in this case it holds currency. If you want to track money for multiple purposes then you should use multiple accounts;

* Journal entries is **a way to represent changes in balances** on accounts. It's like a git diff, it holds only the changes in state but not the state itself;

* Ledgers are **where the accounts lives**. If you want to change its accounts' balances, you **post** (apply) a journal entry to a ledger;

* Accounts have a **class** and a class has a **natural balance** (Debit or Credit) which tells us what is the kind of operation that makes the account's balance increase;

* Debit and Credit means **nothing but a label**. It's only when you put together the natural balance from the account's class (Debit or Credit) and the direction of the operation (also Debit or Credit) that you can resolve wether the operation should increase or decrease the account's balance;

* Making your numbers trustworthy:

  * The **sum of Debit operations** in a journal entry **SHOULD be equal** the **sum of Credit operations**. That indicates that the journal entry is balanced;

  * The **sum of balances from Debit accounts** SHOULD be equal the **sum of balances from Credit accounts**. If you only ever post balanced journal entries to your ledger then, consequentially, your ledger will be balanced too;

That's it for this post. As I mentioned, this is just an introduction but hopefully it's enough for you to start playing with double-entry bookkeeping.

---

If this subjected is of your interest, please consider following me and stay tuned for more articles in this series about double-entry bookkeeping ;)

You might also be interested in [Bookk](https://github.com/rwillians/bookk), my Elixir/Erlang library that provides the building blocks for operating ledgers with double-entry bookkeeping.