Quartz is a tool which builds a “digital garden” which is navigable through a nice web UI. Perfect for sharing notes. It wasn’t entirely clear how to get it to hook into org roam at first, but this is my configuration.

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))
(straight-use-package 'use-package)
(setq straight-use-package-by-default t)
 
(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
 
(use-package org
  :bind (("\C-ca" . org-agenda)
         :map org-mode-map
         ("C-c l" . org-store-link)
         ("C-c s" . ja/windows-screenshot))
 
  :config
  (setq org-ellipsis " ▾"
        org-hide-emphasis-markers t
        org-image-actual-width '(550)
        org-src-fontify-natively t
        org-enforce-todo-dependencies t
        org-fontify-quote-and-verse-blocks t
        org-src-tab-acts-natively t
        org-edit-src-content-indentation 2
        org-hide-block-startup nil
	org-confirm-babel-evaluate nil
	org-todo-keywords
        '((sequence "TODO" "NEXT" "WAITING" "BLOCKED" "DONE"))
        org-src-preserve-indentation t
        org-startup-folded 'content
        org-cycle-separator-lines 2
        org-modules nil
        org-directory (cond
                       ;; it's in the roaming data
                       ((eq system-type 'windows-nt) "\\..\\..\\docs\\")
                       ;; done via syncthing
                       ((eq system-type 'darwin) (concat (getenv "HOME") "/docs/"))
                       ;; use dropbox on home computer
                       (t (concat (getenv "HOME") "/")))
        org-agenda-files (directory-files-recursively org-directory "org$")
        org-refile-targets '((nil :maxlevel . 9)
                             (org-agenda-files :maxlevel . 9))
        org-outline-path-complete-in-steps nil         ; Refile in a single go
        org-refile-use-outline-path t                  ; Show full paths for refiling
        org-log-done 'note
 
        )
 
  (set-face-attribute 'org-document-title nil :font "Vollkorn" :weight 'bold :height 1.3)
  (dolist (face '((org-level-1 . 1.2)
                  (org-level-2 . 1.1)
                  (org-level-3 . 1.05)
                  (org-level-4 . 1.0)
                  (org-level-5 . 1.1)
                  (org-level-6 . 1.1)
                  (org-level-7 . 1.1)
                  (org-level-8 . 1.1)))
    (set-face-attribute (car face) nil :font "Vollkorn" :weight 'medium :height (cdr face)))
  ;; Make sure org-indent face is available
  (require 'org-indent)
 
  ;; Ensure that anything that should be fixed-pitch in Org files appears that way
  (set-face-attribute 'org-block nil :foreground nil :inherit 'fixed-pitch)
  (set-face-attribute 'org-table nil  :inherit 'fixed-pitch)
  (set-face-attribute 'org-formula nil  :inherit 'fixed-pitch)
  (set-face-attribute 'org-code nil   :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-indent nil :inherit '(org-hide fixed-pitch))
  (set-face-attribute 'org-verbatim nil :inherit '(shadow fixed-pitch))
  (set-face-attribute 'org-special-keyword nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-meta-line nil :inherit '(font-lock-comment-face fixed-pitch))
  (set-face-attribute 'org-checkbox nil :inherit 'fixed-pitch)
 
  ;; Get rid of the background on column views
  (set-face-attribute 'org-column nil :background nil)
  (set-face-attribute 'org-column-title nil :background nil)
  ;; maybe https://github.com/alphapapa/magit-todos ?
) ; close opening from org block.
 
 
 
(use-package org-roam
  :after org
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n g" . org-roam-graph)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n c" . org-roam-capture)
         ("C-c n t" . org-roam-tag-add)
         ;; Dailies
         ("C-c n j" . org-roam-dailies-capture-today))
  :init
  (setq org-roam-v2-ack t
        org-roam-directory (concat org-directory "roam/"))
 
  :config
  (org-roam-db-autosync-mode)
 
  ;; link to my journal node on dailies insertion
  (setq org-roam-dailies-capture-templates
	'(("d" "Journal" entry "* %?"
           :if-new (file+head+olp "%<%Y-%m-%d>.org"
	  	  	          "#+title: %<%Y-%m-%d>\n[[id:81A8F7B2-5E27-4469-9473-97AAF9BFA104][journal]]\n"
		  	          ("Journal")))))
 
  ;; If using org-roam-protocol
  (require 'org-roam-protocol))
 
 
(use-package ox-hugo
  :ensure t
  :pin melpa
  :config (setq org-hugo-front-matter-format "yaml")
  :after ox)
 
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(safe-local-variable-values
   '((org-cite-csl-styles-dir . "./cite/csl/")
     (org-export-allow-bind-keywords . t)
     (eval toggle-truncate-lines 1)
     (eval require 'ox-texinfo+ nil t)
     (eval require 'ol-info)
     (org-src-preserve-indentation)
     (eval require 'ol-man nil t)
     (eval require 'magit-base nil t)
     (eval setq-local org-fold-core-style 'overlays)
     (eval and buffer-file-name
	   (not
	    (eq major-mode 'package-recipe-mode))
	   (or
	    (require 'package-recipe-mode nil t)
	    (let
		((load-path
		  (cons "../package-build" load-path)))
	      (require 'package-recipe-mode nil t)))
	   (package-recipe-mode)))))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )
 
(load-theme 'manoj-dark) ;; so I can read the M-x line in terminal mode
 
(setq org-hugo-base-dir (expand-file-name "~/quartz/"))
(setq org-export-select-tags '())
(setq org-plantuml-jar-path (expand-file-name "~/plantuml-1.2024.6.jar"))
 
 
(defun my/org-get-filetags (e)
  ; per https://emacs.stackexchange.com/questions/75952/how-can-i-retrieve-org-file-meta-data-filetags-from-an-org-element-parse-buff
  (let ((type (org-element-type e))
        (key (org-element-property :key e))
        (value (org-element-property :value e)))
    (if (and (eq type 'keyword) (equal key "FILETAGS"))
        (split-string value ":"))))
 
(defun flatten-list (list-of-lists)
  "Flatten a LIST-OF-LISTS into a single list."
  (apply 'append list-of-lists))
 
(require 'cl-lib)
(defun string-lists-intersect-p (list1 list2)
  "Return t if LIST1 and LIST2 have any elements in common, nil otherwise."
  (not (null (cl-intersection list1 list2 :test 'string=))))
 
 
;; TODO: There's an odd interaction w/ file tags & headlines. Removing file tags works, but that's not quite what I'd prefer to happen.
(defun abrahms/ox-hugo-org-publish (plist filename pub-dir)
  (message "Was asked to export %s" filename)
  ;;; skip dailies
  (if (not (string-match-p (regexp-quote "/daily/") filename))
      (with-current-buffer (find-file-noselect filename)
	(let ((tags (flatten-list (org-element-map (org-element-parse-buffer) '(keyword) #'my/org-get-filetags))))
	  (if (not (string-lists-intersect-p tags org-export-exclude-tags))
	      (org-hugo--export-file-to-md filename)
	    (message "Didn't export. Found one of the exclude tags (%s) in the file's tags (%s)" org-export-exclude-tags tags)
	    )))))
 
(setq org-publish-project-alist
      '(("quartz"
	 :base-directory "~/roam/"
	 :publishing-directory "~/quartz/"
	 :select-tags '()
	 :recursive t
	 ;; :publishing-function org-hugo-export-wim-to-md
	 ;; :publishing-function org-hugo--export-subtree-to-md
	 ;; :publishing-function '((lambda (plist fname pubdir &rest rest) (message plist fname pubdir rest)))
	 ;; pubfn signature example: (org-latex-publish-to-pdf PLIST FILENAME PUB-DIR)
	 :publishing-function abrahms/ox-hugo-org-publish
	 :author "Justin Abrahms"
	 :email "justin@abrah.ms"
 
	 ))
      org-export-with-broken-links t
      org-export-with-tasks nil
      org-export-with-tags nil
      )

This was originally developed in a virtual machine with no dependencies. These are what I required to get it up and running.

sudo apt-get update
sudo apt install -y emacs git ca-certificates curl gnupg tmux build-essential linux-headers-`uname -r`
sudo apt autoremove
 
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt install -y nodejs
 
# mount dropbox links from host machine
sudo mkdir /media/cdrom
sudo mount -t iso9660 /dev/cdrom /media/cdrom
sudo /media/cdrom/./VBoxLinuxAdditions.run
mkdir roam
sudo mount -t vboxsf roam ~/roam
cd roam/
sudo vi /etc/fstab
sudo vi /etc/modules
sudo reboot
 
# Install quartz
git clone https://github.com/jackyzha0/quartz.git
cd quartz/
npm i
npx quartz create