Introducing Zetteldeft

A Zettelkasten for Emacs

NOTE (Mar 2023): Zetteldeft is no longer under active development. The the code is functional and the package remains available, but I am currently exploring note-taking based on Denote rather than on Deft. Feel free to reach out (via Mastodon or email) if you want to exchange ideas.

Zetteldeft is an extension of the Deft package for Emacs. Building on Deft’s search functionality, Zetteldeft provides a way to create and manage links between short notes.

In the spirit of Zettelkasten, Zetteldeft maintains a flat hierarchy at the level of files, but invites authors to create structure and meaning via links and tags. The result is a free-form note taking system of linked notes and ideas. Or, as the original Zettelkasten creator Niklas Luhmann would call it: a partner in communication.1

The text below introduces Zetteldeft, but even easier is the tutorial: get to know Zetteldeft from within Zetteldeft with zd-tutorial on Github. Installation instructions included. Clone it and get started!

Just want source? Take a look at this "literate code", which contains both source and documentation, or simply refer to the Github repository.

I’ve been maintaining this code for personal use since 2018,2 and have been sharing it on Github for a while now. It’s high time for a proper introduction of this package.

One last note: I hope to make this a living document, so expect changes and additions. And feel free to leave comments, for example via Github, Twitter, or (preferably) Mastodon.

A Zettelkasten in Deft

As the name suggests, Zetteldeft is inspired by the now famous Zettelkasten system first implemented by the German sociologist Niklas Luhmann long before Personal Computers made their appearance.

In our digital times, however, a Zettelkasten note-taking system looks a lot like (though is not the same as) a personal wiki for your notes. This introduction won’t attempt to explain what a Zettelkasten is or what you might use it for. To that end, the internet provides various resources, such as the great and their community.3

In this text I want to briefly introduce what Zetteldeft is and mention its core features, so that you can check it out if you’d like.

Key concepts

Following the Zettelkasten philosophy, each note in Zetteldeft should either: (1) contain a core idea, (2) connect different ideas (and link to notes), (3) or contain a structured set of links to other notes.

How you do that is completely up to you, but links between notes are key. And, it should be emphasized, links require work. Work done personally by you, the author, so that your notes might breathe life.4

In Zetteldeft, each note has a unique identifier or ID, based on the time and date of its creation, included at the beginning of its filename. This, fore example, is the name of a file in my Zettelkasten: 2018-07-07-2356 The zetteldeft

Notes contain links to other notes. These links are indicated by prepending the § character to an ID: §2018-07-07-2356 links to the file mentioned above. No other formatting is needed: a plain text § and the ID suffice to create a link. And don’t worry, you won’t have to type the § manually (or the ID for that matter). And yes, you can change this link indicator or even disable it (and include a link suffix, if you so require).

Figure 1: A note with links. The note shown is part of zd-tutorial

The ID combined with Deft’s full text search allow to

  1. retrieve a note via its identifier (by searching file titles),
  2. find out which notes link to a given note (via a full text search).

That’s pretty much all there is to it, for the basics at least. All of this is done in plain text. Org-mode by default, but it really is formatting agnostic.

A way to further organize your notes, is to use tags, indicated with a # (or another string, it’s all customizable). In my Zettelkasten, for example, I use #zetteldeft for all notes related to… Well, you can guess.

Basic functions

A quick introduction

Let’s look at some basic functions you need to get started.

Create a note with C-c d n (or zetteldeft-new-file). Enter a title and you’re set. Zetteldeft will generate a note ID and include it in its filename.

To insert a link to a note, you can use

  • C-c d i (or zetteldeft-find-file-id-insert),
  • or C-c d I if you want to include the title of your destination (which calls zetteldeft-find-file-full-title-insert).

Hit C-c d f (or zetteldeft-follow-link) to follow a link to a note. All link indicators, those § symbols, will be replaced different characters (thanks to the Avy package). Pick one to follow a link. If only one link is available, or if point is in a link, it will be selected automatically.

Use C-c d F to open a link in a separate window of choice. This is especially useful when browsing your own notes, looking for new ideas and connections.

To quickly open one of the notes in your Zettelkasten, use C-c d o (or zetteldeft-find-file) and search the titles. Or simply hit C-c d D to open Deft and start a full text search.

To quickly find out which notes refer to the current note, use C-c d c (which is zetteldeft-search-current-id).

To search a tag, hit C-c d t and select a highlighted tag, similar to how you follow a link. Easily insert tags with C-c d # and select one from the list (or enter a new one). To generate a list of tags currently in your Zettelkasten, use C-c d T. Quickly launch a search for a tag of choice with C-c d /.

There are many more functions, but these will be enough to get you started.

An overview of keybindings

As Zetteldeft does not launch a minor mode, no default keys are bound. You can set keys mentioned in this text by calling zetteldeft-set-classic-keybindings.

For different setups with similar bindings, check the literate source. Personally, I prefer vim style bindings behind a leader key, set up with general, like so.

Table 1: Classic keybindings
Key Function
C-c d d deft
C-c d D zetteldeft-deft-new-search
C-c d R deft-refresh
C-c d s zetteldeft-search-at-point
C-c d c zetteldeft-search-current-id
C-c d f zetteldeft-follow-link
C-c d F zetteldeft-avy-file-search-ace-window
C-c d l zetteldeft-avy-link-search
C-c d t zetteldeft-avy-tag-search
C-c d T zetteldeft-tag-buffer
C-c d # zetteldeft-tag-insert
C-c d i zetteldeft-find-file-id-insert
C-c d I zetteldeft-find-file-full-title-insert
C-c d o zetteldeft-find-file
C-c d n zetteldeft-new-file
C-c d N zetteldeft-new-file-and-link
C-c d r zetteldeft-file-rename
C-c d x zetteldeft-count-words

Sneak peek at more advanced features

As emphasized above, any Zettelkasten system relies on its author for links between notes. There are, however, some features in Zetteldeft that help you with this. For this introduction, I won’t go into detail, but more information is found in the full

There is zetteldeft-insert-list-links to automatically generate a list of links to notes containing a provided search term. Or use zetteldeft-insert-list-links-missing if you only want to include those notes that don’t yet appear in the current note.

Zetteldeft is not limited to Org-mode, but integrates well with source code blocks to, for example, automate generating the lists mentioned above.

You can export your notes to HTML to read them outside of of Emacs, as explained in the documentation.

With the help of graphviz, we can even draw graphical representations of links between notes. Check out zetteldeft-org-graph-search and zetteldeft-org-graph-note in the documentation. It generates something like this:

Figure 2: Example of a graph generated with graphviz.

This feature is fairly crude but easily hackable. Ideas on how to extend or replace it are more than welcome.

Installing & getting started

Installing Zetteldeft

This section will take you through an example Zetteldeft setup and installation. It assumes basic Emacs knowledge, so I’m going to guess you understand that the code below should go in your init.el (or equivalent).

It also assumes that you have use-package installed, that you use MELPA to install Emacs packages, and that you’ll write notes in org-mode.

Prefer Markdown? That’s easy enough to change in the example below.

For different methods of installation, please refer to the documentation.


Zetteldeft relies on Deft. Let’s start with a basic setup.

(use-package deft
  :ensure t
    (deft-extensions '("org" "md" "txt"))
    (deft-directory "~/notes")
    (deft-use-filename-as-title t))

Note that none of these settings are strictly required, apart from changing the default deft-directory.

The deft-use-filename-as-title ensures that we can see the note IDs from the deft buffer, but this can be disabled if you prefer.


Installing Zetteldeft can be done in a similar fashion.

Let’s start bare bones:

(use-package zetteldeft
  :ensure t
  :after deft
  :config (zetteldeft-set-classic-keybindings))

That should be enough to get you started, really.

Installation with Spacemacs

Installation with Spacemacs is easy. Locate dotspacemacs-configuration-layers in your .spacemacs and add the code like so.

(setq-default dotspacemacs-configuration-layers
  '((deft :variables deft-zetteldeft t)))

This should take care of keybindings as well. Take a look in the documentation to see how keys are bound.


Some pointers for further customization:

  • alter zetteldeft-link-indicator to change the prefix to links, or set it to an empty string to remove it altogether,
  • change zetteldeft-title-prefix and zetteldeft-title-suffix to change how titles are appear,
  • you can modify zetteldeft-id-format to change how IDs are generated, but make sure to change zetteldeft-id-regex accordingly so that the new IDs can be detected.

There’s more to Zetteldeft, and to its customization, but that’s all for this introduction.

Using Zetteldeft with Markdown notes

While Zetteldeft works nicely with Org-mode, you can call its functions from any mode. Many people keep Zettelkasten in Markdown, so let’s explore how such a setup can be achieved.

First, make sure deft-extensions is set correctly. If md is the first element on the list, new notes will be Markdown notes. Zetteldeft uses Deft to create new notes, so using zetteldeft-new-file should now create Markdown files.

(setq deft-extensions '("md" "org" "txt"))

In such Zettelkasten links are often wrapped in square brackets. This can be easily achieved by setting the zetteldeft-link-indicator and zetteldeft-link-suffix.

(setq zetteldeft-link-indicator "[["
      zetteldeft-link-suffix "]]")

To make sure that your Markdown notes start with correct title syntax, customize the zetteldeft-title-prefix.

(setq zetteldeft-title-prefix "# ")

When using zetteldeft-insert-list-links, you might want to change a list entry to correct Markdown syntax, like so:

(setq zetteldeft-list-prefix "* ")

To highlight links you need to set up font-lock keywords for markdown-mode.

(font-lock-add-keywords 'markdown-mode
      . font-lock-warning-face)))

Alternatively, if you want to highlight the brackets as well, you need to escape them like so:

(font-lock-add-keywords 'markdown-mode
   `((,(concat "\\[\\["
      . font-lock-warning-face)))



Luhmann was first and foremost a social theorist who developed a unique systems theory. In one of his writings, he compares his Zettelkasten to a "communicative system". Available here in English translation:


Please beware that I’m no programmer. Zetteldeft is written in Emacs Lisp, the only language I can claim to have ever programmed in outside of school, but can’t claim to know well. I use Emacs mainly for writing, both personal and academic, and have fallen in love with its extensibility. My overall experience resonates strongly with this story shared by Richard Stallman:

Multics Emacs proved to be a great success – programming new editing commands was so convenient that even the secretaries in his [Bernie Greenberg] office started learning how to use it. They used a manual someone had written which showed how to extend Emacs, but didn’t say it was a programming. So the secretaries, who believed they couldn’t do programming, weren’t scared off. They read the manual, discovered they could do useful things and they learned to program.


Zetteldeft is inspired by The Archive, created by the guys at


Or, in the words of Luhmann himself:

It is impossible to think without writing; at least it is impossible in any sophisticated or networked (anschlußfähig) fashion.

Quote from 1.