# persisted.nvim gives Neovim sessions that follow directories and git branches

> Persisted.nvim is a Lua plugin that records Neovim sessions with :mksession, saves them under .local/share/nvim/sessions, autoloads them per working directory or git branch, and offers a Telescope picker for managing them. It suits a developer who wants their buffer layout restored per project, and it inherits Vim's session options rather than defining its own state format.

**olimorris/persisted.nvim** — 💾 Simple session management for Neovim with git branching, autoloading and Telescope support

- Repository: https://github.com/olimorris/persisted.nvim
- Stars: 544 · Forks: 33
- Language: Lua
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/olimorris-persisted-nvim

## Session management on top of :mksession

Persisted.nvim is described as a simple lua plugin for working with sessions in Neovim, and it is a fork of folke's Persistence.nvim. The mechanism underneath is not custom. The README states plainly that the plugin uses Vim's :mksession command, and that you may therefore change the vim.o.sessionoptions value to determine what gets written into the session, with :h sessionoptions as the reference. The author's own setting is quoted in the README as vim.o.sessionoptions = "buffers,curdir,folds,globals,tabpages,winpos,winsize". That single line tells you most of what the plugin can and cannot restore: buffers, the current directory, folds, globals, tab pages, window positions and window sizes. Not cursor position, not marks, not which plugin was open. The plugin's job is to name, store, find and restore those files, not to invent a richer session format. The plugin is MIT licensed, the repository is not archived, and the last push was on 2026-10-15, with v3.1.1 released the same day, after v3.1.0 in August 2026 and v3.0.0 in January 2026. The only stated requirement is Neovim >= 0.8.0.

## Where the session files live and why that matters

Sessions are stored under .local/share/nvim/sessions, and the plugin automatically saves the active session there on exiting Neovim. The location is the save_dir option, and it is built from Vim's standard data path.

```lua
  save_dir = vim.fn.expand(vim.fn.stdpath("data") .. "/sessions/"), -- Directory where session files are saved
```

The README notes that the location may be changed by altering save_dir, and shows the same expression with a comment saying it resolves to ~/.local/share/nvim/sessions/. But it also carries a warning that the plugin may be unable to find existing sessions if the save_dir value is changed, and that is a caveat rather than a detail. The reason is structural: sessions are looked up by a filename derived from the project directory, so a lookup that assumes one directory finds nothing in another. If you keep session files in a dotfiles repository or a synced folder, expect to migrate them yourself. The follow_cwd option controls whether the session file changes to match any change in the cwd, which is on by default and is the mechanism behind the per directory behaviour that most people want from this plugin.

## Installing it with the plugin manager you already use

The README documents installation for vim.pack, Lazy.nvim, Packer and Vim Plug, and the shape is the same in each case: add the plugin, then call setup. With vim.pack the call is a single line, and the setup call goes somewhere in your config.

```lua
vim.pack.add({ "https://www.github.com/olimorris/persisted.nvim" })

-- Somewhere in your config
require("persisted").setup()
```

With Lazy.nvim the plugin spec includes an event of BufReadPre, with a comment explaining that this ensures the plugin loads only when a buffer has been loaded, and an opts table for your configuration.

```lua
-- Lua
{
  "olimorris/persisted.nvim",
  event = "BufReadPre", -- Ensure the plugin loads only when a buffer has been loaded
  opts = {
    -- Your config goes here ...
  },
}
```

Packer takes a use call with a config function, and Vim Plug uses a Plug line followed by a lua heredoc that calls setup with an options table, where the comment offers both a configuration block and the option of leaving it empty to use the defaults.

## The command set and the global variables

The commands are where most of the interaction happens, and the list is long enough to be worth reading in full. :Persisted toggle decides whether to load, start or stop a session. :Persisted start begins recording, which the README says is useful if autostart is false, and :Persisted stop ends it. :Persisted save saves the current session and :Persisted save with a name saves it under a specific name. :Persisted select loads a session from a list, described as useful if you do not want to use the Telescope extension, and :Persisted load loads the session for the current directory and current branch if git_use_branch is true. There are also load with a name, load_last for the most recent session, delete, delete with a name, delete_current, and clean, which deletes orphaned sessions and excludes named sessions. The plugin also sets three global variables during its lifecycle: vim.g.persisting as a boolean for whether the plugin is active for the current session, vim.g.persisting_session as the path to the current session if follow_cwd is false, and vim.g.persisted_loaded_session as the path to the last loaded session. Those globals are the hook point for other plugins and status lines.

## The Telescope picker and its four actions

There is a Telescope extension for managing sessions, opened with :Telescope persisted, and it needs to be loaded explicitly.

```lua
require("telescope").load_extension("persisted")
```

The default actions are worth noting because two of them are not standard. Enter opens or sources the session file. Ctrl-c copies the session file, which is how you duplicate a session under a new name rather than recreating it. Ctrl-b adds or updates the git branch for the session file, which is the manual escape hatch for the branch naming behaviour. Ctrl-d deletes the session file. The layout is customised from within Telescope's own setup.

```lua
require('telescope').setup({
  defaults = {
    …
  },
  extensions = {
    persisted = {
      layout_config = { width = 0.55, height = 0.55 }
    }
  }
})
```

The plugin's own defaults carry a telescope table with the same three mappings and a set of icons for the selected item, the directory and the branch, so a custom picker is a configuration change rather than a patch.

## Git branch sessions and the directory allow lists

The first feature in the list is support for sessions across multiple git branches, and the option that turns it on is use_git_branch, which is off by default. With it enabled, the branch name becomes part of the session file name, so a checkout of a different branch gets a different session rather than overwriting the one you had. The Telescope action Ctrl-b does the same thing manually for a single file. Two more options decide where the plugin acts at all. allowed_dirs is a table of directories that the plugin will start and autoload from, and ignored_dirs is a table of directories that are ignored for starting and autoloading, both empty by default. That pair is how you keep the plugin out of your dotfiles directory or out of a scratch folder without disabling it globally. Autoloading itself is a separate option, autoload, which is false by default, and there is a callback for the case where autoload is enabled but there is no session to load, on_autoload_no_session. The plugin also offers custom events that users can hook into for tighter integrations, which is the intended way to connect it to a status line or a dashboard.

## Where persisted.nvim is the wrong choice

Three limits are worth stating directly. The first is that the session content is not the plugin's to choose. Everything you get back is what :mksession writes, which is governed by sessionoptions, and the README's note about the author using a specific option set is the clearest statement of that dependency. If you expect to return to a file with your cursor on the right line, in the right split, with your folds intact, that depends on Vim's session machinery, and the plugin's contribution is naming and retrieval. The second is that this is a Neovim plugin, not a Vim one, since the requirement is Neovim >= 0.8.0 and the code is Lua, so a Vim user is out of luck. The third is that sessions are per project and per branch, which is exactly what you want on a workstation with several projects and exactly what you do not want if you want one session to follow you across a directory tree, because the file naming is derived from the directory and the branch, and the README warns that changing save_dir can make existing sessions unreachable. A comparable alternative for people who want richer restore behaviour is to write your own session file from a custom autocmd, which gives full control over what is captured and stored at the cost of maintaining that logic yourself, and for people whose main goal is window and buffer layout rather than project isolation, plain :mksession plus a handful of mappings is less machinery for the same result. The Telescope extension also assumes Telescope is already in your setup, which is a dependency worth checking before you install the plugin.

## Conclusion

Adopt persisted.nvim if you switch between projects daily and want Neovim to restore your buffer layout, folds and window sizes automatically per directory or per git branch, because it builds on :mksession and adds the directory aware naming, autoloading and a Telescope picker that plain Vim sessions lack. Do not adopt it if you want Neovim to restore cursor position, marks and your plugin state, since the plugin delegates entirely to Vim's :mksession and the sessionoptions value, so what you get back is exactly what that option set captures. Verify two things before you configure it: the sessionoptions you set, because the author uses buffers,curdir,folds,globals,tabpages,winpos,winsize and changing it changes the saved file, and whether the default save_dir already holds sessions you care about, since the README warns the plugin may be unable to find existing sessions if save_dir is changed. The practical first step is to install it with your package manager, call require("persisted").setup() with the defaults, and open Neovim in two different directories to see two separate sessions appear before you turn on autoload.

## FAQ

### What does persisted.nvim do?

It is a Lua plugin for Neovim that manages sessions using Vim's :mksession command, saving them under .local/share/nvim/sessions, autoloading them per directory or git branch, and offering commands to save, load, delete and clean sessions. It is a fork of folke's Persistence.nvim.

### How do I install persisted.nvim?

The README documents installation for vim.pack, Lazy.nvim, Packer and Vim Plug. With vim.pack you call vim.pack.add with the repository URL and then require("persisted").setup() in your config, and with the other managers you add the plugin spec and call setup in the same way. Neovim 0.8.0 or newer is required.

### Where does persisted.nvim store session files?

By default under .local/share/nvim/sessions, with the save_dir option built from vim.fn.stdpath("data"). The plugin automatically saves the active session there when Neovim exits, and the README warns that the plugin may be unable to find existing sessions if you change the save_dir value.

### What can a persisted.nvim session restore?

Whatever Vim's :mksession writes, which you control with the vim.o.sessionoptions value. The README notes that the author uses buffers,curdir,folds,globals,tabpages,winpos,winsize, so tabs, window positions and window sizes are restored but cursor position and marks are not part of that set.

### How does the Telescope extension for persisted.nvim work?

Load it with require("telescope").load_extension("persisted") and open it with :Telescope persisted. The default actions are Enter to open or source the session file, Ctrl-c to copy it, Ctrl-b to add or update the git branch for it, and Ctrl-d to delete it, and the layout can be adjusted through Telescope's extensions table.

## Sources

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

---

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