What is MessagePack-RPC?
MessagePack-RPC is a binary RPC protocol built on top of MessagePack serialization. It enables efficient, language-agnostic remote procedure calls.Key Characteristics
- Binary protocol: More compact and efficient than JSON-RPC
- Language agnostic: Works with any language that has MessagePack support
- Bidirectional: Both client and server can initiate calls
- Asynchronous: Supports non-blocking requests and notifications
Protocol Specification
Nvim follows the MessagePack-RPC specification with some additional constraints:Nvim-Specific Constraints
Nvim adds these extra constraints to the standard MessagePack-RPC protocol: These constraints ensure predictable behavior and prevent race conditions.Message Types
MessagePack-RPC defines four message types:1. Request
A request expects a response from the server. Format:[0, msgid, method, params]
0: Message type (request)msgid: Unique integer ID for matching responsesmethod: String method name (e.g., “nvim_command”)params: Array of method parameters
2. Response
A response to a previous request. Format:[1, msgid, error, result]
1: Message type (response)msgid: ID of the request being responded toerror: Error object (null if successful)result: Return value (null if error)
3. Notification
A one-way message that does not expect a response. Format:[2, method, params]
2: Message type (notification)method: String method nameparams: Array of method parameters
Notifications are fire-and-forget. The sender does not wait for or receive a response.
4. Event (Nvim Extension)
Events are notifications sent from Nvim to the client (e.g., UI events, buffer updates). Format:[2, "event_name", [event_params]]
Example UI redraw event:
Request/Response Flow
Nvim processes request
Nvim receives the request, validates parameters, and executes the API function.
Synchronous vs Asynchronous
Synchronous Requests (Request/Response)
Block until a response is received:Asynchronous Notifications
Send fire-and-forget messages:Fast vs Deferred Functions
Most API functions are deferred: they are queued on the main loop and processed sequentially with normal input.If the editor is waiting for user input in a modal fashion (e.g., hit-enter prompt), deferred requests will block.
nvim_get_mode()nvim_input()nvim_input_mouse()- Other functions marked with
api-fastin documentation
vim.in_fast_event() to detect if you’re in a fast context.
Error Handling
Errors are returned in the response message: Error Format:[error_type, error_message]
Exception: General exceptionValidation: Invalid arguments
Extended Types (EXT)
Nvim uses MessagePack extension types for special objects:| Type | Code | Description |
|---|---|---|
| Buffer | 0 | Buffer handle |
| Window | 1 | Window handle |
| Tabpage | 2 | Tabpage handle |
Most client libraries handle these automatically. You typically work with opaque handle objects.
Connection Example
Here’s a low-level example showing the MessagePack-RPC protocol:Message Batching
You can send multiple messages in sequence without waiting for responses:Performance Considerations
Use Notifications for Fire-and-Forget
If you don’t need a response, use notifications:Batch API Calls
Usenvim_call_atomic() to batch multiple API calls into one request:
Use Buffer Updates for Large Text
For inserting large blocks of text, usenvim_paste() instead of multiple API calls:
Debugging RPC Communication
Enable RPC Logging
Set the$NVIM_LISTEN_ADDRESS environment variable to log RPC messages:
Inspect with tcpdump (TCP connections)
For TCP connections, you can capture packets:Manual Protocol Testing
Usenvim_get_api_info() to explore the API:
Security Considerations
Best Practices
- Use Unix sockets over TCP: Named pipes are more secure than TCP sockets
- Bind to localhost only: Never expose TCP sockets on public interfaces
- Set socket permissions: Restrict access to the socket file
- Validate client identity: Use
nvim_set_client_info()for authentication
Client Libraries
Official and community client libraries handle MessagePack-RPC for you:| Language | Library | Installation |
|---|---|---|
| Python | pynvim | pip install pynvim |
| Ruby | neovim-ruby | gem install neovim |
| JavaScript | node-client | npm install neovim |
| Lua | Built-in | vim.rpcrequest() |
| Go | go-client | go get github.com/neovim/go-client |
| Rust | nvim-rs | cargo add nvim-rs |
| Java | neovim-java | Maven/Gradle |
Using a client library is strongly recommended over implementing the protocol manually.
Next Steps
API Reference
Browse all available API functions
Buffer API
Buffer operations and updates