# NeoCodeium gives Neovim Windsurf completions without the flicker

> NeoCodeium is a MIT licensed Lua plugin that drives the Windsurf language server from Neovim, replacing the official plugin's flickering virtual text with cached, debounce-free suggestions and a Lua API for accepting, cycling and clearing them. It requires Neovim 0.10 or newer, ships no default keymaps, and every keystroke in an enabled buffer reaches Windsurf servers.

**monkoose/neocodeium** — free AI completion plugin for neovim

- Repository: https://github.com/monkoose/neocodeium
- Stars: 519 · Forks: 21
- Language: Lua
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/monkoose-neocodeium

## The flicker in multi-line virtual text was the reason for the plugin

NeoCodeium exists because of a specific irritation. The author found that suggestions in the official plugin flickered, and that this was especially annoying when dealing with multi-line virtual text. Two smaller wishes came with it: the ability to accept a suggestion repeatedly using the `.` command, which matters for a plugin used as the main completion source with nvim-cmp invoked only manually, and a smoother feel overall. The plugin is written in Lua and supports only Neovim, so it is not a drop-in for the Vim-oriented windsurf.vim plugin it is compared against in the README. The functional differences it claims over that plugin are concrete: flickering removed in most scenarios, repeatable completions on the current line with the `.` key, performance gains through cache techniques, the suggestion count label moved into the number column so it sits closer to the context, default keymaps removed, and no debounce by default so suggestions appear while you type.

## The Windsurf language server does the work, the plugin does the UI

NeoCodeium is powered by Windsurf, formerly Codeium, and it is worth being precise about the architecture. The plugin does not contain a language model. It starts and talks to the Windsurf language server, which is a separate binary that evaluates your code and returns completions, and the plugin renders those completions as virtual text and handles accepting them. The setup options reflect that split. The `bin` option points at a custom Windsurf server binary, with a download link to the codeium releases, and `server.api_url` and `server.portal_url` select the API and portal endpoints, which is what enterprise users need when their company hands out portal and API URLs. The plugin also has global and per-buffer kill switches, `:NeoCodeium enable` and `:NeoCodeium enable_buffer`, so the server can be started and stopped without reloading the session. Authentication is a separate step: `:NeoCodeium auth` obtains an API token, and on Windows WSL the README notes that `wslview` should be installed so the browser opens properly.

## Installing with lazy.nvim and binding accept to Alt-f

The README gives the lazy.nvim example, and points you to your own plugin manager's documentation if you use something else. The plugin is loaded lazily, and the config function sets up the module and binds a key:

```lua
-- add this to the file where you setup your other plugins:
{
  "monkoose/neocodeium",
  event = "VeryLazy",
  config = function()
    local neocodeium = require("neocodeium")
    neocodeium.setup()
    vim.keymap.set("i", "<A-f>", neocodeium.accept)
  end,
}
```

After that, Alt-f in insert mode accepts the current suggestion. Note what is absent: the plugin ships no default keymaps, so the binding is yours to define, and if you follow the README example as written you get a single accept action and nothing else. Enterprise users configure the endpoints instead:

```lua
{
  "monkoose/neocodeium",
  event = "VeryLazy",
  opts = {
    server = {
      api_url = 'https://codeium.company.net/_route/api_server',
      portal_url = 'https://codeium.company.net',
    },
  },
}
```

That form relies on the opts convention, so the choice between opts and an explicit config function is part of how you wire it up.

## Debounce, max_lines and single_line shape what you see

The documented defaults are extensive, and three of them change what the editor looks like on a normal day. `debounce` defaults to false, which means suggestions appear while you type rather than after a pause, and setting it to true restores the delay. `show_label` controls whether the suggestion count appears in the line number column. `single_line` is a table with its own `enabled` flag and a `label`, and when it is on, multi-line suggestions collapse into a single line and only reveal full lines at the end of the suggested line, which the README describes as less distracting and better suited to running alongside other completion plugins. Two options control how much context the server sees. `max_lines` defaults to 10000 lines parsed from loaded buffers, the current buffer is always parsed in full, setting it to 0 stops non-current buffers from being parsed at all at the cost of suggestion quality, and -1 parses every line. A `filter` function decides per buffer whether the plugin is active, and `filetypes` disables suggestions in help, gitcommit and gitrebase buffers and in buffers whose filetype is a dot.

## A Lua API for accepting, cycling and clearing suggestions

Everything the plugin can do to a suggestion is exposed as a Lua function on the neocodeium module, which is what makes it composable with other completion setups. The set includes accepting the whole suggestion, accepting only part of it when the full thing does not make sense, and clearing the current suggestion:

```lua
local neocodeium = require("neocodeium")

-- Accepts the suggestion
neocodeium.accept()

-- Accepts only part of the suggestion if the full suggestion doesn't make sense
neocodeium.accept_word()
neocodeium.accept_line()

-- Clears the current suggestion
neocodeium.clear()
```

Beyond that, cycle(n) moves through alternatives, with a negative value cycling in reverse and a default of one item, cycle_or_complete(n) does the same but also asks for a suggestion when none is visible, which is the companion to the `manual` option, and visible() reports whether a suggestion's virtual text is currently shown, which the README notes is useful for some complex key mappings. With `manual` set to true, autosuggestions are off and suggestions are requested on demand through cycle_or_complete(). The plugin is developed against a test suite in the tests/ directory, and the Makefile runs it headless:

```bash
	nvim --headless -c "PlenaryBusted tests { keep_going = false }"
```

## Disabling a buffer does not switch off the server

The README carries a warning that is worth reading closely before you install anything. While the plugin is in use, your code is constantly sent to Windsurf servers by their own language server, in order to evaluate and return completions. The plugin can disable the server globally or for individual buffers, and it does not send data from disabled buffers. The catch is stated in the same paragraph: the Windsurf server is still running behind the scenes, and the authors cannot guarantee that it does not send information while running. So the per-buffer switch is a statement about what the plugin forwards, not a promise that the process is inert. The README directs you to the Windsurf Privacy Policy before using the plugin at all. For a project with secrets in the buffer, a proprietary codebase, or a client agreement that forbids third party code processing, that is a hard constraint rather than a preference, and the `filter` option exists precisely so you can express it.

## No Vim support, no default keymaps, bounded context

Three limits are visible in the documentation. The first is platform: the plugin supports only Neovim, written in Lua, and requires Neovim 0.10.0 or newer, so a Vim user has to look at windsurf.vim instead. The second is that default keymaps have been removed, which is a feature for people who already have a mapping scheme and a cost for everyone else, since a fresh install shows completions that you then have to learn to accept. The third is that context is bounded: `max_lines` limits how much of the loaded buffers are parsed, and while the current buffer is always parsed fully, background buffers are capped at 10000 lines by default. Setting `max_lines` to 0 disables parsing of non-current buffers, and the README is explicit that this may lower suggestion quality, which is the honest trade-off between latency and context. The whole feature also depends on a server binary and on a commercial service staying reachable, so the plugin is not a self-contained tool.

## windsurf.vim, nvim-cmp and the release cadence

The alternative approaches are not hypothetical. windsurf.vim is the plugin the README compares itself against, and the difference is mostly about the host editor and the interface: NeoCodeium is Neovim only and renders its own suggestion count label in the number column, while the other plugin gained the ability to complete only a word or line of a suggestion. The nvim-cmp route is the second option, and it is the author's own setup, since he uses it as the main completion plugin and only invokes it manually, which is why the plugin offers cycle_or_complete() and why repeatable acceptance with `.` mattered in the first place. On upkeep, the project is not archived and the last push was on 2026-06-22, which is also the date of the v1.19.1 tag, preceded by v1.19.0 on 2026-06-11 and v1.18.0 on 2026-06-05, so the release cadence in the visible window is roughly weekly. Licence terms are MIT, which is permissive for a plugin of this size, and the repository keeps its documentation in doc/, its Lua sources in lua/ and its formatting configuration in .stylua.toml and .luarc.json.

## Conclusion

Adopt NeoCodeium if you are a Neovim user who wants Windsurf completions without the flicker of the official plugin and if you are willing to map your own keys and to accept that enabled buffers are sent to Windsurf servers. Skip it if you are on Vim rather than Neovim, if you cannot route code through a third party service, or if you want a completion engine you control end to end. Before enabling it, read the Windsurf Privacy Policy, set the `filter` option to exclude sensitive buffers, and confirm your Neovim version is at least 0.10.0.

## FAQ

### What is NeoCodeium and what does it add to Neovim?

NeoCodeium is a Lua plugin for Neovim that provides AI completion powered by Windsurf, formerly Codeium. It was created to remove the flickering suggestions of the official plugin, especially with multi-line virtual text, and it adds repeatable acceptance of suggestions with the `.` key.

### How do I install NeoCodeium with lazy.nvim?

Add the plugin spec to your plugin file with the event set to VeryLazy and call neocodeium.setup() in the config function. The README example binds `vim.keymap.set("i", "<A-f>", neocodeium.accept)` so Alt-f accepts a suggestion in insert mode.

### Does NeoCodeium work in Vim, and what are the requirements?

It supports only Neovim and requires Neovim 0.10.0 or newer. The README compares it with windsurf.vim, which is the option for Vim users.

### Is my code sent anywhere when I use NeoCodeium?

Yes. The README warns that your code is constantly sent to Windsurf servers by their own language server so completions can be evaluated. The server can be disabled globally or per buffer, and the plugin does not send data from disabled buffers, but the server may still be running behind the scenes.

### How do I control how much context NeoCodeium sends to the server?

The `max_lines` option caps how many lines are parsed from loaded buffers, with the current buffer always parsed in full, and it defaults to 10000. Setting it to 0 stops non-current buffers from being parsed at all, which the README notes may lower suggestion quality, and the `filter` function decides which buffers are enabled at all.

## Sources

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

---

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