Publish your Neovim plugins to LuaRocks

Posted on January 10, 2023

This is a follow-up on a series of blog posts by @teto that propose a solution to a major pain point of the Neovim plugin ecosystem - Dependency management.

As someone who only recently started maintaining Neovim plugins, I have been quite frustrated with my experience so far…

The current status quo

1. A horrible UX

…where users, not plugin authors, have to declare dependencies.

Here’s an example using packer.nvim:

use {
  'junnplus/lsp-setup.nvim',
  requires = {
    'neovim/nvim-lspconfig',
    'williamboman/mason.nvim',
    'williamboman/mason-lspconfig.nvim',
  }
}

This shouldn’t be the user’s responsibility.

What if dependencies are added or changed? It’s the user who has to update their config or deal with breakage.

2. Plugin authors copy/pasting code instead of using libraries

…because they don’t want their users to have to deal with this horrible UX.

I’ve been guilty of doing so myself.

3. Instability

As far as I know, we currently have no easy way to declare version constraints for dependencies. Something that LuaRocks supports, and which definitely should not be left up to the user.

All of this potentially gets worse with transitive dependencies.

The vicious cycle

As I see it, we have ourselves a dilemma:

This is something I’ve observed in many fields. For example, critics of electromobility have claimed that EVs will never be feasible, because we don’t have enough charging infrastructure. But which came first? Cars, or petrol stations?

I’m a strong believer that we need plugin authors to publish their packages to LuaRocks before package managers start supporting it. Just like we had cars before petrol stations, and electric vehicles before charging infrastructure.

Introducing the LuaRocks tag release action

As a catalyst to alleviate these issues, @teto and I have started the nvim-neorocks organisation and released the luarocks-tag-release GitHub action.

The goal is to minimise the effort for developers to release their plugins to LuaRocks, and to keep their published packages up to date.

How to get started as a plugin developer?

name: LuaRocks release
on:
  push:
    tags:
      - "*"

jobs:
  luarocks-release:
    runs-on: ubuntu-latest
    name: LuaRocks upload
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: LuaRocks Upload
        uses: nvim-neorocks/luarocks-tag-release@v4
        env:
          LUAROCKS_API_KEY: ${{ secrets.LUAROCKS_API_KEY }}
        with: # Optional inputs...
          dependencies: |
            plenary.nvim
            nvim-lspconfig

Whenever you push a tag (expected to adhere to semantic versioning), the workflow will:

  1. Automatically fetch most of the relevant information (summary, license, …) from GitHub
  2. Generate a rockspec for the release
  3. Run a test to make sure LuaRocks can install your plugin locally
  4. Publish your plugin to LuaRocks
  5. Run a test to verify that your plugin can be installed from LuaRocks

If you need more flexibility, you can specify additional inputs or even use a rockspec template.

To advertise that your plugin is available on LuaRocks, you can add a shield to your README:

[![LuaRocks](https://img.shields.io/luarocks/v/<user>/<plugin>?logo=lua&color=purple)](https://luarocks.org/modules/<user>/<plugin>)

For example:

LuaRocks

[![LuaRocks](https://img.shields.io/luarocks/v/neovim/nvim-lspconfig?logo=lua&color=purple)](https://luarocks.org/modules/neovim/nvim-lspconfig)

Here are some workflows and PRs you can use for inspiration:

[^1] pull request

See also the workflow’s wiki page.

What can you do as a Neovim user?

If you don’t maintain your own plugins, but want to see the ecosystem improve, you can suggest the workflow to your favourite plugins, or open a pull request. In most cases, it’s extremely easy to add the workflow. See the above PR examples.

If you run in to problems or have any questions, don’t hesitate to open an issue or start a discussion!

What’s next?

For now, I am experimenting with a fork of LuaRocks, stripped down to the bare minimum needed to install packages. I am still uncertain of what that will lead to in the near future.

  • Perhaps a package manager as a proof-of-concept?
  • Maybe a package that can use Neovim as an interpreter to run LuaRocks so that it can use Neovim’s Lua API in test runs?

Hopeful for the future. Let’s make this happen!

Follow-up

Test your Neovim plugins with luarocks & busted