Implementation of the personal wiki site Roam Research using GNU Emacs and org-mode.


  • make your own wiki with backlinks and cross-references
  • works on org-mode files (plain text, uses a database but all data is stored in the files themselves)



collect backlinks and put them in a div at the bottom of each page:

(defun collect-backlinks-string (backend) ;; collect org-roam backlinks and format
      (when (org-roam-node-at-point)
        (let* ((source-node (org-roam-node-at-point))
               (source-file (org-roam-node-file source-node))
               (nodes-in-file (--filter (s-equals? (org-roam-node-file it) source-file)
               (nodes-start-position (-map 'org-roam-node-point nodes-in-file))
               ;; Nodes don't store the last position, so get the next headline position
               ;; and subtract one character (or, if no next headline, get point-max)
               (nodes-end-position (-map (lambda (nodes-start-position)
                                           (goto-char nodes-start-position)
                                           (if (org-before-first-heading-p) ;; file node
                                             (if (> (point) nodes-start-position)
                                                 (- (point) 1) ;; successfully found next
                                               (point-max)))) ;; there was no next
               ;; sort in order of decreasing end position
               (nodes-in-file-sorted (->> (-zip nodes-in-file nodes-end-position)
                                          (--sort (> (cdr it) (cdr other))))))
          (dolist (node-and-end nodes-in-file-sorted)
            (-let (((node . end-position) node-and-end))
              (when (org-roam-backlinks-get node)
                (goto-char end-position)
                ;; Add the references as a subtree of the node
                (setq heading (format "\n\n%s References\n"
                                      (s-repeat (+ (org-roam-node-level node) 1) "*")))
                (insert heading)
                (setq properties-drawer ":PROPERTIES:\n:HTML_CONTAINER_CLASS: references\n:END:\n")
                (insert properties-drawer)
                (dolist (backlink (org-roam-backlinks-get node))
                  (let* ((source-node (org-roam-backlink-source-node backlink))
                         (properties (org-roam-backlink-properties backlink))
                         (outline (when-let ((outline (plist-get properties :outline)))
                                      (mapconcat #'org-link-display-format outline " > ")))
                         (point (org-roam-backlink-point backlink))
                         (text (s-replace "\n" " " (org-roam-preview-get-contents
                                                    (org-roam-node-file source-node)
                         (reference (format "%s [[id:%s][%s]]\n%s\n%s\n\n"
                                            (s-repeat (+ (org-roam-node-level node) 2) "*")
                                            (org-roam-node-id source-node)
                                            (org-roam-node-title source-node)
                                            (if outline (format "%s (/%s/)"
                                            (s-repeat (+ (org-roam-node-level node) 3) "*") outline) "")
                   (insert reference)))))))))

(add-hook 'org-export-before-processing-hook 'collect-backlinks-string)

Links to this node

How to embed handwritten content in your org-roam site

(Transcript > The Setup > Write)

  • In Write, set Preferences -> Advanced -> File Type to SVG - create a Write document in the org source directory you keep your org-roam files in. - write your stuff. Consult the Write docs for info on the various features.


This site is created using GNU Emacs and org-mode (specifically org-roam). There are also handwritten notes created with Stylus Labs Write.