# Neovim carries a Zig build, a BSDmakefile, and a moving stable tag, none of which the README walks you through

> Neovim refactors Vim around a messagepack RPC layer and its own Lua and Vimscript subsystems. The build wrapper, the license boundary and the release tags all have sharp edges that the short README does not spell out.

**neovim/neovim** — An extensible Vim-based editor focused on usability and modern integrations.

- Repository: https://github.com/neovim/neovim
- Website: https://neovim.io
- Stars: 102,667 · Forks: 7,141
- Language: Vim Script
- License: not declared
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/neovim-neovim

## The tree carries build.zig and a BSDmakefile, and the README names only CMake

The install from source section says the build is CMake-based and that a Makefile is provided as a convenience, then hands you two commands. The root disagrees quietly, because the file list also includes build.zig and build.zig.zon, plus a BSDmakefile sitting next to Makefile, plus CMakePresets.json and a cmake.packaging/ directory. That is two build description systems, two make entry points, and a preset file, with only one of them described in the text people actually read. Consequence for a reader: a source build has more than one entry point and the README does not tell you which one the project treats as current. If you pick the Zig build because it is in the tree, you are choosing a path nobody in this file has described for you, and CMakePresets.json exists for people who want the other one enumerated. Nothing in the visible text ties build.zig to a release, so treat the CMake route as the documented one and the Zig files as an alternative someone is working on.

## On Windows the wrapper forces Ninja and PowerShell with no fallback

The Makefile branches on the operating system and the two branches are not symmetric.

```make
  MKDIR := @$$null = new-item -itemtype directory -force
  TOUCH := @$$null = new-item -force
  RM := remove-item -force
  CMAKE := cmake
  CMAKE_GENERATOR := Ninja
```

That is the Windows side, reached when OS is Windows_NT and the PATH has no semicolon. It sets SHELL to powershell.exe with -NoProfile -NoLogo, rewrites mkdir, touch and rm as PowerShell cmdlets, and hard-codes the Ninja generator. The Unix side is gentler: it probes for cmake3, then cmake, and chooses Ninja only if ninja is on the PATH, otherwise falling back to Unix Makefiles.

```make
  CMAKE := $(shell (command -v cmake3 || command -v cmake || echo cmake))
  CMAKE_GENERATOR ?= "$(shell (command -v ninja > /dev/null 2>&1 && echo "Ninja") || echo "Unix Makefiles")"
```

Consequence: on Windows a missing Ninja install has no fallback path, and -NoProfile means your PowerShell profile cannot adjust anything the wrapper does. On Unix the reverse holds, since an absent ninja silently downgrades you to Unix Makefiles instead of telling you, and the same missing binary therefore produces two different build systems on two platforms.

## local.mk is pulled in silently, so one commit can produce two different builds

One line does most of the damage here.

```make
-include local.mk
```

The comment above it points at contrib/local.mk.example, so the intended use is a local override file that is not tracked. The same file also defines the boolean filters the rest of the build uses, which tells you exactly which spellings are accepted.

```make
filter-false = $(strip $(filter-out 0 off OFF false FALSE,$1))
filter-true = $(strip $(filter-out 1 on ON true TRUE,$1))
```

So a flag is 0, off, OFF, false or FALSE for false, and 1, on, ON, true or TRUE for true, and nothing else. Consequence for a reader: local.mk is included without error when absent and without record when present, so a build difference between your machine and a colleague's has no trace in git, and a value you pass in another case form is not rejected, it is just passed through unfiltered.

## The install prefix is checked against a stale cache, and checkprefix is how it fails

The prefix can arrive two ways, directly as CMAKE_INSTALL_PREFIX or buried inside CMAKE_EXTRA_FLAGS, and the Makefile greps for it.

```bash
make CMAKE_BUILD_TYPE=RelWithDebInfo CMAKE_INSTALL_PREFIX=/full/path/
make install
```

The comment above that block notes the second form, and that a target called checkprefix verifies the value against the CMake-cached one, citing issue 9615. Once a prefix is found, it is forced into CMAKE_EXTRA_FLAGS with an override. That is the whole point of the check. Consequence: what can disagree with your new prefix is the build directory you already have, because build/CMakeCache.txt still holds the old resolved value, and the README points you at that same file as a debugging aid. A reused build tree therefore fails at a check target rather than quietly installing to the wrong place, and the fix is a clean configure, not a different flag. The Unix default path also does not take a prefix, so sudo appears only in that one command.

## Apache 2.0 starts at commit b17d96, and vim-patch code keeps other terms

The license paragraph is short and has two conditions. Contributions since b17d96 are Apache 2.0, except contributions copied from Vim, which are identified by a token, vim-patch, in the commit. The full detail is in LICENSE.txt, and the root also holds a file named BSDmakefile, which is a naming history rather than a license statement but does tell you the project did not begin under Apache 2.0. The README gives no date for b17d96, so you cannot tell from this file how much history predates the grant. Consequence for a reader: you cannot assume an arbitrary Neovim commit is Apache 2.0. If you are vendoring or redistributing, you have to check each commit for that token, and code lifted from Vim is not covered by the project's own license grant at all.

## The managed package list is six Unix distributions and Windows gets a tarball

Two install routes, and they are not equal. Managed packages are named for Homebrew, Debian, Ubuntu, Fedora, Arch Linux, Void Linux and Gentoo. Pre-built packages for Windows, macOS and Linux are on the Releases page. Every named package manager is a Unix one; Windows appears only as a download, and no Snap, Flatpak or Nix entry is listed. The pre-built route also changes what you get, because the Releases page carries two floating tags alongside the versioned one: nightly, described as an Nvim development prerelease build, and stable, described as an Nvim release build. Consequence for a reader: a Windows user has no named package route in this file, and a distribution packager choosing between tags has to decide whether they want the fixed artifact at v0.12.5 or whatever stable currently points at, because the two tags do not move together.

## The stable and nightly tags are a month apart right now

The release list shows the shape of the project's versioning. There is a tag literally named nightly, updated 2026-09-30, described as an Nvim development prerelease build. There is a tag literally named stable, dated 2026-08-23, described as an Nvim release build. And there is a fixed artifact, v0.12.5, dated the same 2026-08-23. The two floating tags are therefore a rolling window onto the same moment, roughly five weeks apart from each other, and both sit inside a 0.x version line. The README's answer to what changed is `:help news` for noteworthy changes in the latest version, with the full feature list at `:help nvim-features`. Consequence for a reader: a number in the 0.12 line tells you far less than a plugin author would like, and a bug report is more useful with the exact tag than with the word stable, because stable can point at a different commit by the time anyone reads it.

## generators/ writes source at build time, so the tree you read is not the tree you compile

The project layout puts a code generation step inside the application source.

    │  ├─ generators/   code generation (pre-compilation)

Alongside it sit api/ for the API subsystem, eval/ for Vimscript, event/ for the event loop, lua/ for the Lua subsystem, msgpack_rpc/ for RPC, os/ for platform code, and tui/ for the built-in UI. Two scripting subsystems are named and neither Ruby nor Python is, which is what makes the feature line about compatibility with most Vim plugins, including Ruby and Python plugins, a compatibility statement rather than a host for those runtimes. The messagepack RPC layer is the one transport, so a language on the long list of API clients is a client somebody else wrote. Consequence for a reader: reading this repository is not the same as reading what you compile, and a grep through src/ can miss behaviour that only exists after generation runs.

## Conclusion

Neovim suits people who want a programmable editor core with a real RPC surface and a Lua runtime, and who will read BUILD.md and the Makefile rather than expect a package to answer everything. Do not pick it on a promise of Vim plugin compatibility, because the stated claim is most plugins and the authoritative list is not in the README. Before you commit, check the platform support page for your own system, decide whether you are tracking the moving stable tag or a fixed 0.12.5, and read LICENSE.txt if you intend to redistribute code that came from Vim.

## FAQ

### Is Neovim an ide?

The README does not call it an IDE. It lists an embedded scriptable terminal emulator, asynchronous job control, and API access from languages including C/C++, C#, Go, JavaScript/Node.js, Lua, Python, Ruby and Rust, then sends you to `:help nvim-features` for the full list.

### Which one is better, Vim or Neovim?

The project states its aim as aggressively refactoring Vim, to simplify maintenance, split work between developers, enable advanced UIs without core changes, and maximize extensibility. For moving over, it points at `:help nvim-from-vim` rather than making the case for you.

### how to install neovim on ubuntu

Ubuntu is one of the named managed package targets, alongside Homebrew, Debian, Fedora, Arch Linux, Void Linux and Gentoo. Pre-built packages for Windows, macOS and Linux are on the Releases page, and a source build uses CMake with the provided Makefile.

### how to use neovim on windows

Pre-built Windows packages are on the Releases page, and no Windows package manager is named in the managed list. Building there goes through the root Makefile, which sets SHELL to powershell.exe with -NoProfile -NoLogo and fixes the CMake generator to Ninja.

### how to use neovim terminal

The feature list names an embedded, scriptable terminal emulator as part of the editor and links it to the terminal page in the user documentation. The project layout shows the editor core under src/nvim/ with subsystems for the API, the event loop, Lua, Vimscript and msgpack RPC.

## Sources

- [Official documentation](https://neovim.io)
- [Official README](https://github.com/neovim/neovim#readme)
- [Project repository](https://github.com/neovim/neovim)
- [Release notes](https://github.com/neovim/neovim/releases)

---

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