An Obsidian-like note-taking mode for Emacs. One keybinding opens a full workspace with a file tree sidebar and your org notes.
- File tree sidebar with expand/collapse, indent guides, current file tracking, item counts, optional nerd font icons, and note preview on navigation
- Quick capture — just type, first line becomes the title, saved to your inbox
- Wikilinks —
[[note title]]syntax with font-lock, click to follow, create on missing - Backlinks — ripgrep-powered, computed on demand, displayed in a side panel
- Daily notes — one keybinding for today, yesterday, or tomorrow
- Search — full-text ripgrep search with optional Consult integration
- Tag search — find notes by
#hashtagor org:tag:syntax - Inbox review — triage untagged notes
- Graph view — visualize note connections via Graphviz
No database. No external Emacs dependencies. Just org files, a directory, and ripgrep.
- Emacs 29.1+
- ripgrep (
rg) on your PATH
Optional:
- Consult for live search with preview
- Graphviz (
dot) for graph view - Nerd Fonts for file/folder icons in the tree sidebar
Grove is available on MELPA. After adding MELPA to your package archives:
(use-package grove
:ensure t
:bind-keymap ("C-c v" . grove-command-map)
:custom
(grove-directory "~/notes/")
:config
(global-grove-mode 1))global-grove-mode activates grove-mode in any org buffer that lives inside grove-directory, which enables wikilink font-locking and the C-c C-l keybinding for inserting links. Omit it if you’d rather enable grove-mode manually per buffer.
Clone the repository and add it to your load path:
(use-package grove
:load-path "~/path/to/grove"
:bind-keymap ("C-c v" . grove-command-map)
:custom
(grove-directory "~/notes/")
:config
(global-grove-mode 1))Set your vault directory and press C-c v v to open the workspace.
| Key | Command | Description |
|---|---|---|
C-c v v | grove-open | Open the grove workspace |
C-c v q | grove-close | Close and restore layout |
C-c v n | grove-capture | Quick capture a new note |
C-c v f | grove-find | Find note by title |
C-c v s | grove-search | Full-text ripgrep search |
C-c v d | grove-daily | Open today’s daily note |
C-c v b | grove-backlinks | Show backlinks for note |
C-c v t | grove-search-tag | Search by tag |
C-c v i | grove-inbox-review | Triage untagged notes |
C-c v l | grove-link-insert | Insert a wikilink |
C-c v g | grove-graph | Show vault graph |
| Key | Action |
|---|---|
RET | Open file / toggle dir |
TAB | Toggle directory expand |
n / C-n | Next entry (with preview) |
p / C-p | Previous entry (with preview) |
g | Refresh tree |
q | Close sidebar |
C-c v n opens *grove-capture*, a blank org buffer. Type freely — no prompts, no template. The first line becomes the title; everything below becomes the body.
C-c C-csaves to the inboxC-c C-kdiscards
For example, typing:
Project ideas for next quarter
- migrate to ripgrep
- add a graph view
and pressing C-c C-c writes inbox/project-ideas-for-next-quarter.org:
#+title: Project ideas for next quarter
- migrate to ripgrep
- add a graph view
Filenames are derived from the title (lowercased, spaces to dashes). A numeric suffix is appended on collision.
C-c v i opens *grove-inbox*, a triage buffer that lists notes needing attention. The buffer groups notes by the reason they showed up — currently, Untagged: notes with no #+filetags: line and no inline #hashtags.
| Key | Action |
|---|---|
RET | Visit the note at point |
n / p | Move to next / previous line |
g | Refresh the buffer |
q | Close the buffer |
The intended workflow is short loops: open the inbox, jump into a note with RET, add tags or wikilinks, save, and either come back with C-c v i or refresh in place with g. Notes drop off the list as you tag them, so the buffer doubles as a progress indicator.
The list is built from the vault cache, so it covers your whole vault — not just files under grove-inbox-directory. Tag a note anywhere and it disappears from the next refresh.
C-c v g renders a graph of all notes and their [[wikilinks]] using Graphviz. Requires dot on your PATH.
The graph display adapts to your frame width — on wide frames (160+ columns) it opens as a right side panel, otherwise it uses a full buffer. You can override this with grove-graph-display: 'side, 'buffer, or 'auto (default).
Use + / - to zoom in/out and 0 to fit to window.
;; Required: set your vault directory
(setq grove-directory "~/notes/")
;; Optional: customize subdirectories (defaults shown)
(setq grove-inbox-directory "inbox")
(setq grove-daily-directory "daily")
;; Optional: daily note filename format (default shown)
(setq grove-daily-format "%Y-%m-%d")
;; Optional: tree sidebar width (default shown)
(setq grove-tree-width 30)
;; Optional: show nerd font icons in the tree sidebar
(setq grove-tree-icons t)
;; Optional: graph view settings (defaults shown)
(setq grove-graph-layout "neato") ; or "dot", "fdp", "sfdp"
(setq grove-graph-display 'auto) ; or 'side, 'buffer
(setq grove-graph-min-width 160) ; frame width threshold for autoGPL-3.0. See LICENSE.

