Lazy.nvim: how to revert a plugin back to a previous version
Tags: neovim, shell
Published: 2023-07-30 20:38:12

---
title: Lazy.nvim: how to revert a plugin back to a previous version
published: true
description: learn how to restore a plugin back to previous version using lazy.nvim
tags: #neovim #shell
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-07-30 13:29 +0000
---

If you've been using Neovim for a while maybe you noticed that plugins receive updates all the time. This isn't always good news, a change can introduce a bug in your config, or maybe it changed the current api. It can be annoying, I know. But today we are going to learn how [lazy.nvim](https://github.com/folke/lazy.nvim) can help us recover from bad situations, so we can always have Neovim in a good state.

I'm going to tell you how to rollback a plugin update using lazy.nvim's interface. And also, in case something goes horribly wrong, how you can rollback every plugin installed back to a known previous state.

## Revert a plugin

If you know what plugin broke your Neovim config you can execute the command.

```
:Lazy log some-plugin
```

Where `some-plugin` is the name of your plugin. This command will open lazy.nvim's interface and it will show the previous commits.

If I execute the command `:Lazy log nvim-lspconfig`, this is what I get.

```
● nvim-lspconfig 371.28ms ⌘ Lsp
  b609127 feat(omnisharp): find root directory for .csx scripts (#2715) (hace 4 días)
  654dd9e fix(rust_analyzer): check active clients is empty (#2734) (hace 5 días)
  6f426c3 docs: update server_configurations.md skip-checks: true (hace 6 días)
  01b25ff docs: make vimdocs consistent with readme (#2732) (hace 6 días)
  dd11ba7 fix(pyright): re-enable single-file mode (#2730) (hace 10 días)
  6c53bf7 fix(pyright): fix root_dir detection (#2727) (hace 10 días)
  443c56a docs: update server_configurations.md skip-checks: true (hace 11 días)
  e7be6d4 feat(v): add `v-analyzer` (#2726) (hace 11 días)
```

Notice that before each commit message we have the commit hash.

To revert the plugin to any of those commits all I have to do is place the cursor above the commit hash and press `r`.

## The lockfile

If there is no way of knowing which plugin is causing the error then you could use this command 

```
:Lazy restore
``` 

With this you will be able to revert all the plugins to the state reflected in the lockfile.

If you don't know, the lockfile is a JSON file that contains the current commit hash of all your plugins. This is located in the same folder as your `init.lua` or `init.vim` config. The lockfile is actually called `lazy-lock.json`.

There is one problem: the lockfile updates with your plugins. If you don't backup your lockfile before an update there is no way to revert to the previous working state.

### What to do?

Here are few ideas:

* Make a copy

Easiest thing will be to create a copy of the lockfile and just keep it around. You would navigate to your Neovim config folder and copy the file `lazy-lock.json`.

```
cp lazy-lock.json lazy-lock.backup.json
```

There you go. `lazy-lock.backup.json` can have the last working state of all your plugins. When something goes wrong you simply change the name of the backup file to `lazy-lock.json`. Then in Neovim you can execute the command `:Lazy restore`.

* Use `git`

You would want to add the lockfile to git. Have a commit with a stable version of the lockfile. If something goes wrong you can revert the lockfile using the `git` cli. And then use `:Lazy restore` inside Neovim.

If you don't know how to revert to a commit with the `git` cli, try to use the website of your repo (github/gitlab/whatever). Go to the lockfile and copy it to your system.

* Automatic backups

What I do is use lua to make a backup of the lockfile. I use the autocommand `User LazyUpdatePre`, this is executed before lazy.nvim updates the plugins. Here I have a function that creates a copy of the lockfile with a time and date as the name.

Here is the code.

```lua
local lazy_cmds = vim.api.nvim_create_augroup('lazy_cmds', {clear = true})
local snapshot_dir = vim.fn.stdpath('data') .. '/plugin-snapshot'
local lockfile = vim.fn.stdpath('config') .. '/lazy-lock.json'

vim.api.nvim_create_user_command(
  'BrowseSnapshots',
  'edit ' .. snapshot_dir,
  {}
)

vim.api.nvim_create_autocmd('User', {
  group = lazy_cmds,
  pattern = 'LazyUpdatePre',
  desc = 'Backup lazy.nvim lockfile',
  callback = function(event)
    vim.fn.mkdir(snapshot_dir, 'p')
    local snapshot = snapshot_dir .. os.date('/%Y-%m-%dT%H:%M:%S.json')

    vim.loop.fs_copyfile(lockfile, snapshot)
  end,
})
```

If something goes wrong I use the command `:BrowseSnapshots` to search for the latest lockfile. I usually just grab the commit of the plugin that broke my config, then copy it to the current lockfile. After that, I use the restore command with the name of the plugin.

```
:Lazy restore some-plugin
```

If something went really really bad, I would just copy the whole backup and replace the current lockfile.

## Conclusion

Is important to be prepared in case a plugin makes our editor unusable. Fortunaly lazy.nvim gives us convenient tools to recover from a bad state. We can use the interface to revert a plugin to a recent version, or we can use the lockfile to revert everything to a previous working state. So there is always a way to have Neovim with a working config.

---

Thank you for your time. If you find this article useful and want to support my efforts, consider leaving a tip in [buy me a coffee ☕](https://www.buymeacoffee.com/vonheikemen).

[![buy me a coffee](https://res.cloudinary.com/vonheikemen/image/upload/v1618466522/buy-me-coffee_ah0uzh.png)](https://www.buymeacoffee.com/vonheikemen)