1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
|
[[!meta title="Zettelkasten for Regular Emacs Hackers"]]
[[!meta copyright="Copyright © 2025 Christian Tietze"]]
[[!inline pages="internal(2025/info/zettelkasten-nav)" raw="yes"]]
<!-- Initially generated with emacsconf-publish-talk-page and then left alone for manual editing -->
<!-- You can manually edit this file to update the abstract, add links, etc. --->
# Zettelkasten for Regular Emacs Hackers
Christian Tietze (he) - [@ctietze@mastodon.social](https://mastodon.social/@ctietze) <https://christiantietze.de> <https://zettelkasten.de>, <mailto:hi@christiantietze.de>
[[!inline pages="internal(2025/info/zettelkasten-before)" raw="yes"]]
There's this one thing you can do with your Emacs that is not chiefly a technological problem to solve: thinking through writing.
Emacs offers a malleable environment where you can tweak every key stroke, and every pixel on screen to your needs.
Since we're all here at EmacsConf, the intention is clear: to use and enjoy Emacs, and spend our lives in this amazing environment.
While it's easy to ditch modern UI conveniences and pull technology like email, chat, database and server management, and editing book drafts into Emacs – well, these are tasks that have been implemented, for which there exist alternatives, and which you can teach Emacs to do in a similar way.
Oversimplifying: we can copy and tweak existing solutions and have a good life.
Now while everyone's email needs to use the same protocol, everyone's approach to _thinking_ is different. There's no cookie cutter solution to merely rewrite in Emacs Lisp. We all need to figure out how to do this on our own, and then find an implementation that suits our needs. (Including using paper, but we're not talking about paper here.)
**This is where I want to show you one simple foundational method to deep thinking, understanding, and problem solving:** create yourself a Zettelkasten, an environment of linked notes that scales well over decades, so that you can take it with you into retirement and beyond for a lifelong journey of learning.
For this presentation, I merely assume that you agree that writing improves the quality and depth of thought. I also assume that you know how to type and move around in Emacs. The rest is just convention, and we'll walk through a couple of examples and exercises together so that after this talk, you're equipped with the simple tools that help you unlock new insights in your future.
## About Christian
Christian is a macOS/iOS developer with a strong focus on user experience and clean architecture. Driven by a passion for accessibility and performance, Christian has shipped many apps and authored three technical books and 895+ blog posts, helping developers world-wide to realize their app ideas with a deep understand for the technologies they use. In 2013, Christian wrote about the Zettelkasten topic on his own personal blog and eventually moved everything over to <https://zettelkasten.de> where he and Sascha continue to teach and write.
## Code and Notes from the Talk
### Minimal Emacs + Denote Configuration
This is the relevant configuration Christian used in the Emacs demo. Save this to a folder as `init.el`, and launch via:
$ emacs -nw --init-directory . init.el
`init.el` contents:
```elisp
(load-theme 'modus-vivendi-tinted) ;; Dark theme to match dark slides
(menu-bar-mode -1) ;; Disable topmost menu bar
(package-refresh-contents)
(use-package denote
:ensure t
:hook (dired-mode . denote-dired-mode)
:bind
(("C-c n n" . denote)
("C-c n r" . denote-rename-file)
("C-c n l" . denote-link)
("C-c n c" . denote-link-after-creating)
("C-c n b" . denote-backlinks)
("C-c n d" . denote-dired)
("C-c n g" . denote-grep))
:config
(setq denote-directory (expand-file-name "./notes/"))
;; Automatically rename Denote buffers when opening them so that
;; instead of their long file name they have, for example, a literal
;; "[D]" followed by the file's title. Read the doc string of
;; `denote-rename-buffer-format' for how to modify this.
(denote-rename-buffer-mode 1))
;; For the demo, I forced notes to show in full screen by default.
(setopt display-buffer-alist nil)
(add-to-list 'display-buffer-alist
'("^\\[D\\] " ;; Denote buffer name prefix
(display-buffer-reuse-mode-window display-buffer-full-frame)
))
```
### Notes created during the demo
These are the notes Christian created during the recording. The recording was sped up 3x--4x, so this could be nicer to read than having to squint at the video:
#### `20251121T204827--mechanics-and-habits-to-use-a-zettelkasten__zettelkasten.org`
```org
#+title: Mechanics and habits to use a Zettelkasten
#+date: [2025-11-21 Fri 20:48]
#+filetags: :zettelkasten:
#+identifier: 20251121T204827
Essential:
- Write: put in effort; [[denote:20251121T205045][GIGO]]
- Connect: Link notes to create trails
- Correct: Improve as you go
Additional:
- Design for use: give things a purpose, e.g. blog about it
- Create structure. [[denote:20251121T205312][Types of structures in a Zettelkasten]]: design new entry points and trails
- Start in the Zettelkasten: use the system to learn, make it grow, get better
- Start with a link: keeps your notes connected. [[denote:20251121T210416][Create notes as link first to avoid orphans]]
Tool doesn't matter as much. Small files are good. [[denote:20251121T210107][Use Denote in Emacs]]
(Christian Tietze: Zettelkasten for Regular Emacs Hackers, EmacsConf 2025)
```
#### `20251121T205045--gigo__programming_quality.org`
```org
#+title: Garbage in, garbage out
#+date: [2025-11-21 Fri 20:50]
#+filetags: :programming:quality:
#+identifier: 20251121T205045
The principle known as "Garbage In, Garbage Out" (GIGO) in computer
programming states that for any system, the quality of output is
directly depending on the quality of input.
See: https://en.wikipedia.org/wiki/Garbase_in,_garbage_out
```
#### `20251121T205312--types-of-structures-in-a-zettelkasten__structure_zettelkasten.org`
```org
#+title: Types of structures in a Zettelkasten
#+date: [2025-11-21 Fri 20:53]
#+filetags: :structure:zettelkasten:
#+identifier: 20251121T205312
Non-comprehensive list of structures that could be used in a Zettelkasten:
- Opposition pair: 1 note for the pair, 1 note per position/opposition each; pro/contra
- Table of contents: list of topics/headings
- an outline for a writing project
- recreation of a book's contents (so I can write in detail about the book);
- Argument: recreation of a distilled form to get to a conclusion;
list premises and evidence, and how these support the conclusion
- Counter-argument: address parts of the original argument to support another
view and test the argument's strength
- Table of things
- Graphics, like a concept map, Mind-Map, diagram: visually bring
elements into a relation, then write about the relation and the elements
Metaphors:
- Iceberg: visibile tip with hidden depth; someting that appears small
but is large; good metaphor for obstacles
- Black box: focus on inputs and outputs, and ignore the 'how' in the middle
- e.g. most Emacs Lisp functions (hoping the documentation is good)
- [[denote:20251121T205739][Atom, molecule, organism]]: how small parts compose to larger parts,
which compose to even larger pieces
(Christian Tietze: Zettelkasten for Regular Emacs Hackers, EmacsConf 2025)
```
#### `20251121T205739--atom-molecule-organism-metaphor__composition_recursion.org`
```org
#+title: Atom, molecule, organism metaphor
#+date: [2025-11-21 Fri 20:57]
#+filetags: :composition:recursion:
#+identifier: 20251121T205739
Atom: smallest part, indivisible elements
Molecule: comprised of atoms; structure added to combine elements
Organism: comprised of molecules; different level of analysis, irreducible to molecules/atoms
This can be used e.g. for programming: functions compose into larger
functions which compose into packages.
Actual biological organisms also work in such a way. Organs are part
of bodily functions (high abstraction), but from a chemical or
physical perspective, you can decompose them into atoms. That doesn't
tell you anything about the organ's function.
```
#### `20251121T210107--denoteel-for-zettelkasten-in-emacs__denote_emacs_zettelkasten.org`
```org
#+title: Denote.el for Zettelkasten in Emacs
#+date: [2025-11-21 Fri 21:01]
#+filetags: :denote:emacs:zettelkasten:
#+identifier: 20251121T210107
While not shipping with Emacs out of the box, Denote is easy to install and a great start to manage notes:
- it comes with unified way to create new notes, and hides time-stamped ID's with "[D]" in buffer lists
- it can manage links, and show incoming links to notes ("backlinks")
- it supports quickly adding links, and creating links _first_ out of
the box -- it just creates the note immediately, so you don't notice
- [[denote:20251121T210416][Create notes as link first to avoid orphans]]
* Example configuration
#+BEGIN_SRC elisp
(use-package denote
:ensure t
:hook (dired-mode . denote-dired-mode)
:bind
(("C-c n n" . denote)
("C-c n r" . denote-rename-file)
("C-c n l" . denote-link)
("C-c n c" . denote-link-after-creating)
("C-c n b" . denote-backlinks)
("C-c n d" . denote-dired)
("C-c n g" . denote-grep))
:config
(setq denote-directory (expand-file-name "./notes/"))
;; Automatically rename Denote buffers when opening them so that
;; instead of their long file name they have, for example, a literal
;; "[D]" followed by the file's title. Read the doc string of
;; `denote-rename-buffer-format' for how to modify this.
(denote-rename-buffer-mode 1))
#+END_SRC
```
#### `20251121T210416--create-notes-as-link-first-to-avoid-orphans__linking_zettelkasten.org`
```org
#+title: Create notes as link first to avoid orphans
#+date: [2025-11-21 Fri 21:04]
#+filetags: :linking:zettelkasten:
#+identifier: 20251121T210416
Recommended practice by Christian Tietze: start a new note with a link
first from some place, any place, then create the file to match that
link (which would initially lead nowhere).
- Reduces orphans in the Zettelkasten by guaranteeing every note to
have at least one link.
- Supposedly teaches you to think about possible connections early,
which makes the network better.
A very loosey-goosey approach, when taken literally and used
liberally: it doesn't matter where you are, just leave a forward link
to something you wish existed. Even if it doesn't fit the current
note. After all, you came up with the idea just now -- so maybe
there's a connection that you just can't spell out, yet?
```
[[!inline pages="internal(2025/info/zettelkasten-after)" raw="yes"]]
[[!inline pages="internal(2025/info/zettelkasten-nav)" raw="yes"]]
|