On this page#
- What the integration actually does
- The wiring
- The two things that break it
- Verifying it works
- Team considerations
- FAQ
What the integration actually does#
The reliable Claude Code Neovim integration is deliberately small: run Claude Code in a terminal rooted at the repository, let it edit files on disk, and make Neovim notice those external changes. It does not turn Claude Code into an in-process Neovim plugin, and pretending otherwise creates fragile automation.
Claude Code is an agentic coding tool that can inspect a codebase, modify files, and run commands. Neovim remains the editor, buffer manager, and place where you review the resulting changes.
| What people expect | What actually happens | |---|---| | Claude edits the active Neovim buffer | Claude edits the file on disk | | Neovim automatically reflects every edit | A loaded buffer may remain stale | | The visible project is automatically the agent’s project | The agent operates from its terminal working directory | | Undo reverses the agent’s entire change | Neovim undo only covers changes known to that buffer | | A successful prompt proves correct wiring | The wrong checkout can be edited successfully |
That separation is good. Claude Code owns agent execution; Neovim owns editing and inspection. The official overview explains the agent’s codebase-level role, but it does not solve Neovim’s buffer synchronization for you.
The important boundary is filesystem state. If Claude changes src/api.lua while Neovim has an older, modified copy in memory, there are now two competing versions. A decorative chat window does nothing to resolve that conflict.
Photo by cottonbro studio on Pexels.
The wiring#
Wire Neovim Claude Code around three invariants: launch from the repository root, use the executable Neovim can actually resolve, and check for external file changes. The following Lua configuration provides that baseline without coupling your repository to a third-party Neovim plugin.
1. Make external changes visible#
Neovim must periodically check whether files changed outside the editor. autoread permits safe reloads, while checktime performs the actual timestamp check when you return to Neovim or revisit a buffer.
vim.opt.autoread = true
vim.api.nvim_create_autocmd(
{ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" },
{
group = vim.api.nvim_create_augroup(
"external_file_changes",
{ clear = true }
),
command = "checktime",
}
)This does not overwrite a locally modified buffer. That protection is essential: automatic synchronization must never silently discard human edits. Claude Code’s documented ability to change files is exactly why the editor-side reload policy matters; keep the Claude Code documentation as the authority for agent behavior.
2. Resolve the repository root and executable#
The command below finds the nearest .git directory, falls back to Neovim’s working directory, verifies that claude is available, and opens it in a bottom terminal split.
local function open_claude()
local root = vim.fs.root(0, { ".git" }) or vim.fn.getcwd()
local executable = vim.fn.exepath("claude")
if executable == "" then
vim.notify(
"Claude Code executable not found in Neovim's PATH",
vim.log.levels.ERROR
)
return
end
vim.cmd("botright 15split")
vim.cmd("terminal")
vim.fn.chansend(
vim.b.terminal_job_id,
"cd " .. vim.fn.shellescape(root) ..
" && " .. vim.fn.shellescape(executable) .. "\n"
)
vim.cmd("startinsert")
end
vim.api.nvim_create_user_command(
"ClaudeCode",
open_claude,
{ desc = "Open Claude Code at the repository root" }
)Launch it with:
:ClaudeCodeUsing vim.fs.root() matters in monorepos and when Neovim was started above or below the repository. Claude must operate on the same tree you are reviewing, not merely whatever directory the shell inherited.
3. Add an explicit review command#
After an agent turn, leave terminal mode, refresh file state, and inspect the repository diff. This makes review a named operation instead of an optional habit.
vim.api.nvim_create_user_command("ClaudeReview", function()
vim.cmd("checktime")
vim.cmd("botright new")
vim.fn.termopen({ "git", "diff", "--stat" })
vim.cmd("startinsert")
end, { desc = "Refresh buffers and show the current diff summary" })For repositories with stronger invariants, the next step is not more editor decoration. It is an operating contract covering scope, verification, rollback, and review. PairFoundry’s Agent Operating Kit is the relevant path; the packs overview shows the broader set.
The two things that break it#
Two failures account for most misleading setups: Neovim cannot see the Claude executable, or Neovim retains an old buffer after Claude changes its file. The first prevents startup. The second is worse because everything appears connected while your editor shows state that is no longer authoritative.
Failure 1: claude: command not found#
This means the shell environment inside Neovim does not have the same PATH as the terminal where Claude Code normally runs. Installing another plugin is the wrong fix; the problem occurs before any Neovim integration code can communicate with Claude.
Confirm what Neovim resolves:
:echo exepath("claude")If the result is empty, start Neovim from a shell where claude already resolves, or correct the environment used to launch Neovim. GUI launchers commonly inherit a different environment from interactive shells.
Do not hardcode a teammate-specific path in shared configuration. The earlier vim.fn.exepath("claude") check fails visibly and lets each machine resolve its own installation. Installation and authentication remain Claude Code concerns governed by the official documentation.
Failure 2: WARNING: The file has been changed since reading it!!!#
This is the failure mode thin integration guides miss. Claude successfully edited the file on disk, but Neovim still has an older buffer. If that buffer also contains unsaved edits, writing it can collide with or replace the agent’s work.
The safe response is:
- Stop and inspect the difference instead of forcing a write.
- Preserve intentional buffer edits with
:writebefore handing the file to Claude, or copy them elsewhere if a conflict already exists. - Use
:checktimefor clean buffers. - Use
:edit!only when you explicitly choose the disk version and accept losing unsaved buffer changes. - Review
git diffbefore continuing.
The automatic checktime configuration reduces stale clean buffers; it cannot decide which side of a genuine conflict is correct. That is a review decision, not a synchronization feature.
Photo by Christina Morillo on Pexels.
Verifying it works#
A working prompt is insufficient proof. Verification must establish that Claude is in the intended checkout, Neovim observes disk changes, unsaved buffers remain protected, and the repository diff contains only expected files. Test those properties before trusting the setup on real work.
Run this checklist:
- Open a tracked, clean file in Neovim.
- Run
:ClaudeCode. - In the Claude terminal, ask it to report the current working directory without changing anything.
- Confirm that directory is the repository Neovim is showing.
- Ask for one small, easily reversible edit to the open file.
- Return to the buffer and confirm the new content appears after
:checktime. - Run
:ClaudeReview, then inspect the fullgit diff. - Undo or revert the disposable edit through your normal repository workflow.
Repeat once with an unsaved Neovim change. The correct result is a warning or retained modified buffer—not silent replacement. The Claude Code overview describes an agent capable of acting across the codebase; your verification must therefore cover repository scope, not just the currently visible file.
For a deeper workflow track before standardizing the setup, use PairFoundry’s free foundations tutorials. Related integration patterns live under Wiring It In.
Team considerations#
A team-ready configuration must avoid machine-specific paths and document four things: launch command, repository-root rule, buffer-conflict policy, and required verification. Without that contract, the second developer inherits a shortcut whose hidden assumptions only exist on the first developer’s machine.
Keep shared configuration portable:
- Resolve
claudewithexepath()instead of embedding an absolute path. - Root sessions from
.git, especially when developers use worktrees. - Require clean or intentionally saved buffers before agent edits.
- Treat
git diffas the review surface, not the terminal transcript. - Keep authentication and local environment details out of the repository.
- Document the rollback path before encouraging broad agent changes.
Do not mandate a Neovim plugin merely to make adoption look standardized. Standardize the invariants first. Plugins may improve presentation, but they cannot eliminate wrong-directory execution, stale buffers, or conflicting unsaved changes.
Photo by Lukas Blazek on Pexels.
Related reading#
- Cursor VS Code: the wiring, and the two things that break it
- Obsidian MCP server — a setup that survives a second developer
FAQ#
Should I use Claude Code inside Neovim for every repository task?#
No. Use it when filesystem-level edits and terminal execution fit the task and the repository has a reliable review and verification path. Avoid handing it broad changes when unsaved editor state, generated files, unclear ownership, or missing tests make the resulting diff difficult to validate.
How is this different from an official Claude Code IDE integration?#
This setup intentionally uses Claude Code’s terminal workflow and Neovim’s native file and terminal primitives. It does not claim an embedded protocol or special editor awareness. The official Claude Code documentation remains authoritative for Claude Code itself; the Neovim synchronization layer is your configuration.
What should a teammate check when Neovim Claude Code works on one machine but not another?#
Check :echo exepath("claude"), the terminal’s working directory, and whether external-change autocmds are installed. Then compare local launch environments. A shared config can define behavior, but it cannot guarantee that every developer’s Neovim process inherits an identical executable path or authenticated session.
How do I back out safely when Claude changes the wrong files?#
Stop the agent, inspect the complete diff, and revert only the unwanted paths using the repository’s normal version-control workflow. Do not use :edit! indiscriminately: it discards unsaved buffer changes. Separate disk rollback from buffer recovery, then run :checktime after the repository state is correct.
When should I avoid a claude code neovim workflow entirely?#
Avoid it when the authoritative state does not live in files Claude can safely inspect, when repository commands can affect external systems, or when nobody can review the resulting diff. The integration is appropriate for controlled code changes; it is not permission to bypass operational boundaries.