Tarides Logo
An abstract rendition of a monitor with different creative tools including paintbrushes, scissors, and a paintbucket. Neovim's logo is displayed on the monitor. Neovim logo attributed to Jason Long

Creating ocaml.nvim to Bring Neovim Support to OCaml's LSP Server

CG

Software Engineer

Posted on Wed, 10 Dec 2025

We are happy to announce the release of the new ocaml.nvim plugin! It provides Neovim users with access to advanced ocaml-lsp features without getting involved in complicated editor-side logic. Think of it as the Neovim sibling of the Emacs plugin ocaml-eglot – which we have also covered on the blog – simplifying maintenance while still providing custom OCaml features. This is part of Tarides' ongoing effort to improve the OCaml user experience by introducing new features and improving existing ones.

In this post, we provide a brief overview of the relationship between Merlin, LSP, and Neovim in OCaml, the goals and features of ocaml.nvim, and offer some insight into how the engineers approached this project. We encourage you to install the plugin if you’re a NeoVim user (or just curious!) and give it a try. The repository is public and comes with documentation about its features and how to install the plugin. To help the team out, you can share your feedback on the OCaml Discuss forum, in the repo, or by emailing Charlène directly.

Merlin, LSP, & NeoVim

The Language Server Protocol (LSP) was created to address a programming landscape of a growing number of incompatible editors. The open protocol standardises the interactions between an editor and a server providing IDE services, creating a standard model supporting any compatible editor.

Created before the LSP, OCaml’s editor-agnostic server, Merlin, has offered advanced in-editor functionalities to the language for a long time. It quickly gained popularity within the community and was supported by several editors, including Emacs and Vim. However, supporting and maintaining each individual editor was resource intensive, as they required a tailored approach whenever they, OCaml, or Merlin updated.

Now, thanks to the fact that most modern editors use LSP to communicate with programming languages, OCaml can use LSP defaults to integrate Merlin with each editor’s LSP plugins. Neovim is one of the most popular editors (alongside Emacs, Vim, and VSCode) in the OCaml community. The new ocaml.nvim extension enables Neovim to support custom commands that are not possible with the standard LSP. The plugin ocaml.nvim works with generic Neovim LSP to provide access to advanced ocaml-lsp features, including all the advanced Merlin commands not supported by generic LSP clients. This approach addresses the so-called ‘editor burnout’ problem, which we have described in greater detail in our post on ocaml-eglot, ocaml.nvim’s ‘sibling’.

OCaml.nvim: Creating a New Plugin

The goal of the project was to create a modern and idiomatic Neovim plugin that would implement the server’s custom requests in a way that respected the design of the editor. We wanted to create a good foundation for community and industry users to build on, with a minimalist and well-documented plugin.

The ocaml.nvim plugin, of course, also supports key custom OCaml features, including advanced type-enclosing functionality, syntax-aware navigation, search by type, construct, and switching between the corresponding .ml and .mli. Check out the ocaml.nvim repository to read more about the supported features.

Code Actions and Custom Requests

Since this plugin aimed to enhance the standard LSP features, we needed to rely on an additional protocol to link specific information to a particular command. LSP offers two types of special requests: code actions and custom requests.

The LSP already lists code actions, but when there are numerous options, this special request can be confusing to use. Moreover, code actions prevent the use of parameters. They do not, for example, let the user select between multiple choices. This is where custom requests come into play.

Custom requests allow the language server to converse with the user as much as needed, for example, to collect choices. As a consequence, they require an extra plugin to translate the conversation from the server to the user, as the LSP cannot generalise the infinity of commands we could imagine in all languages.

Every function is available on the Merlin side and accessible via ocaml-lsp. There are two types of calls.

  • Ocaml-lsp API: This is the language server for OCaml. It provides the default features to the LSP. It also offers more than that. We can connect to the API to request information based on the cursor location or the server's knowledge of the current file.
  • MerlinCallCompatible: This is also provided by ocaml-lsp, and allows us to invoke the Merlin commands. It requires additional arguments and returns the result in a character string format; here, we used JSON.

UI Elements

Our objective was to provide a clear interface. To achieve this, we implemented four main UI elements for the entire plugin.

  • Selector: opens a floating window where the focus is initialised at the first line. Then, you can use the arrows and enter to move and select the wanted line.

The floating window with the first line ‘sys.command string -> int’ highlighted

  • New Window: This is built-in with nvim, and splits the current window to open a new buffer.

The floating window with a split and a new buffer

  • One-line Display: This is the simplest UI, simply a print. If it takes less than one line, it is displayed where you enter the commands.

The floating window displaying the string in a single line

  • Multi-line Display: By default, if the string in print exceeds one line, it displays it in multiple lines. However, this behaviour is not ideal because it requires pressing Enter to erase the text in an unappealing manner. So, the plugin provides an alternative that is similar to the UI selector.

The floating window with a box containing the information from the string

Regarding customisation, since everyone has their own keymaps, we provided default ones and allow users to modify them to suit their needs and preferences.

Try it Out!

Visit the ocaml.nvim repository on GitHub to get started with the new plugin. The repo includes the installation instructions, a straightforward process using lazy.nvim, as well as a features list and some examples.

Since the team is working towards a 1.0 release, any and all feedback is welcome. Remember to share your thoughts, suggestions, and questions on Discuss or in the repo through issues and commits.

You can connect with us on Bluesky, Mastodon, Threads, and LinkedIn or sign up for our mailing list to stay updated on our latest projects. We look forward to hearing from you!

Open-Source Development

Tarides champions open-source development. We create and maintain key features of the OCaml language in collaboration with the OCaml community. To learn more about how you can support our open-source work, discover our page on GitHub.

Explore Commercial Opportunities

We are always happy to discuss commercial opportunities around OCaml. We provide core services, including training, tailor-made tools, and secure solutions. Tarides can help your teams realise their vision