With the competing demands of work, creative projects and keeping one’s house in order, it’s worthwhile to realize that your brain can only handle so much. While remembering things is great, sometimes you need to offload it to a personal knowledge system. There are many different approaches to these, using digital or analogue means.

A personal knowledge system1 is a collection of notes related to things you need to know, or want to explore. This can be as mundane as recording administrivia about your household, or as deep as trying to understand the philosophy of life. It’s important that it has some sort of system around it - a notepad with random scribbles is only useful in the moment. You want the notes to be useful forever.

I wanted to explain my digital knowledge system, which I call my “Exocortex”. It’s my brain outside my brain. I actually have two - one for work and one for home, and don’t really mix them. Having two allowed me to experiment a little, and view the same structure under different contexts. They work much the same though, so I’ll just pretend I have one.

I’ll walk you through some ideas about knowledge systems, introduce you to my Exocortex and the thinking behind it, and then transition into a discussion of implementation at the end. If you’re not big into Emacs, you can just skip that and go to the links.

Personal Knowledge Systems

My Exocortex is my own approach taking elements from popular knowledge systems such as Zettelkasten and Building a Second Brain. What are these?

Zettelkasten (wiki) is an old method, often reinvented, named after the German for “slip box”. Your knowledge system is a huge slip box full of notes. Every note is a small index card with the idea on it, with a reference ID and links to other cards or tags. The reference ID might just be a unique identifier, or some sort of hierarchical category. While some people still use this manual method, I find it’s an enormous amount of effort that you don’t get paid back with in efficiency. More modern approaches use digital storage rather than index cards or books, which can allow for searching or reference-following.

Building a Second Brain (website) (book) is a methodology (and associated course) about knowledge management by Tiago Forte without a specific instantiation. It focusses more on how you organize the information, and recommends digital approaches. Forte offers two main ideas:

PARA
Divide the universe into Projects (efforts with end states), Areas of Responsibility (efforts without end states), Resources (interests without effort or end states) and Archive (inactive items).
CODE method
Four distinct modes of using your Second Brain/Knowledge system: Capture, Organize, Distill, Express.

Jonny Boyd gave an expanded discussion of these ideas on Youtube.

The PARA method is useful to be mindful of where you’re locating a note and under what context. Recording the details about a car you own (Resource) is different from the notes you accumulate when you’re looking to buy one (Project). I don’t think it’s worthwhile being too strict about it.

I find the CODE method a good mental model for appropriate “modes of thought”. Writing is different from editing, and you should really be doing one or the other, not both. Editing notes can either be Organizing them (tagging, moving, refactoring notes) or Distilling them (rewriting, pruning notes). You need to be in one mindset or another, otherwise you’ll be messy. Capturing is pure input mode, and Expressing is pure output mode, so being mindful of these modes goes a long way.

I’ve taken the ideas from Zettelkasten and Second Brain, but in some ways bent or broken the rules.

People can be dogmatic about individual notes being atomic. This can sometimes make notes closer to idea snacks rather than true building blocks of thought.

People can also be dogmatic about having or not having hierarchies. I’ve experimented with both. If you have a strict and strong hierarchy, then you need to spend a lot of time Organizing to make sure the note fits the system. Occasionally this deforms ideas to fit the system, rather than the other way around. If you have only incidental hierarchies formed by links, then you may miss out on connections and opportunities because you forgot to tag a thing that one time.

I definitely think a primarily digital system is the way to go. You can’t search text notes, and you can’t back them up easily. With a little preparation, a digital system can be accessible everywhere via cloud storage or apps. The one downside is that it is harder to make freeform notes or diagrams by digital means.

Popular digital systems include: Evernote, Notion, Obsidian, Google Keep, or OneNote. If I wasn’t so invested in Emacs, I’d use Obsidian. I’ve used Evernote and Notion in the past.

Overview of my setup

The three main bits of hardware are my Linux desktop, my Android phone and a little Moleskine notebook called my commonplace book. The exocortex resides on my desktop, but my phone and commonplace book are used for input. More on that later.

I use Emacs and org-roam, which stands on the mighty shoulders of org-mode. Emacs is my workhorse. I do everything in it. I have a fantastic muscle memory for functions and set of extensions to make me productive. It’s not for everyone, but luckily I don’t have to be everyone.

org-mode is the organization mode par excellence. It allows you to write in plain text, but it has enough programmatic helpers to supercharge your performance. For example it can:

  • Write documents with foldable headings, links, formatting, mathematics, and media
  • Maintain a To-Do list
  • Maintain an agenda of meetings and events
  • Tag your content and search amongst it
  • Write documents that export to LaTeXed PDFs or Markdown, amongst other formats
  • Do spreadsheet calculations
  • Interlace program code and text in a literate programming way
  • Create new files, heading or tasks quickly (org-capture)

You can use as much or as little of these capabilities as you want.

org-roam uses the structure provided by org-mode to maintain a sort of digital Zettelkasten system. Topics are single files or headings in a file. You can easily link between topics and get backlinks (topics that have linked to this one). By sufficient linking, you can start to form a web of ideas. It maintains all the link and note data invisibly via a SQLite database.

I keep the Exocortex within a git repository, so I can keep a running history or restore things if I accidentally programmatically destroy everything. My interaction with the git repository is automatic, so there’s no thought given to all the complexity that git offers (or threatens with).

I have experimented with exporting my Exocortex into HTML. This is only moderately useful and I’ll talk about later.

You could recreate this system with denote in Emacs, or Obsidian, but I like this setup.

Some nomenclature

Note-taking

A note is the building block of a knowledge system. An accumulation of linked notes is a knowledge system.

Notes associate with one another via links. Links are unidirectional and specific.

Tags are a way to collect notes together2. A note has a property storing the appropriate tags for that note (eg. technique, productivity). Each tag is like a link to a note with that tag. Some people have a note corresponding to a tag, either to make things more explicit, or to provide explanation about a tag.

Categories are even more general than tags. Often they are used to denote the type of note, rather than any indication to the content. You might have a category of explanations so you can examine all explanatory notes, regardless of how they interrelate.

Knowledge systems can often intersect with other organizational tools like calendars or to-do lists. org-mode encourages this. I tend to separate them out because I want my Exocortex to be my understanding of the world, not just administrivia. I do blur that, though.

Technical

I won’t give a tutorial on org-mode or org-roam (see here and here for them), but want to give some terminology to explain the ideas.

org-mode files are individual text files. They are easily human-readable but they include some text markup to aid in organization.

An org-mode file contains a number of headings. Each heading can have properties, some of which might be a unique ID, a DEADLINE or whatever you like.

org-roam uses the ID property to identify a particular note. As of version 2, a note can be an entire file (if you have a top-level ID) or a particular heading. Or both!

org-mode has tags that associate to a particular heading. You can also have FILETAGS so at the top of a file, it adds these tags to all headings.

org-mode also has CATEGORY for files. These are broad labels, and not as fine-grained as tags.

Using org-mode capture (org-capture) lets you quickly create a file or heading, depending on how you set it up. org-roam has its own extension to org-capture, specific to org-roam but works pretty much the same.

How it’s organized

Main areas

In its current format, my Exocortex keeps a web of notes, and a separate set of daily reflections. The idea is that when I start work for the day, rather than leaping into email or social networks, I’ll reflect on how my day had started, what I plan to do, how I plan to do it and how I felt about things.

Really there’s no difference between notes and dailies - dailies are just notes with a timestamp title (eg 2022-11-22). I also have some shortcuts that switch to or create the daily reflection super-quick via (org-roam-dailies-goto-today).3

Dailies tend to link to other notes, but notes are supposed to be timeless, or at least evergreen - accumulating and tended to over time. I’ve experimented with recording creation and modification times, but it doesn’t turn out to be as useful as I feel it should be.

Example of a note

Here’s my note on Second Brain:

secondbrain.png

which looks like this in raw form:

`orgmode :PROPERTIES: :ID: 57b9dccc-8e60-4594-91f6-f9ce9215d425 :mtime: 20221229214730 20220711162759 20220711094059 20220710214445 :ctime: 20220710214445 :ROAM_ALIASES: “Building a Second Brain” :END:

+TITLE: Second Brain

+CATEGORY:

+FILETAGS: :STUB:knowledge-management:

Tiago Forte worked on codifying making your own “Second Brain” ([[id:e01ea9f7-7bf8-4bc1-a869-01238de36f95][Exocortex]], in my terminology). He’s spun a business out of it, and it’s done well. The title of the accompanying book is /Building a Second Brain: A Proven Method to Organize Your Digital Life and Unlock Your Creative Potential/.

Forte recommends using a [[id:9f8fe129-2600-48b0-8cea-cd974f857aaf][digital knowledge management tool]].

Building A Second Brain has a number of tools, given by 4 letter words: - [[id:34cd8446-0892-4440-8e66-6682cc992734][PARA Method]] - [[id:9f96ff23-333d-4635-a0ec-4bde33ce3362][CODE system]]

  • Links

  • [[https://buildingasecondbrain.com][Building a Second Brain website]]

  • [[https://www.artofmanliness.com/character/advice/podcast-816-building-a-second-brain/][Art of Manliness #816: Building a Second Brain]] “`

A good note has an economical description of the idea, related topics and links to further articles. Over time it should build up, but also reduce down - adding a little more insight may allow you to rewrite the note more tightly and more correctly.

It should ideally be a single topic, but that topic might be:

  • A concept
  • A list of brainstormed ideas
  • A grouping of things
  • About a single object in the world (eg car or appliance)

The ingress path

The easiest way to create a note is just browsing to a new note, or linking to one. This creates a simple templated file in the right place with all the right metadata. But this exists on my desktop. What if I want to do this while I’m out and about?

I have two methods: my phone and my commonplace book.

I use Orgzly on my phone with a home screen fast link that will write an org-mode heading in an Inbox file. This (ignoring the idiosyncrasies of Orgzly and synching) will synch via Dropbox.

This path has overtaken my previous way of recording interesting papers or websites to read later. I used to use Pocket, but on almost every axis (search, link curation, tagging, insights) it disappoints. With Android’s share functionality, I can get Orgzly to add papers or links to the inbox as quick as I could with Pocket.

My commonplace book is a Moleskine notebook with bookmarks and a dedicated pen stuck in it. It fits in my pocket. If I’m sans phone, want to be more thoughtful about the entry, or just in a place where writing or drawing is faster, I’ll use my commonplace book. It’s very low-tech but it works.

I have a reminder every Wednesday to go through my Exocortex inbox, which means the Orgzly inbox file and the most recent commonplace book notes. I manually input them via my desktop. This helps me tune the notes to be more descriptive and useful, and think more about my notes’ contents.

I have thought about more advanced and automatic methods like scanning, but the slow and deliberate practice is actually useful for making the content go through my brain before it goes into the Exocortex.

Hierarchies or not?

In a previous iteration of my Exocortex, I went all in on hierarchies. I wanted to put all my different notes into separate categories. I’d create a new note with org-capture and it’d ask me to choose the type of note. The categories I had:

Concepts
Base concepts like a mathematical or technical definition. Examples: “elliptic curve”, or “Continuous Integration”
Questions
Explicit questions that the note would attempt to answer, or run through the thinking. Examples: “How would I triage 10,000 text titles into categories?” or “How do you create a random safe prime?”
Feynman Distillations
A method attributed to Richard Feynman is also called “progressive summarization”. You need to teach a topic to a patient, intelligent child, so you write the explanation. Read back over it to find any gaps, leaps of logic, and then rewrite to improve it.
Projects
Nexus points for keeping notes on bodies of work.

When exporting to HTML each category would be sorted into a list of topics. It soon became comically obvious that the vast amount of notes are Concepts. The only benefit was if I knew I had written a Question, but not the exact name, I could browse the small number of question notes. Of course, this advantage diminishes with use.

My home exocortex has done away with categories, organizing content via tags and links. You can expose the link structure via org-roam-ui. I also use “guide notes” which are particular jumping-off points, like the “notes for tags” example mentioned above. Example guides:

My Projects
Links to the main notes for each creative project I’m working on.
House guide
Links to every aspect of our house - appliances, emergency procedures, neighbours, network information.
Health guide
Links to notes on medication, doctor’s visits and health topics for me and my family.

Even though these are a little bespoke and manual, it helps me be mindful about linking things together and allows me to add context. The automatic categorization was easy but if it takes zero thought, then you get what you paid for.

What to capture

In short, everything. If it’s useful and I could forget any part of it, then it should go into the Exocortex.

I record all sorts of trivial data for my appliances and vehicles, like registration numbers, service records and things like that. It’s better to record and forget them, than try to find them under duress, or try to remember vague memories of last year. For example, collecting the service logs of my car allows me to keep a second record of them outside of the book in my car, and predict when and how much the next service will take.

I used to keep a wide array of design notes for different projects, scattered in their project folders or what-have-you. Keeping them in my Exocortex instead allows me to find them easier and link them together. By linking them ideas can migrate between projects and are not lost if I abandon a project.

I don’t tend to include much timestamping in the notes themselves. I’ve seen people try to keep old notes, marked up by time, alongside the newest versions. I’ve rarely found this useful, and would prefer to include the reasons why my thinking updated in the discussion itself.

I’ve begun using org-cite to keep a bibliography, in case I want to refer to particular books, papers, videos or websites. BibTeX is clunky as hell, so I don’t do this as much as I should. Ideally I’d have a note for a particular paper and a cross-reference would know how to assemble a bibliography out of properties.

Given org-mode lets you include source code blocks and run them, I found it very useful to write example code as a note. For example, I might have a mathematical example that I step through using Magma code. It will be a nice curated example that I can hit C-c C-c on, and it’ll run it and put the results into the note itself. This replaces the time-honoured scrap file hidden in some directory somewhere where I figured out how to achieve some task. This way I can keep a good example, link it to the relevant concepts, and even use the example code to explore different variations.

Advanced Topics

Basic Setup

I have my files under ~/Projects/exocortex.

The file hierarchy looks like this: . ├── attach/ (File attachments to notes) ├── daily/ (Daily notes) ├── data/ (Extra computed data) ├── exocortex.db (org-roam's SQLite database for the Exocortex) ├── images/ (Static images for category titles for exporting) ├── index.org (Front page for exporting) ├── nodes/ (Every other note as .org files) ├── references.bib (BibTeX references) └── static/ (Static CSS or JS for the export)

All daily notes go into daily. All other notes go into nodes with no further directory structure. Putting them in their own directories just keeps everything tidy, and allows files like index.org to be considered separately.

The basic org-roam setup code:

`lisp ;; To migrate fully to org-roam v2 (setq org-roam-v2-ack t)

(use-package org-roam :config ;; Where the Exocortex files live (setq org-roam-directory (file-truename “~/Projects/exocortex/”)) ;; Where daily notes live, under the main directory (setq org-roam-dailies-directory “daily/”) ;; Branding customization for the Backlinks buffer (setq org-roam-buffer “Exocortex“) ;; Where the Exocortex database is located (setq org-roam-db-location (file-truename “~/Projects/exocortex/exocortex.db”)) ;; My custom variable to know where my exported front page is (setq org-roam-index-file “/home/brettw/Projects/exocortex/index.org”) ;; Which completion system I use (setq org-roam-completion-system ‘helm)

;; I set the attach directory here because I mostly only attach files to a Exocortex note (setq org-attach-id-dir “/home/brettw/Projects/exocortex/attach/”)

; Exclude data/ or index.org from the Exocortex (setq org-roam-file-exclude-regexp (rx (or “data/” “index.org”)) ) (setq org-roam-graph-exclude-matcher ‘(“index.org”)) (require ‘org-roam-protocol) (require ‘org-roam-export) ) “`

I also use two other packages, org-roam-timestamps and org-roam-ui. The first allows for easy recording of creation and modification timestamps inside org-mode properties. I used to use Emacs default timestamp package, but that encouraged me to include the timestamps in the note text itself.

org-roam-ui creates a web server that displays your Exocortex as a dynamic graph. This makes it easy to explore the Exocortex —- for example, finding nodes with no links to or from them —- and it synchronises with your browsing and editing in Emacs.

exocortex-2022-09.png

To set these both up:

`lisp (use-package org-roam-timestamps :after org-roam :config (org-roam-timestamps-mode))

(use-package org-roam-ui :after org-roam :hook (after-init . org-roam-ui-mode) :config (setq org-roam-ui-sync-theme t org-roam-ui-follow t org-roam-ui-update-on-save t org-roam-ui-open-on-start nil)) “`

Keys

I use the prefix of C-c r for my Exocortex key bindings (r for roam).

  • If I want to insert a link to another note: C-c r i
  • If I want to find another note: C-c r f
  • If I want to see the backlinks and other org-roam info: C-c r r

Templates

Since jettisoning categories, my capture templates are very simple. I also use the nice pattern of making the templates actual org files that I can edit easily, rather than messing with my config too much.

`lisp (setq org-roam-capture-templates ‘( (“n” “Node” plain (file “~/org/templates/exocortex-node.org”) ;; Put all notes in the nodes/ directory :if-new (file+head “nodes/${slug}.org” “#+TITLE: ${title}\n#+FILETAGS: :STUB:\n”) :unnarrowed t :immediate-finish t ) ))

(setq org-roam-dailies-capture-templates ‘((“d” “General daily” entry (file “~/org/templates/exocortex-daily.org”) :if-new (file+head “%<%Y-%m-%d>.org” “#+TITLE: %<%Y-%m-%d>\n#+CATEGORY: daily\n#+INCLUDE: ~/org/templates/exocortex-head.org”) :unnarrowed t :immediate-finish t ) )) “`

Of note is that I always give a note a STUB tag. This identifies notes that need work. So when I automatically create a note by linking to a currently non-existent note, it tags it as unfinished.

Finding random stub articles

Now that we automatically mark new notes with STUB, we need a way to jump to random ones when we are in the Organization phase of CODE (aka when we are gardening).

The code is very simple: “`lisp (defun org-roam-is-stub-p (node) “Is this org-roam node a STUB?” (member “STUB” (org-roam-node-tags node)) )

(defun org-roam-random-stub () “Get a random node with the STUB tag. ” (org-roam-node-random nil ‘org-roam-is-stub-p)) “`

I also add (org-roam-random-stab) to my initial-scratch-message so I can jump to a random stub from my scratch buffer via C-x C-e.

Exporting

While nowadays I prefer to use org-roam-ui to visualize my Exocortex, I did spend a long time finetuning how to export to HTML. This creates a website with a main front page, and all the notes underneath.

While I have my notes under ~/Projects/exocortex/, I publish them to ~/Projects/websites/exocortex/. If you wanted to make them public, you could simply rsync them to your website. While I flirted with the idea of a public exocortex, I think the main benefit of the notes are for me, and I want to write for myself, not an audience.

In any case, publishing org-mode files is very easy. This code sets up all the sundry bits that go into the final webpage.

`lisp ;; My custom HTML export (see below) (require ‘exocortex)

(setq org-publish-project-alist ( list

    ;; Export the Exocortex project as a collection of smaller projects
    '("exocortex"
      :components ("exocortex-html" "exocortex-nodes" "exocortex-css" "exocortex-js" "exocortex-images"))

    ;; Export the index file
    '("exocortex-html"
      :base-directory "~/Projects/exocortex"
      :base-extension "org"
      :publishing-directory "~/Projects/websites/exocortex/"
      :publishing-function org-exocortex-publish-to-html
      )

    ;; Export the individual note nodes
    '("exocortex-nodes"
      :base-directory "~/Projects/exocortex/nodes/"
      :base-extension "org"
      :publishing-directory "~/Projects/websites/exocortex/nodes/"
      :publishing-function org-exocortex-publish-to-html
      )

    ;; Export the static CSS
    '("exocortex-css"
      :base-directory "~/Projects/exocortex/static/"
      :base-extension "css"
      :publishing-directory "~/Projects/websites/exocortex/css/"
      :publishing-function org-publish-attachment
      )

    ;; Export the static JS
    '("exocortex-js"
      :base-directory "~/Projects/exocortex/static/"
      :base-extension "js"
      :publishing-directory "~/Projects/websites/exocortex/js/"
      :publishing-function org-publish-attachment
      )

    ;; Export images
    '("exocortex-images"
      :base-directory "~/Projects/exocortex/images/"
      :base-extension "svg\\|jpg\\|png\\|gif"
      :publishing-directory "~/Projects/websites/exocortex/images/"
      :publishing-function org-publish-attachment
      )
    )
  )

;; Always publish all files, because some of the inclusions/references are non-obvious to org (setq org-publish-use-timestamps-flag nil)

;; Set the default doctype to be HTML5 (setq org-html-doctype “html5”) “`

To publish the entire Exocortex, just M-x org-publish-project and select exocortex, or if you’re viewing an Exocortex node already, just M-x org-publish-current-project. While working on styling it with CSS, you can just use M-x org-publish exocortex-css to save time.

The tricky bit getting all the styling working. org-mode exports org files to HTML out-of-the-box with some straightforward transformations, but if you want strong control over the layout, you need to create your own export method, which I’ve done in exocortex.el. The code for this is too complicated and messy to quote here, so just grab it from my gist.

Also in that gist is my index.org which is a macro- and dynamic-block-heavy org file. The dynamic blocks allow you to create an index of note links, and the macros help with styling using Bootstrap. The code supporting the dynamic blocks is in category.el. It basically searches the database and assembles the org-mode text corresponding to the links per category.

This code also associates a category image (from images/) to a category as the header for a card. Basically you get a nice image per category.

You can do similar things with tags, but since I’ve moved away from exporting to HTML altogether, I don’t have the code readily available.

Transclusion

One mind-blowing technique I’m trying to explore is the use of transclusion. org-transclusion by Nobiot allows you to include text from other files that is linked to the original. You can edit that file when transcluded, or update the original and have the transcluded content update in real-time. Moreover, the file including the transcluded content never copies that content.

My setup:

lisp (use-package org-transclusion :after org :bind (("C-c t i" . org-transclusion-add) ("C-c t r" . org-transclusion-remove) ("C-c t R" . org-transclusion-remove-all) ("C-c t <tab>" . org-transclusion-refresh) ("C-c t m" . org-transclusion-mode)) )

So you can add to any note

`orgmode

+transclude: [[57b9dccc-8e60-4594-91f6-f9ce9215d425][Second Brain]]

`

and the text from that note will be included once you hit C-c t i (org-transclusion-add). The fringe is marked so you know it’s transcluded text. Whilst the point is over this region, you can hit o to browse the original file, g to refresh it, or even e to live-sync edit it.

Of course there’s always #+INCLUDE: other_file.org which I often use for standard headers like global LaTeX definitions or org-mode macros.

I haven’t yet picked up transclusion as a common thing to do - my focus on file notes rather than heading notes probably makes this harder to use. But you can always use it to include things like source code or bits of text.

Automatic and AI techniques

One thing I’ve thought about but not chased down is the application of programmatic or artificial-intelligence-powered techniques. Ideas in this space

Activity calendar
For dailies or notes in general, get the creation/modification times and see how productive you were over the year, like Github’s contribution graph. You could weight by actual words written, in case you went on a stub-article-creating frenzy.
Automatic tagging
Suggest tags based on the text. This would have to learn from your own tagging system.
Suggested links
Go through the text and find things that should be links to other notes. You may want to use the Wikipedia style of only linking the first instance, though.
Zeitgeist capture
Order your notes by modification time and topic model over time. You can see if your interest in certain areas waxes or wanes over time.

Links to other resources

Here’s a number of exocortices, for inspiration or learning from.

If you have any questions, comments or want to share your knowledge system, hit me up on Mastodon or Twitter.


  1. Some use the phase “personal knowledge management system”. I omit “management” because I think the system is the focus, encompasses management, and the management isn’t the focus — the knowledge is. 

  2. Tags are also good for controlling export. You can omit notes by adding a private tag, or go one further and use encrypt so that the note file itself is encrypted if you set up org-encrypt

  3. I’ve modified initial-scratch-message in my Emacs setup to include the text (org-roam-dailies-goto-today) so I can jump into my daily from starting Emacs just with C-x C-e