Open-Source Wikis

/

Neovim

/

How to contribute

neovim/neovim

How to contribute

The canonical contributor docs live in CONTRIBUTING.md at the repo root and runtime/doc/dev*.txt. This page is the orientation that points you at them in the right order.

Where to start

If you have not built Neovim yet, do that first: Getting started.

For a first patch, the official suggestions are:

  • The complexity:low issue label on GitHub.
  • Bugs found by Coverity (you can request access; the report is not public).
  • A Vim patch — porting a small change from upstream Vim. This requires familiarity with both editors but the workflow is well-documented in runtime/doc/dev_vimpatch.txt.

If you don't know where the code you want to change lives, Architecture and Systems are the maps.

Pull request checklist

The maintainers care about each of these:

  1. Conventional commit subject. type(scope): subject. Types: build, ci, docs, feat, fix, perf, refactor, revert, test, vim-patch. Append ! for a breaking change.
  2. Problem / Solution body. Describe the problem first, then the solution. The PR description should be substantively the same as the commit body.
  3. Tests. Almost every change needs a functional or unit test. See Testing.
  4. No unrelated cosmetic edits. Drive-by formatting in unrelated files makes review hard.
  5. Rebased on master, not merged. Force-push after addressing review comments is normal.
  6. CI green. The full matrix runs lint, unittest, functionaltest, oldtest, ASAN/UBSAN, valgrind, and the docs lint.

AI-assisted work

CONTRIBUTING.md and AGENTS.md are explicit:

  • YOU review any AI-generated diff before marking the PR ready.
  • No verbosity. Strip the model's editorial flourishes from doc, comments, commit messages, and PR descriptions.
  • No redundant code or tests. Deduplicate before submitting.
  • AI disclosure. Add an AI-assisted: <tool name> trailer to every commit that used AI in any capacity.

A PR that arrives with hedged, verbose, or duplicative AI-style content gets bounced back for cleanup before it is reviewed for correctness.

What goes into C versus Lua

Verbatim from CONTRIBUTING.md: "New functionality should generally be implemented in Lua, not C." The reference PRs #37757 and #37831 are cited as good examples.

The decision tree in runtime/doc/dev_arch.txt for adding a new Vimscript function or Ex command:

  1. Full Lua — implementation entirely in Lua under runtime/lua/vim/_core/vimfn.lua. Vimscript callers go through a tiny C wrapper. Preferred.
  2. Partial Lua — a thin C function calls into Lua via nlua_call_vimfn / nlua_call_excmd. Useful when the C side already has the data.
  3. Legacy C — only when there is a concrete reason not to use Lua.

Same hierarchy applies to autocmds, options, UI events, and most "new feature" patches.

Style and structure

  • C style is src/uncrustify.cfg (with .clang-format as a softer fallback). make formatc formats changed C in place.
  • Lua style is stylua against .stylua.toml. make formatlua formats it.
  • Tree-sitter queries are formatted with make formatquery.
  • Lint with make lint. CI builds with -Werror, so a warning is a failure.
  • Header hygiene uses include-what-you-use. make iwyu applies the suggestions.

The full style guide is at runtime/doc/dev_style.txt.

Reviewing

Reviewers pull PRs locally with gh pr checkout <url>. To get a useful diff for the conversation:

git log -p -W master..FETCH_HEAD

Show the full surrounding function for each change with -W; show a per-commit diff with -p.

Where the deep dives live

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

How to contribute – Neovim wiki | Factory