How I organize my notes app in 2024
Personnal process documentation
Notes on how I organize notes in Joplin.
Joplin is my main productivity tool. It completely replaced my paper-based GTD stack that I used for about a decade to manage all my tasks, projects and ideas.
In this post, I describe how I organize Projects, Areas, Resources and Archives — from the PARA method — in Joplin. I’ll show how I integrated the Getting Things Done (a.k.a. GTD) and Bullet Journal (a.k.a. BuJo) methods to manage my tasks and captured notes as well.
Table of Contents
Metrics
The ‘Synchronization Status’ page, under the ‘Help’ menu, provide some statistics about the total number of items in my Joplin database.
Here’s the count of objects by type:
- Notes: 1506
- Folders (a.k.a. Notebooks): 256
- Resources: 561
- Tags: 9
- Tagged notes: 70
Top-level notebooks
Here’s my list of top-level notebooks and their size (as of 2024-11-30). I also included the emoji I selected to represent them in the UI.
- 📥 0 Inbox (193)
- 👷🏻 0 Tasks (113)
- 🏗️ 1.1 Projets personnels (6)
- 🚀 1.1 Projets sysadmin (9)
- 🗓️ 1.2 Projets activités (14)
- 1.3 Projets Grafana (29)
- ✍🏻 1.4 Projets écriture (2)
- 🚁 2 Areas (386)
- 🗃️ 3 Références (405)
- 🗄️ 4 Archives (279)
The PARA method
I follow the PARA method to organize my notes into Projects, Areas, Resources and Archives notebooks.
Learn more about PARA from Forte Labs:
https://fortelabs.com/blog/para/
There are many great videos on getting started with implementing PARA in your notetaking app.
Joplin is not represented, but that’s okay, because PARA is software-agnostic by design.
https://fortelabs.com/blog/how-to-implement-para-in-your-favorite-notetaking-app/
My ‘0 Inbox’ and ‘0 Tasks’ notebooks
For tasks and captured notes, I integrated some components of the GTD and BuJo methods in Joplin.
PARA folders are commonly prefixed with numbers 1 to 4, wich keeps them in order of actionability. For example, ‘1 Projects’ are more actionable than ‘4 Archives’. Following this logic, tasks and captured notes are more actionable than Projects, therefore, I use the ‘0’ prefix so that these folders get sorted at the top.
Under ‘0 Inbox’, I have my ‘BuJo’ notebook, and several ‘Incubation’ notebooks, to hold on to Someday/Maybe items, tend to ideas and make them grow into actual projects.
Notebooks structure
Here is how I structure my Notebooks in Joplin. This list contains Notebooks, no Notes are represented.
- 📥 0 Inbox
- BuJo
- Incubation
- Incubation activités
- Incubation écriture
- Incubation Grafana
- Incubation Riya
- Incubation sysadmin
- Meeting notes
- 👷🏻 0 Tasks
- Accounting
- Errands
- Reading
- 🏗️ 1.1 Projets personnels
- 🚀 1.1 Projets sysadmin
- 🗓️ 1.2 Projets activités
- 1.3 Projets Grafana
- ✍🏻 1.4 Projets écriture
- 🚁 2 Areas
- Accounting
- Blogging
- Car
- Fitness
- 🧑🏻💻 Grafana Labs
- Benefits
- People
- Professional Services
- Clients
- Lab environments
- PS team
- Workstation
- Microblogging
- Montréal
- Poetry
- ❤️ Riya
- Santa Fe
- Self
- Checklists
- Historique
- Systems Administration
- Backups
- Home server
- Laptop bootstrapping
- Phone
- Runbooks
- Services
- 🗃️ 3 Références
- Accounting
- Aikido
- Art
- Art and science inspiration
- Artists
- Writing
- Astronomy
- Career skills
- Dance
- Degoogling
- Games
- Horticulture
- Flowers
- Herbs
- Information technology
- Data science
- Programming
- Systems administration
- Outdoors
- Backpacking
- Camping
- Herbology
- Hiking
- Knots
- Maps
- Meteorology
- 🧭 Places
- Albuquerque
- Montreal
- New York City
- Santa Fe
- Taos
- Productivité
- Psychologie
- 🥗 Recettes
- Cocktails
- Deserts
- Ferments
- Health
- Repas
- Repas bengali
- Salads
- Dips, dressings
- Soups
- Software
- Android
- Joplin
- Kubernetes
- Vin
- 🗄️ 4 Archives
- Archives Administration de systèmes
- Archives Blogging
- Archives Grafana
- Archives Personnel
As you can see, I split my Projects directories into multiple top level categories. This makes it easier to find relevant projects based on context.
BuJo
Here’s what my BuJo notes in Joplin look like. We’re looking at one work-related BuJo note. This is how I manage all my tasks.
Notes:
- I don’t create a “task” note for every single actionable task that I have.
Instead, I use the task list formating.
- In Markdown, task lists have lines starting with
- [ ]
or- [x]
for incompleted and completed items, respectively. - Using lists allows me to easily group, reorder, and add formatting like bold or highlighting to items.
- I reorganize notes daily. Sometimes multiple times in a day.
- In Markdown, task lists have lines starting with
- All BuJo Notes are “Task” type in Joplin.
- When the Note is unchecked, it means there are incomplete tasks or unprocessed notes therein.
- When all tasks have been completed or migrated, and all notes have been processed or organized, then I check the Joplin note.
- Eventually, I’ll review the checked notes, to make sure they don’t contain information I want to keep.
- To close out old BuJo notes, I may migrate content to newer notes and mark the old one as checked.
- Note titles start with the date of creation (yyyy-mm-dd), followed by keywords to identify the context.
- ‘p’ means “Personal”.
- ‘gl’ is work related (Grafana Labs).
- ‘groceries’, self-explanatory.
Plugins
These are the plugins I install and configure on Joplin Desktop.
- Simple Backup
- Backup path:
/home/alex/Backups/Joplin/JoplinBackup <hostname>
- Keep x backups:
10
- Create Subfolder:
unchecked
- Backup path:
- Note Tabs
- Simple Highlighter
- Table Formatter Plugin
- Note Link System
- Rich Markdown
Tags
Sometimes, when I’m traveling or going through a very intense logistical process, I need to have several notes on “quick dial”. That’s when I use tags. I’ll tag notes for my itinerary, schedule, checklists, ticket scan codes, things like that.
Resources
Any file type can be attached to Joplin notes. My notes attachments consist mainly of images and PDFs, which can be displayed inline in a note.
Notes attachments are saved in the backend as ‘resources’. My resources directory contains 562 files, totaling 274.2MB, which I find quite manageable. I’m careful about storing large attachments, and only storing what I want to refer to later, but I wouldn’t mind if my resources grew to a few gigabytes.
Sync and backup architecture
This diagram shows how I use synchronization and backup features to use Joplin across devices and keep my data secure.
Notes:
The ~/Backups/
directory happens to be one of my top-level directories,
which is synchronized to my Nextcloud account,
and backed up to a remote Borg repository.
See How I organize my digital files in 2024
for more information.
Randomnote
I like this idea of a button to bring up a random note from Joplin.
This was before ForteLabs removed some free content from the blog.
Here is the archived article:
https://web.archive.org/web/20221208130825/https://fortelabs.com/blog/p-a-r-a-iii-building-an-idea-generator/
The script randomnote.py
:
#!/bin/env python3
import argparse
import logging
import random
import socket
import subprocess
import sys
import requests
excluded_notebooks_titles = [
"0 Inbox",
"4 Archives",
]
hostname = socket.gethostname()
if hostname == "electron":
token = "aaaa"
elif hostname == "higgs":
token = "bbbb"
elif hostname == "quark":
token = "cccc"
params = {
'token': token,
}
def main(dry_run=False):
try:
ping_joplin()
except:
logging.error("Joplin is not running.")
if not dry_run:
subprocess.run(["notify-send", "randomnote.py: Joplin is not running."])
sys.exit(1)
all_notes = list_notes()
notebooks = list_notebooks()
global excluded_notebooks_ids
excluded_notebooks_ids = set()
for notebook in notebooks.values():
recurse_parent_notebook(notebook, notebooks)
logging.debug("Excluded notebooks:")
for n in excluded_notebooks_ids:
logging.debug(notebooks[n]['title'])
valid_notes = []
for note in all_notes.values():
if note['parent_id'] in excluded_notebooks_ids:
notebook = notebooks[note['parent_id']]
logging.debug(f"Excluded note: {notebook['title']} / {note['title']}")
else:
valid_notes.append(note)
random_note = random.choice(valid_notes)
notebook = notebooks[random_note['parent_id']]
print(f"Random note: {notebook['title']} / {random_note['title']}")
if not dry_run:
subprocess.run(["xdg-open", "joplin://x-callback-url/openNote?id={}".format(random_note['id'])])
def ping_joplin():
r = requests.get("http://localhost:41184/ping")
r.raise_for_status()
def list_notes(page=1):
params['page'] = page
r = requests.get("http://localhost:41184/notes", params=params)
r.raise_for_status()
data = r.json()
all_notes = {}
for note in data['items']:
all_notes[note['id']] = note
if data['has_more']:
all_notes.update(list_notes(page+1))
return all_notes
def list_notebooks(page=1):
params['page'] = page
r = requests.get("http://localhost:41184/folders", params=params)
r.raise_for_status()
data = r.json()
notebooks = {}
for notebook in data['items']:
notebooks[notebook['id']] = notebook
if data['has_more']:
notebooks.update(list_notebooks(page+1))
return notebooks
def recurse_parent_notebook(notebook, notebooks):
is_excluded = False
logging.debug(notebook)
parent_id = notebook['parent_id']
if parent_id:
logging.debug("Recursion")
is_excluded = recurse_parent_notebook(notebooks[parent_id], notebooks)
if is_excluded:
excluded_notebooks_ids.add(notebook['id'])
elif notebook['title'] in excluded_notebooks_titles:
excluded_notebooks_ids.add(notebook['id'])
is_excluded = True
if is_excluded:
logging.debug(f"{notebook['title']} is excluded.")
return is_excluded
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Opens a random note in Joplin."
)
parser.add_argument("--dry-run", "-n",
help="Select a random note but don't launch Joplin.",
action="store_true",
)
parser.add_argument("--debug", "-d",
help="Increase verbosity level.",
action="store_true",
)
args = parser.parse_args()
if args.debug:
log_level = logging.DEBUG
else:
log_level = logging.INFO
logging.basicConfig(
level=log_level,
)
logging.debug("Log level set to DEBUG.")
main(dry_run=args.dry_run)
The desktop application file joplin-randomnote.desktop
:
[Desktop Entry]
Version=1.1
Type=Application
Name=Random Note
Comment=Joplin random note
StartupWMClass=Joplin
Icon=/home/alex/.local/share/icons/joplinrandomnote.png
Exec=/home/alex/Programs/personal/randomnote.py
Actions=
Categories=Office;
NoDisplay=false
The application icon: