zettelkasten.nvim
July 11, 2026 ยท View on GitHub
A Zettelkasten note-taking plugin for Neovim, written in Lua.
- ๐ Intro
- โจ Features
- ๐ฆ Installation
- ๐ง Configuration
- โ๏ธ Commands
- โจ๏ธ Key Bindings
- ๐จ Browser Format
- ๐ Picker Integration
- ๐ญ Telescope Integration
- ๐ Calendar Extension
- ๐ฌ Chat Integration
- ๐ Debug
- ๐ธ Screenshots
- ๐ฃ Self-Promotion
- ๐ Credits
- ๐ฌ Feedback
๐ Intro
zettelkasten.nvim brings Zettelkasten-style note-taking into Neovim.
Notes are stored as Markdown files with timestamp-based IDs, and the plugin provides a browser
window, tags sidebar, reference/backlink tracking, completion, and integrations with picker.nvim,
telescope.nvim, calendar.nvim, and chat.nvim.
โจ Features
- ๐ Zettelkasten Notes - Create notes with timestamp-based IDs (
YYYY-MM-DD-HH-MM-SS.md) - ๐๏ธ Note Browser - Browse all notes in a dedicated window with customizable format
- ๐ท๏ธ Tags Sidebar - Foldable tag tree for visual tag-based filtering
- ๐ References & Backlinks - Automatic
[[note-id]]reference detection and backlink tracking - โ๏ธ Completion - Note ID and tag completion via
completefuncandtagfunc - ๐ Quickfix Integration - List back references in the quickfix/location window
- ๐ผ๏ธ Clipboard Image Paste - Paste images from clipboard directly into notes (macOS/Linux/Windows)
- ๐ Multi-Picker Support - Integrates with picker.nvim and telescope.nvim
- ๐ Calendar Integration - Highlights dates with notes via calendar.nvim
- ๐ฌ Chat Integration - Create, retrieve, and update notes via chat.nvim
- ๐งฉ Note Templates - Create notes from pre-defined templates
๐ฆ Installation
Using nvim-plug:
require('plug').add({
{
'wsdjeg/zettelkasten.nvim',
config = function()
require('zettelkasten').setup({
notes_path = '~/.zettelkasten',
template_dir = '~/.zettelkasten_template',
preview_command = 'pedit',
browseformat = '%f - %h [%r Refs] [%b B-Refs] %t',
})
vim.keymap.set('n', '<leader>mzb', '<cmd>ZkBrowse<cr>', { silent = true })
vim.keymap.set('n', '<leader>mzn', '<cmd>ZkNew<cr>', { silent = true })
end,
},
})
Using LuaRocks:
luarocks install zettelkasten.nvim
๐ง Configuration
All options are passed to require('zettelkasten').setup({}):
| Option | Type | Default | Description |
|---|---|---|---|
notes_path | string | '~/.zettelkasten/' | Directory where notes are stored |
template_dir | string | '~/.zettelkasten_template' | Directory containing note templates |
preview_command | string | 'pedit' | Vim command used for note preview |
browseformat | string | '%f - %h [%r Refs] [%b B-Refs] %t' | Format string for the browser window (see Browser Format) |
completion_kind | string | '[zettelkasten]' | Kind label shown in completion menu |
browse_title_width | number | 30 | Max display width for note titles in the browser |
โ๏ธ Commands
| Command | Description |
|---|---|
:ZkNew | Create a new zettelkasten note |
:ZkBrowse [tags...] | Open the note browser; optional tag arguments to filter |
:ZkHover [-preview] [-return-lines] [word] | Show note info in a notification; -preview opens preview window, -return-lines returns full content |
โจ๏ธ Key Bindings
Browser Window
| Key | Description |
|---|---|
F2 | Open the zettelkasten tags sidebar |
<LeftRelease> | Filter notes by the tag under cursor |
<Enter> / gf | Open the note under cursor |
Ctrl-l | Clear tag filter and reload all notes |
Ctrl-] / K | Preview note via keywordprg (:ZkHover -preview) |
[I | List back references in the quickfix window |
Ctrl-x Ctrl-u | Complete note ID or tags (insert mode) |
q | Close the browser window |
Tags Sidebar
| Key | Description |
|---|---|
<Enter> | Filter browser notes by the tag under cursor |
<LeftRelease> | Filter by tag, or toggle fold on fold markers |
F2 / q | Close the tags sidebar |
Note Buffer
| Key | Description |
|---|---|
<Leader>p | Paste image from clipboard into the note |
K | Hover note info (:ZkHover) |
[I | List back references in the quickfix window |
Ctrl-] | Jump to [[note-id]] reference via tagfunc |
Ctrl-x Ctrl-u | Complete note ID or tags (insert mode) |
๐จ Browser Format
The browseformat option controls how each note is displayed in the browser window.
The following modifiers are supported:
| Modifier | Description |
|---|---|
%f | File name (e.g. 2024-01-15-10-30-00.md) |
%h | Note title (padded/truncated to browse_title_width) |
%d | Note ID (timestamp) |
%r | Number of references (outgoing [[links]]) |
%b | Number of back references (incoming links) |
%t | Space-separated tags |
๐ Picker Integration
zettelkasten.nvim provides sources for picker.nvim:
:Picker zettelkasten
:Picker zettelkasten_tag
:Picker zettelkasten_template
| Source | Description |
|---|---|
zettelkasten | Fuzzy find notes, open or insert note ID |
zettelkasten_tag | Fuzzy find tags, filter browser by selection |
zettelkasten_template | Fuzzy find templates, create note from selection |
Key bindings in picker sources:
| Key | Description |
|---|---|
<Enter> | Default action (open note / filter / create) |
<C-y> | Insert selected note's ID at cursor position |
๐ญ Telescope Integration
zettelkasten.nvim also provides extensions for telescope.nvim:
require('telescope').load_extension('zettelkasten')
require('telescope').load_extension('zettelkasten_tags')
require('telescope').load_extension('zettelkasten_template')
| Command | Description |
|---|---|
:Telescope zettelkasten | Find and open notes |
:Telescope zettelkasten_tags | Find and filter by tags |
:Telescope zettelkasten_template | Find and create from templates |
๐ Calendar Extension
zettelkasten.nvim provides an extension for calendar.nvim. It highlights dates that have zettelkasten notes associated with them.
When pressing <Enter> on a date in the calendar, the following actions are available:
- Create a daily note - Creates a new note with the selected date
- Browse daily notes - Opens the browser filtered by the selected date
๐ฌ Chat Integration
zettelkasten.nvim provides three tools for chat.nvim:
Create Notes
@zk create <title>
Creates a new zettelkasten note with automatic ID generation and tag support.
Parameters:
title(string, required): The title of the notecontent(string, required): The main body content of the notetags(array of strings, optional): Tags for categorizing the note (e.g.,["programming", "vim"])
The note file is formatted as:
# <id> <title>
tags: #tag1 #tag2
<content>
Retrieve Notes
@zk get <tags>
Retrieves zettelkasten notes by tags. Returns a JSON array of matching notes with file_name and title fields.
Update Notes
@zk update <id> <action> [parameters]
Updates an existing zettelkasten note with partial modifications โ no need to pass the full note content.
Parameters:
id(string, required): The note ID (e.g.,"2024-01-15-10-30-00")action(string, required): One of the following:
| Action | Description | Extra Parameters |
|---|---|---|
update_title | Change the note title (ID preserved) | title (string, required) |
add_tags | Add tags (duplicates skipped) | tags (string[], required) |
remove_tags | Remove tags (removes line if empty) | tags (string[], required) |
replace_text | Find/replace in note body | old_text (string), new_text (string) |
Tags can be provided with or without # prefix. For replace_text, the title line (line 1) is skipped. Use empty new_text to delete text.
Examples:
@zk update id="2024-01-15-10-30-00" action="update_title" title="New Title"
@zk update id="2024-01-15-10-30-00" action="add_tags" tags=["python", "web"]
@zk update id="2024-01-15-10-30-00" action="remove_tags" tags=["old-tag"]
@zk update id="2024-01-15-10-30-00" action="replace_text" old_text="old code" new_text="new code"
๐ Debug
Debug zettelkasten.nvim with logger.nvim:
require('plug').add({
{
'wsdjeg/zettelkasten.nvim',
depends = { { 'wsdjeg/logger.nvim' } },
},
})
๐ธ Screenshots

๐ฃ Self-Promotion
Like this plugin? Star the repository on GitHub.
Love this plugin? Follow me on GitHub.
๐ Credits
This plugin is forked from Furkanzmc/zettelkasten.nvim.
New features added in this fork:
- Tags sidebar with foldable tag tree for visual filtering
- Tag completion in
completefunc(detects#prefix context) - Clipboard image paste (macOS / Linux / Windows)
- Note templates and custom-date note creation via
zknew(opt) - Calendar.nvim, picker.nvim, telescope.nvim, and chat.nvim integrations
- LuaRocks support and release-please automation
Improvements over upstream:
- Nil-safety and file-handle cleanup in note parsing
- Duplicate note ID guard in
set_note_id - Read-only browser buffer with richer keybindings (
q,<Enter>,<C-l>,<F2>) - CJK-aware title truncation in the browser formatter
- Simplified config (module-level fields instead of
config.get()) - Comprehensive unit test suite with luaunit
๐ฌ Feedback
If you encounter any bugs or have suggestions, please file an issue in the issue tracker.