A Neovim plugin to visualize your notes vault in a board-style view — for quick, contextual overviews without relying on a file tree (that is limited for this sort of overview).
VaultView allows users to create customizable boards that give a quick, visual overview of their note vault. Instead of navigating through a file tree, VaultView parses and displays your notes in boards or matrices — giving you an at-a-glance view of what’s inside and what each note contains.
With it, you can:
- Quickly browse your vault in a structured, board-like interface.
- See summaries or key content (like headings, links, or metadata) from your notes.
- Open notes directly in Neovim or Obsidian.
- Navigate the boards fluidly using Vim motions or custom pickers.
- Features
- How it works
- Why this plugin
- External dependencies
- Installation
- Configuration
- Usage
- Keybinds inside VaultView UI
- Roadmap
- Known Issues
- Search / Parse / Display specific files in a matrix or board view
- Open the corresponding file in Neovim or Obsidian
- Navigate between board entries using Vim motions or custom pickers
- Fully customizable boards — define what subset of your vault each one displays
- Access the files of your vault for quick edit from any Neovim project
A Map Of Content is a special type of note that serves as a hub or index that gives you an overview of a topic and quickly navigates you to the relevant notes.
A MOC can typically be built within Obsidian by creating a file whose content is a list of links to other notes related to a specific subject.
An optimized workflow to populate MOCs in Obsidian is to use [[links]] in notes that relate to the MOC topic and then display dynamically with Dataview plugin in the MOC file all notes that link to it.
For example:
- Projects.md -> the MOC file
- Project 1.md -> file containing [[Projects]] (I usually put the link at the top of the file)
- Project 2.md -> file containing [[Projects]]
and the dynamically displayed content in Projects.md with Dataview would be (with links that can be followed):

This concept of MOC can be applied to various note organization preferences.
The problem with this is that while you can click on the links in Obsidian, you can’t quickly get an overview of what’s inside each linked note without opening it + you can only display one MOC at a time.
Tip
With the VaultView plugin, you can create a board that displays all your MOCs at once, along with the headings (or whatever content_selector you prefer) inside each linked note — and navigate it quickly using Vim motions. Plus quickly open the file in either Neovim or Obsidian.
Quick edit of a file from the board:

The plugin is architectured around the concept of MVC (Model-View-Controller) pattern.
A board in VaultView consists of three main parts:
- Board Data (The Model)
The data is generated by a parser, which: read- Takes all (or a subset) of your vault’s files => "Input Selection"
- Organizes it into a structured format => "Board Data Structuring"
- Extracts and aggregates relevant information for each entry => "Content Selection"
Board
├── Pages
│ ├── Lists (one column/block per list)
│ │ ├── Entries (one card per entry)
│ │ │ └── Content (displayed in cards)
Currently Supported Parsers:
- Daily Note Parser -> Retrieves all daily notes in your vault, sorts them by year/month, and extracts headings for each day.
- MOC Parser -> Finds all your MOC files and, for each one, lists all files linking to it — along with their headings (to display a TOC inside each card).
-
View (The Controller) The View holds data and states related to one board. It delegates the rendering of the data to a specific layout.
-
View Layout (The View)
The layout determines how the parsed data is displayed.
Currently Supported Layouts:
- Vertical Carousel
- Columns
I love Obsidian — especially for features like the Excalidraw plugin and great table handling. However, when it comes to navigation with hjkl and text editing, nothing beats Neovim.
What I missed most in Obsidian was a quick way to visualize my vault based on certain criteria — for example:
- Seeing what’s inside all my MOCs (Maps of Content)
- Browsing through all my Daily Notes
Obsidian has Dataview and Bases, but:
- They’re confined within Obsidian’s UI.
- They require a specific query/config language.
- They lack the power of Vim motions.
I actually started thinking about VaultView before Obsidian Bases even existed — and it turned out to be a great way to learn Lua and Neovim plugin development.
{
"fvalenza/vaultview",
dependencies = { "ColinKennedy/mega.cmdparse", "ColinKennedy/mega.logging", "folke/snacks.nvim" },
}return {
"fvalenza/vaultview.nvim",
dependencies = { "ColinKennedy/mega.cmdparse", "ColinKennedy/mega.logging", "folke/snacks.nvim" },
keys = {
{ "<leader>vv", "<Plug>(VaultView)", mode = "n", desc = "Open VaultView" },
},
config = function()
vim.g.vaultview_configuration = {
logging = {
level = "info",
use_console = false,
use_file = false,
output_path = "/tmp/vaultview.log",
raw_debug_console = false, -- Used to output special strings breaking classic formatting
},
hints = {
board_navigation = true,
-- pages_navigation = false, -- TODO: not yet implemented
-- entry_navigation = false, -- TODO: not yet implemented
},
selectors = {
input = { -- list of custom input selectors. They keys can be used in board definitions
exemple_list_files = { -- a comma-separated list of file paths
"/path/to/file1.md",
"/path/to/file2.md",
"/path/to/file3.md",
},
exemple_lua_function =function(search_path) -- a function that returns a list of file paths from a given search_path
return {
}
end,
exemple_shell_command = [=[ your_shell_command ]=], -- Custom shell command to list files
},
entry_content= { -- custom content selectors can be defined here and chosen in the board configuration
-- shall be grep/awk/rg command lines
},
},
vaults = {
["myVault"] = { -- Just a key used to reference the vault in board config but can be the same as obsidianVaultName
path = "/tmp/myVault/",
obsidianVaultName = "myVault", -- Name of the vault as known by Obsidian (used to build uri)
},
},
boards = {
{
vault = "myVault", -- key of the vault to use for this board.
name = "dailyBoard", -- name of the board as printed in the top of UI
parser = "daily", -- parser used to retrieve information to display in the view -> currently supported parsers: "daily", "moc"
viewlayout = "carousel", -- how information is displayed in the view -> currently supported layouts: "carousel", "columns"
input_selector = "yyyy-mm-dd.md",-- rule to select files to be included in the board. Can be a built-in selector or a user-defined one
subfolder = "vault/0-dailynotes", -- optional subfolder inside vault to limit the scope of the input files
content_selector = "h2", -- rule to select content inside each file to be displayed in the view. Can be a built-in selector or a user-defined one
},
{
vault = "obsidian:<workspace_name>", -- special syntax to directly reference an Obsidian vault configured in Obsidian.nvim plugin ( key of the workspace as defined in the `workspaces` section of obsidian.nvim plugin configuration)
name = "mocBoard",
parser = "moc",
viewlayout = "columns",
input_selector = "*.md",
subfolder = "vault/1-MOCs",
content_selector = "h2",
},
},
initial_board_idx = 1, -- index of the board to be displayed when opening the vaultview. Optional.
}
end,
}Interaction with the VaultView UI is done through actions exposed as <Plug> mappings.
This plugin defines default keybinds only inside the VaultView UI (through ftplugin/vaultview.lua).
The description of the default keybinds and associated actions/<Plug> is as follows:
| Key | Plug | Description |
|---|---|---|
| (VaultView) | Toggles VaultView UI | |
| q | (VaultViewHide) | Closes VaultView UI |
| ? | (VaultViewHelp) | Open help |
| p | (VaultViewPreviousBoard) | Go to previous board |
| n | (VaultViewNextBoard) | Go to next board |
| <S-h> | (VaultViewPreviousPage) | Go to previous page in current board |
| <S-l> | (VaultViewNextPage) | Go to next page in current board |
| <M-h> | (VaultViewFirstList) | Go to first list in current page |
| h | (VaultViewPreviousList) | Go to previous list in current page |
| c | (VaultViewCenterList) | Go to center list in current page |
| l | (VaultViewNextList) | Go to next list in current page |
| <M-l> | (VaultViewLastList) | Go to last list in current page |
| gg | (VaultViewFirstEntry) | Go to first entry in current list (jumps entry's pages) |
| k | (VaultViewPreviousEntry) | Go to previous entry in current list |
| j | (VaultViewNextEntry) | Go to next entry in current list |
| G | (VaultViewLastEntry) | Go to last entry in current list (jumps entry's pages) |
| <A-k> | (VaultViewPreviousPageInList) | Go to previous entry's page in current list |
| <A-j> | (VaultViewNextPageInList) | Go to next entry's page in current list |
| o | (VaultViewOpenInNeovim) | Open file of currently selected entry in Neovim |
| <CR> | (VaultViewOpenInObsidian) | Open file of currently selected entry in Obsidian |
| r | (VaultViewRefreshEntry) | Refresh Content displayed for selected entry |
| R | (VaultViewFastRefresh) | Refresh Content displayed for all entries (do NOT reparse vault for new entries) |
| 1 | (VaultViewBoard1) | Go To Board 1 |
| 2 | (VaultViewBoard2) | Go To Board 2 |
| 3 | (VaultViewBoard3) | Go To Board 3 |
| 4 | (VaultViewBoard4) | Go To Board 4 |
| 5 | (VaultViewBoard5) | Go To Board 5 |
| 6 | (VaultViewBoard6) | Go To Board 6 |
| 7 | (VaultViewBoard7) | Go To Board 7 |
| 8 | (VaultViewBoard8) | Go To Board 8 |
| 9 | (VaultViewBoard9) | Go To Board 9 |
To overwrite the default keybinds, the advised way is to create your own ftplugin/vaultview.lua (or ftplugin/vaultview-error.lua for corrupted boards) in your Neovim configuration folder (e.g. ~/.config/nvim/ftplugin/vaultview.lua).
In this file, set your preferred keybindings using vim.keymap.set with the {buffer = true} option.
For example:
vim.keymap.set("n", "<C-n>", "<Plug>(VaultViewNextBoard)", { buffer = true })or using LazyVim you can put it directly in the keys section of the plugin specification:
{
"fvalenza/vaultview",
dependencies = { "ColinKennedy/mega.cmdparse", "ColinKennedy/mega.logging", "folke/snacks.nvim" },
keys = {
{ "<leader>vv", "<Plug>(VaultView)", mode = "n", desc = "Open VaultView" },
},
}Warning
No default keybind is set to open the VaultView UI and putting a keymap to <Plug>(VaultView) in ftplugin/vaultview.lua would not work.
It is expected from the user to set at least this keymap in their Neovim configuration file or to use :VaultView open command.
The plugin comes with some default input and content selectors that can be used in the board configuration. In the configuration one can specify custom ones for input selector as either : a list of files, a shell command returning a list of files, or a Lua function returning a list of files. content_selectors only accepts shell commands returning content lines for each entry. The current default ones are:
local input_selectors = {
["*"] = [[find %q -type f | sort ]], -- all files
["*.md"] = [[find %q -type f -name '*.md' | sort ]], -- all markdown files
["yyyy-mm-dd.md"] = [[find %q -type f | sort | grep -E '/[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])\.md$']], -- all markdown files with name matching yyyy-mm-dd.md
}
local content_selectors = {
headings = [=[grep -E '^#+[[:space:]]+.+' %q | sed -E 's/^#+[[:space:]]+//' ]=],
h1 = [=[grep -E '^#[[:space:]]+.+' %q | sed -E 's/^#[[:space:]]+//' ]=],
h2 = [=[grep -E '^##[[:space:]]+.+' %q | sed -E 's/^##[[:space:]]+//' ]=],
h3 = [=[grep -E '^###[[:space:]]+.+' %q | sed -E 's/^###[[:space:]]+//' ]=],
h4 = [=[grep -E '^####[[:space:]]+.+' %q | sed -E 's/^####[[:space:]]+//' ]=],
h2_awk_noexcalidraw = [=[awk '/^# Excalidraw Data/ { exit } /^##[[:space:]]+.+/ { sub(/^##[[:space:]]+/, ""); print }' %q]=],
h2_rg_noexcalidraw = [=[rg --until-pattern '^# Excalidraw Data' '^##[[:space:]]+.+$' %q | sed -E 's/^##[[:space:]]+//' ]=],
}One can provide in the configuration their own custom parsers by providing a function to the "parser" field of a board configuration. The function should take as input the vault subtable of the configuration and the board configuration table:
One can configure a board to use an Obsidian vault configured in the Obsidian.nvim plugin by using the special syntax obsidian:<workspace_name> in the vault field of the board configuration, where <workspace_name> is the key of the workspace as defined in the workspaces section of obsidian.nvim plugin configuration.
Special case: obsidian:CURRENT can be used to reference the curren workspace opened in Obsidian.nvim plugin.
Warning
Current state of obsidian.nvim integration is subject to change:
- obsidian:CURRENT syntax may disappear in the future
- if workspace key name is not the same as name of Obsidian Vault, opening in obsidian won't work
--- parse a vault folder to create a board data structure depending on the board configuration
--- @param vault_path string
--- @param boardConfig vaultview.BoardConfig
---
--- @return table boardData The BoardDataStructure required by ViewLayouts
parser = function(vault_path, boardConfig)
endWarning: First stable release (v1.0.0) of this plugin is still to come, hence the API for custom parsers may change in future releases.
Once setup and your neovim instance running, you can use the following commands to interact with VaultView.
:VaultView open
:VaultView close
:VaultView refreshor you can map your preferred keybinding to <Plug>(VaultView) to open the main VaultView window.
See roadmap


