vim-ai: An OpenAI Client That Lives Inside Vim
AI-powered code assistant for Vim. OpenAI and ChatGPT plugin for Vim and Neovim.
At a glance
- What is it?
- vim-ai wraps OpenAI-compatible chat and completion endpoints in Vim commands and a Python layer. It suits editors who already work inside Vim buffers; it is a poor fit for anyone expecting a free or self-contained assistant.
- Who is it for?
- Adopt vim-ai if you already live in Vim or Neovim, have a paid OpenAI key or an OpenRouter account, and want AI edits to land directly in buffers and registers rather than in a browser tab. Do not adopt it if your environment lacks python3 support in the editor build, if you cannot send selected code to a third-party endpoint, or if you want an assistant that indexes your repository; this plugin has no project-wide context mechanism beyond what you select or type.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Activity is slowing. The repository last received commits 6 months ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The gap vim-ai fills between the buffer and the model
Most editors that gained AI features in the past few years shipped them as a sidebar, a chat panel, or a ghost-text overlay. Vim and Neovim did not get that treatment from their own maintainers, so the integration is left to plugins. vim-ai is one of the older attempts at that, and its design choice is visible in the command list: it treats AI as another Ex command rather than as a separate pane. The README describes the goal plainly: generate code, edit text, or hold an interactive conversation with GPT models, all powered by OpenAI's API. The audience is narrow and specific. It is for people who already keep their hands on the keyboard, who think in ranges and registers, and who would rather run :%AIE fix grammar over a whole buffer than copy text into a web chat and paste it back. It is not for people who want a chat product with history search, file trees, or agentic multi-step tasks. The plugin assumes you have an API key and are willing to pay per token, which the README states directly: usage of the API is not free, but the cost is reasonable and depends on how many tokens you use. That sentence is the whole business model of the project in miniature. There is no bundled model, no local inference, and no free tier provided by the plugin itself.
How a command becomes an API call
The repository is Python, and the README lists one hard prerequisite: Vim or Neovim compiled with python3 support. That is the load-bearing detail. The Vimscript layer defines the commands and reads configuration, then hands the work to Python, which owns the HTTP conversation with the provider. The data flow follows the shape of the command you type. A bare :AI {prompt} sends the prompt and completes it. A visual selection followed by :AIEdit sends the selected text plus an instruction, and the response replaces the selection in place. :AIChat opens or continues a conversation, and :AIStopChat interrupts generation mid-stream. :AIImage goes to an image endpoint instead of a text one. The README is explicit about what leaves your machine: the plugin does not send any of your code behind the scenes, and you only share and pay for what you specifically select, for prompts and chat content. That is a meaningful boundary. It also means the plugin has no ambient awareness of your project. If you want the model to know about a helper function in another file, you have to select it or paste it. Roles are the configuration mechanism layered on top. A role is a re-usable AI instruction and/or configuration, defined in an .ini file pointed at by g:vim_ai_roles_config_file. A role can set options globally, or scope them to one command with a section header like [o1-mini.chat], where the README sets options.stream = 0 and ui.populate_all_options = 1. Roles compose: :AI /o1-mini /grammar helo world! applies both. That composition is the most interesting part of the design, because it turns prompt engineering into something closer to a shell alias.
Installation, token file, and the keys you actually set
The install path is conventional. With vim-plug it is a single line, Plug 'madox2/vim-ai'. Manual installation uses Vim's built-in package mechanism, with the README giving separate clone targets for Vim (~/.vim/pack/plugins/start) and Neovim (~/.local/share/nvim/site/pack/plugins/start). Authentication is a file or an environment variable. The default is a token file at ~/.config/openai.token, written with echo "YOUR_OPENAI_API_KEY" > ~/.config/openai.token. The alternative is export OPENAI_API_KEY="YOUR_OPENAI_API_KEY". Both forms accept an organization id appended after a comma, as in YOUR_OPENAI_API_KEY,YOUR_OPENAI_ORG_ID. If you want the token somewhere else, set let g:vim_ai_token_file_path = '~/.config/openai.token' in your .vimrc. Roles live in a separate file referenced by let g:vim_ai_roles_config_file = '/path/to/my/roles.ini'. The README ships a roles-example.ini in the repository, which is the fastest way to see the syntax without inventing it. Two operational details are worth noting because they affect daily use. First, Ctrl-c cancels :AI and :AIEdit completion, so a slow or expensive request is interruptible. Second, command shortcuts exist (:AIE, :AIC, :AIS, :AIR, :AII), and the README suggests defining your own key bindings rather than relying on defaults. Debug logging is toggled with :AIUtilDebugOn and :AIUtilDebugOff, which is the first thing to reach for when a request returns nothing and you cannot tell whether the problem is the key, the network, or the prompt.
Provider plugins and the OpenAI-compatible escape hatch
vim-ai does not lock you to OpenAI's first-party API, but the escape hatch has two different shapes and they are not equally mature. The simpler one is a proxy. The README suggests OpenRouter, which it says offers many models for free at the time of writing, or a local LiteLLM instance, and it points to a wiki section on configuring custom OpenRouter roles. This works because the plugin talks to anything that speaks the OpenAI wire format. The second shape is the provider plugin system, announced in the README with the admission that there aren't many available yet, so developing new ones is welcome. Three are listed: a Google provider for Gemini models, an OpenAI Responses API provider, and an OpenAI provider with MCP support. The README points developers at the Google provider as the reference implementation and asks them to open a PR to update the list. That is the honest state of the ecosystem. If you want Gemini or Claude today, the proxy route is the one with the least moving parts, and the plugin's own documentation treats it as the primary path rather than a workaround. The provider plugin route is for people who want a native integration and are prepared to write or maintain one.
Where vim-ai stops being the right tool
The clearest limitation is context. Because the plugin only sends what you select or type, it cannot answer questions that require reading your repository. There is no indexing step, no embedding store, and no tool that opens files on the model's behalf. A prompt like "refactor this module" only works if the whole module is in the selection. That is a deliberate privacy property and a real capability ceiling at the same time, and you cannot have one without the other here. The second limitation is the python3 requirement. Vim builds vary widely, and a distribution-packaged Vim without python3 support will not run this plugin at all, regardless of how the Vimscript layer is configured. The README states this as a prerequisite rather than a caveat, which is fair, but it is the first thing to check before spending time on installation. The third is cost predictability. Chat mode accumulates tokens across turns, and the README's own framing, that cost depends on how many tokens you use, means a long :AIChat session against a large model is the expensive path. The plugin gives you :AIStopChat and Ctrl-c, but no budget cap, no per-session token counter, and no warning before an expensive request. If you are on a metered key, that absence matters more than any feature on the list. Finally, the project has no retrieved releases, so there is no versioned changelog to consult. Updates arrive by pulling the repository, and there is no upgrade path documented beyond that.
Alternatives and the difference in approach
The most direct comparison is with editor-agnostic CLI tools such as llm, simonw's command-line client for language models. The difference is where the text lives. llm is a Unix filter: you pipe text in, you get text out, and you compose it with other shell tools. vim-ai is the inverse. It keeps the interaction inside the editor's command language, so ranges, visual selections, and registers are the interface, and the result lands in the buffer rather than in stdout. If your workflow already routes through the shell, llm composes better; if your workflow is a buffer you are editing, vim-ai requires fewer context switches. The second comparison is with Neovim's built-in LSP and completion stack. That stack is local, deterministic, and free, and it does not send your code anywhere. It also cannot rewrite a paragraph of prose or explain an error message. vim-ai is not a replacement for completion; it is a second, separate facility that happens to sit in the same editor. The third comparison is with hosted assistants that index a repository. Those trade the selection boundary for context, which is exactly the trade vim-ai declines to make. Choosing between them is choosing whether you want the model to see your project or only your cursor.
Maintenance, licensing, and what the MIT grant does not cover
The plugin is MIT licensed, which permits commercial use, modification, and redistribution provided the copyright notice and permission notice are preserved. That covers the plugin's own code. It does not cover the API you point it at. Your OpenAI, OpenRouter, or proxy account carries its own terms, its own data handling policy, and its own billing, and the MIT grant from madox2 says nothing about any of that. The README's statement that the plugin does not send code behind the scenes is a description of the plugin's behaviour, not a guarantee about what the upstream provider does with a request once it arrives. Treat those as two separate questions. On maintenance: the repository is not archived and the last push is recent, but with no retrieved releases there is no semantic versioning to pin against. If you vendor the plugin, you are tracking a branch, and a pull can change behaviour without a version number to warn you. The provider plugin list is a further maintenance surface, since those are separate repositories with separate maintainers. A reasonable posture is to pin a commit hash in your plugin manager rather than tracking main, and to read the diff before moving the pin. That is a concrete step, not a general recommendation: it is the only versioning discipline the project's release situation currently allows.
Editorial conclusion
Adopt vim-ai if you already live in Vim or Neovim, have a paid OpenAI key or an OpenRouter account, and want AI edits to land directly in buffers and registers rather than in a browser tab. Do not adopt it if your environment lacks python3 support in the editor build, if you cannot send selected code to a third-party endpoint, or if you want an assistant that indexes your repository; this plugin has no project-wide context mechanism beyond what you select or type. Before committing, verify three things: that your Vim or Neovim reports python3 support, that ~/.config/openai.token or OPENAI_API_KEY is readable by the plugin, and that a single :AIEdit /grammar run on a scratch buffer returns a response you are willing to pay for.
Community notes