# neo-tree.nvim: a Neovim file explorer that avoids breaking changes

> Neo-tree renders filesystem and other tree structures in sidebars, floating windows or netrw-style splits. Its stated policy is to never knowingly ship a breaking change, which shapes both its release cadence and who should adopt it.

**nvim-neo-tree/neo-tree.nvim** — Neovim plugin to manage the file system and other tree like structures.

- Repository: https://github.com/nvim-neo-tree/neo-tree.nvim
- Stars: 5,614 · Forks: 307
- Language: Lua
- License: MIT
- Published: 2026-09-22 · Updated: 2026-09-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/nvim-neo-tree-neo-tree-nvim

## What neo-tree.nvim replaces, and for whom

Neovim ships netrw for browsing files, and netrw has a reputation for surprising behaviour: windows that get taken over, scroll positions that drift, listings that go stale. Neo-tree positions itself against exactly that class of annoyance. The README lists the specific behaviours it promises: the plugin will not let other buffers take over its window, will not leave the window scrolled to the last line when the whole tree fits, and does not need manual refreshing when use_libuv_file_watcher = true.

The audience is Neovim users who want a persistent tree beside their editing window and who care about the tree staying in sync with the filesystem. It is not aimed at people who want a fuzzy-finder style jump-to-file flow. The README's framing is about the sidebar as a place you live in, not a list you visit and dismiss.

The scope is wider than files. The description covers "other tree like structures," so the same UI can render sources beyond the filesystem. That generality is the main structural difference from a plain file browser.

## How the tree is built: nui.nvim for rendering, plenary.nvim for scanning

Neo-tree is not self-contained. The README states it relies on two library plugins: MunifTanjim/nui.nvim for "all UI components, including the tree" and nvim-lua/plenary.nvim for "backend utilities, such as scanning the filesystem." So the data flow is: plenary walks the filesystem, neo-tree holds the resulting node structure, and nui renders it into a window. If either dependency is missing, the plugin has nothing to draw with.

Optional dependencies layer capabilities on top rather than changing the core. nvim-tree/nvim-web-devicons supplies file icons. Crysthamus/nvim-file-operations or antosha417/nvim-lsp-file-operations add LSP-aware renames and similar operations. folke/snacks.nvim and 3rd/image.nvim enable image previews, and the README notes that when both are installed neo-tree tries snacks.nvim first and image.nvim second. s1n7ax/nvim-window-picker backs the _with_window_picker keymaps.

That split matters when something breaks. A rendering glitch points at nui; a missing file or a stale listing points at the scan layer or the watcher setting, not at the drawing code.

## Installing neo-tree.nvim with lazy.nvim or vim.pack

Neo-tree requires Neovim 0.8 or newer. The README gives plugin-manager examples. With lazy.nvim, the plugin is declared with branch = "v3.x" and the two required dependencies:

```lua
return {
  {
    "nvim-neo-tree/neo-tree.nvim",
    branch = "v3.x",
    dependencies = {
      "nvim-lua/plenary.nvim",
      "MunifTanjim/nui.nvim",
      "nvim-tree/nvim-web-devicons", -- optional, but recommended
    },
    lazy = false, -- neo-tree will lazily load itself
  }
}
```

Note the comment on lazy: the README sets lazy = false because the plugin handles its own lazy loading. If you force lazy loading on top of that, you are fighting the design rather than using it.

On Neovim 0.12 and later, the README offers a vim.pack example that pins a version range instead of a branch:

```lua
vim.pack.add({
  {
    src = 'https://github.com/nvim-neo-tree/neo-tree.nvim',
    version = vim.version.range('3')
  },
  -- dependencies
  "https://github.com/nvim-lua/plenary.nvim",
  "https://github.com/MunifTanjim/nui.nvim",
  -- optional, but recommended
  "https://github.com/nvim-tree/nvim-web-devicons",
})
```

The README also documents Packer.nvim and mini.deps examples, and points at doc/install.sh and doc/install.ps1 for manual installation via :h packages on POSIX and Windows respectively. There is a Dockerfile in the repository root that clones plenary.nvim, nui.nvim and nvim-web-devicons into a packer start directory and copies the plugin in, which is the route to take if you want a reproducible container rather than a hand-built config.

After installing, the first real use is a single command. Run :Neotree to open the sidebar, then press ? inside the tree to bring up the keyboard help. The README also suggests :checkhealth neo-tree to confirm the required dependencies are present. Do that before filing anything: a missing nui.nvim looks like a broken plugin but is a missing package.

## Hidden files, gitignore, and the settings that change what you see

Two settings in the README control whether the tree reflects the filesystem or your intent. use_libuv_file_watcher = true makes neo-tree watch the filesystem so the tree does not need manual refreshing. follow_current_file.enabled = true makes the tree track the file you are currently editing. Both are opt-in, and both change what appears on screen in ways that can confuse a new user who expects a static listing.

respect_gitignore is called out in the README with the claim that it "actually works." That phrasing is a dig at other explorers, and it is the setting to check first if files you expect to see are missing. A tree that hides ignored files is behaving as configured, not failing.

Clipboard behaviour is the third axis. clipboard.sync accepts "global" or "universal": global shares the clipboard across trees within one Neovim instance, universal shares it across all Neovim instances. If you run several Neovim sessions and expect a cut in one to paste in another, universal is the setting that makes that true.

## The breaking-change policy and what it costs

The README devotes a section to breaking changes with the strongest language in the document: "we will never knowingly push a breaking change and interrupt your day." When a breaking change is needed, the project creates a new branch the user can opt into at a convenient time. Changelog 3.0 on the wiki records the breaking changes and deprecations that landed in 3.0.

This is a genuine constraint, and it has a price. A plugin that refuses to break users accumulates compatibility paths. Old option shapes stay supported. Behaviour that a cleaner design would remove has to be kept or deprecated slowly. The benefit is that a config written against v3 keeps working; the cost is that the codebase carries more surface area than a project that ships breaking changes freely.

There is a second consequence worth naming. The README's promise is about knowingly pushing breaking changes. It explicitly says bugs happen. So the policy is not a stability guarantee in the sense of "nothing will ever go wrong"; it is a commitment about intent and about giving you a branch to move to. Read it that way when you plan upgrades.

## Where neo-tree.nvim is the wrong choice

Neo-tree is a sidebar-first tool. If your workflow is to open a file by typing part of its name and never look at a directory listing, a tree adds a window you have to manage without adding anything you use. The README's own framing, with its attention to window focus, scroll position and buffer takeover, describes problems that only exist because there is a persistent window in the first place.

The version floor is a hard boundary. Neo-tree supports Neovim 0.8 and onwards. On an older Neovim, this is not a configuration problem you can work around; the plugin is not built for that runtime.

The dependency chain is another real constraint. plenary.nvim and nui.nvim are required, not optional, so a minimal config that avoids plugin dependencies is not compatible with adopting neo-tree. Optional integrations add more: LSP-enhanced renames need nvim-file-operations or nvim-lsp-file-operations, window-picker keymaps need nvim-window-picker, and image previews need snacks.nvim or image.nvim. Each one is a separate thing to keep working.

Finally, the README documents the settings but does not document a rollback path for a bad upgrade. The breaking-change policy points at branches, and the changelog is on the wiki, but if a release misbehaves in your config the README does not tell you how to revert. Pin a version or a branch and keep that pin under your control.

## neo-tree.nvim compared with oil.nvim and NvimTree

The two comparisons people search for are neo-tree against NvimTree and neo-tree against oil. The README does not name either, so the difference has to be read from what neo-tree documents about itself.

On NvimTree: both are sidebar file explorers, so the meaningful difference is the stated behaviour contract. Neo-tree's README makes specific promises about window ownership, scroll position, per-tab isolation ("Neo-tree windows in different tabs are completely separate") and gitignore handling. It also commits to the no-knowing-breaking-changes policy. Those are the claims to test against your own workflow, not the feature list, which overlaps heavily.

On oil: oil's model is to edit the filesystem as a buffer, so you change filenames by editing text and saving. Neo-tree's model is a tree UI with keymaps and commands, and the README's examples are all about window behaviour and rendering. If you want the directory listing to be a normal buffer you edit, that is a different interaction model, not a configuration of neo-tree. If you want a persistent panel with columns you can sort, the README shows sorting on any column in the netrw-style layout, and that is neo-tree's territory.

The honest summary is that neo-tree's differentiator is not features but the stability policy and the attention to sidebar mechanics. If neither of those matters to you, the choice between these tools comes down to which keymap set you prefer.

## Release cadence, licence and upgrade cost

The repository is not archived and the last push was on 2026-09-17. Recent releases are 3.42.0 on 2026-09-01, 3.41.0 on 2026-05-15 and 3.40.0 on 2026-03-28. That is a steady minor-version cadence rather than a churn of major versions, which is consistent with the stated policy of routing breaking changes onto separate branches.

For upgrades, the practical lever is the version pin. The lazy.nvim example uses branch = "v3.x"; the vim.pack example uses version = vim.version.range('3'). Both keep you inside the 3.x line. If you want to absorb a minor release on your own schedule rather than at plugin-manager sync time, the range or branch pin is where you express that.

The licence is MIT. In plain terms, that is a permissive licence: it allows use, modification and redistribution with the licence and copyright notice retained. This is a description of the licence text, not legal advice, and it says nothing about the licences of plenary.nvim, nui.nvim, nvim-web-devicons or the other optional plugins, which you should check separately if licence compatibility matters for your distribution.

The upgrade cost itself is low by design. The README's promise is that a breaking change will not land on your branch unexpectedly, so the work of upgrading is mostly reading the changelog on the wiki and deciding when to move. What you pay for that is the compatibility surface described earlier.

## Conclusion

Adopt neo-tree.nvim if you run Neovim 0.8 or newer, want a filesystem tree that can also render other tree-shaped data, and value a project that routes breaking changes onto a separate opt-in branch. Do not adopt it if you are on Neovim 0.7 or older, or if a single-file picker with no sidebar is enough for your workflow. Before committing, run :checkhealth neo-tree to confirm the required dependencies resolve, and decide whether use_libuv_file_watcher and follow_current_file.enabled should be turned on, since both change how the tree reacts to external changes and cursor movement.

## FAQ

### What are the differences between neo-tree.nvim and NvimTree?

Both are Neovim sidebar file explorers, so the documented difference is behavioural rather than functional. Neo-tree's README makes explicit promises about not letting other buffers take over its window, not leaving the window scrolled to the last line, isolating windows per tab, and handling respect_gitignore correctly, and it commits to never knowingly pushing a breaking change.

### What are the differences between neo-tree.nvim and oil?

Neo-tree presents a tree UI with keymaps and commands, and its README describes layouts including sidebars, floating windows and netrw-style splits. Oil is not mentioned anywhere in the neo-tree documentation, so the README does not describe oil's approach or how the two compare beyond neo-tree's own model.

### How do I install neo-tree.nvim?

It requires Neovim 0.8 or newer plus the plenary.nvim and nui.nvim dependencies. The README gives examples for lazy.nvim, vim.pack, Packer.nvim and mini.deps, and points at doc/install.sh and doc/install.ps1 for manual installation via :h packages.

### How do I use neo-tree.nvim?

Run :Neotree to open it as a sidebar, then press ? while inside the tree to open the keyboard help. The README also suggests running :checkhealth neo-tree to confirm the required dependencies are installed.

### What is neo-tree.nvim?

It is a Neovim plugin for browsing the file system and other tree-like structures, with layouts that include sidebars, floating windows and netrw-style splits. It is written in Lua and licensed under MIT.

## Sources

- [Issues](https://github.com/nvim-neo-tree/neo-tree.nvim/issues)
- [License: MIT](https://github.com/nvim-neo-tree/neo-tree.nvim/blob/main/LICENSE)
- [nvim-neo-tree/neo-tree.nvim on GitHub](https://github.com/nvim-neo-tree/neo-tree.nvim)
- [README](https://github.com/nvim-neo-tree/neo-tree.nvim/blob/main/README.md)
- [Releases](https://github.com/nvim-neo-tree/neo-tree.nvim/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nvim-neo-tree-neo-tree-nvim
