tmux.nvim: one set of keys across Neovim splits and tmux panes
tmux integration for nvim features pane movement and resizing from within nvim.
At a glance
- What is it?
- tmux.nvim is a Neovim plugin that shares clipboard registers with tmux and lets you move and resize across the boundary between a Neovim split and a tmux pane. It is a small Lua plugin with a large configuration surface, and its README says plainly that the author no longer uses tmux and will no longer implement fixes or features.
- Who is it for?
- Adopt tmux.nvim if you work with Neovim inside tmux and want one keyboard model across both, particularly if you routinely yank in one editor instance and paste in another. Do not adopt it as a maintained dependency, because the README states that the author no longer uses tmux and will no longer implement fixes, features or maintenance, with pull requests the only route forward.
- 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?
- Yes. The repository last received commits 7 days ago.
- What is it written in?
- Mainly Lua, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The seam between Neovim splits and tmux panes
tmux.nvim is a Neovim plugin that provides tmux integration for pane movement and resizing from within Neovim. The problem it addresses is a small but persistent annoyance: when you run Neovim inside a tmux pane, the split inside the editor and the pane outside it are two separate hierarchies, and moving between them with the same keys does not work without help.
The plugin shows three features in its README, each with a short demonstration video. Copy from Neovim to Neovim to tmux covers the clipboard case. Navigating from Neovim into tmux panes covers crossing the border. Resizing Neovim splits like tmux panes covers the sizing case.
The requirements are modest: Neovim 0.5 or later, and the plugin and its .tmux.conf scripts are described as battle tested with tmux 3.2a. The repository is a Lua plugin with a spec/ directory for tests, a .luacheckrc, a .stylua.toml for formatting, a flake.nix for development environments, and a tmux.nvim.tmux file that carries the tmux side of the configuration.
The implementation note that matters most is in the usage section: the plugin uses only the Lua API, and the tmux side of the setup has to be added to your own tmux configuration. That is the central design decision here, and the next sections look at what it costs.
Copy sync uses tmux buffers as the master clipboard
The copy sync feature is the most substantial part of the plugin. It uses tmux buffers as the master clipboard for the *, +, unnamed and 0 to 9 registers, and the README stresses that the sync does not rely on temporary files and works with the given tmux API only, which it describes as less insecure.
The practical effect is that a Neovim instance can sit over a shared copy and paste process. You delete in one instance, switch to the second, and paste. That is a small feature that changes how a multi instance workflow feels, and it is the reason the plugin exists rather than being a set of key bindings alone.
The configuration surface here is large enough to need reading. The sync_deletes option is on by default, and the README explains why it cannot be otherwise: Neovim does not allow syncing registers 0 and 1 without overwriting the unnamed register, so the ddp idiom would not be possible if they were synced. The sync_registers_keymap_put and sync_registers_keymap_reg options control whether registers are synchronised when pressing p and P, and when pressing (C-r) and " respectively.
Two options deserve a warning. sync_clipboard is on by default and it overwrites vim.g.clipboard to redirect the * and + registers through tmux, so if you sync your system clipboard without tmux you must disable it. And the README notes a real downside: on really slow machines, calling registers or pasting will eventually produce minimal input lag, because registers are synced in advance to keep the state correct. Disabling sync_registers reduces the effect, but then only the * and + registers are redirected.
Navigation needs matching bindings on both sides
Navigating from Neovim into tmux panes requires configuration in two places, and the README is emphatic that they have to agree. It says your bindings in Neovim must match the bindings defined in tmux, otherwise the pass through will not have the effect it is supposed to have.
The tmux side detects whether the pane is running a Vim-like editor and then decides between sending the key to the editor and moving the pane. The detection is a shell expression against the pane's tty:
is_vim="ps -o state= -o comm= -t '#{pane_tty}' | grep -iqE '^[^TXZ ]+ +(\\S+\\/)?g?\.?(view|n?vim?x?)(-wrapped)?(diff)?$'"The bindings then do double duty. For C-h, if the shell test says the pane holds an editor, the key is sent through to the editor, and only if the pane is at the left edge does tmux move the selection instead:
bind-key -n 'C-h' if-shell "$is_vim" 'send-keys C-h' { if -F '#{pane_at_left}' '' 'select-pane -L' }The same pattern covers C-j, C-k and C-l for the other three directions, plus C-n and C-p for moving between windows, and there is a matching set for the copy-mode-vi table.
That double duty is the mechanism of the whole plugin: the key is forwarded into the editor while there is somewhere to go inside it, and becomes a tmux command when the editor has run out of room. The navigation options in the plugin's own configuration mirror this, with cycle_navigation for cycling to the opposite pane when you move into the border, enable_default_keybindings for the C-hjkl bindings in normal mode, and persist_zoom to prevent tmux from unzooming when you move beyond the Neovim border.
Resizing splits and swapping panes with the same keys
The resize feature gives Neovim splits the same key model as tmux panes. The default keybindings are enabled with the A-hjkl combination in normal mode, and the resize step for the x axis and the y axis are each 1 by default, which is the granularity of a single character cell or line rather than a percentage.
The swap feature is the fourth block in the configuration, and it is configured slightly differently from the others. Its cycle_navigation option is false by default, unlike the navigation block where it is true, and its default keybindings are the C-A-hjkl combination.
Taken together, the four configuration blocks describe a plugin whose scope is deliberately narrow. There is no session management, no window layout engine and no replacement for tmux's own configuration. The plugin sits at the boundary and translates between two hierarchies.
That boundary is also why the tmux configuration matters so much. The .tmux.conf scripts that ship with the project are the tmux half of the contract, and the repository keeps them in a tmux.nvim.tmux file, so the plugin's own tmux side can be inspected and adapted rather than copied blindly.
What the copy sync defaults actually do
Because the copy sync block has so many options, it is worth walking through what the defaults add up to.
The block starts with enable, which turns copy sync on, and the comment notes that by default all registers are synchronized and that the sync_* options control which ones. ignore_buffers starts as an empty table with the empty key set to false, and it exists so that specific tmux buffers can be left out of the sync. The README is specific about the format, saying that ignoring buffers must have the form buffer_name = true to enable an unsorted list in Lua, which it claims enhances the performance of the checks.
register_offset controls where the register sync starts, with an offset of 2 leaving registers 0 and 1 untouched. sync_unnamed synchronises the unnamed register with the first buffer entry from tmux.
redirect_to_clipboard is false by default and the comment explains the version dependency: with TMUX at or above 3.2, all yanks and deletes will get redirected to the system clipboard by tmux. The plugin will set the -w option on set-buffer to achieve that, and for setups where tmux needs more configuration the README points at the tmux-yank plugin.
The installation itself is short. With packer.nvim, the plugin is added and the setup function run:
use({
"aserowy/tmux.nvim",
config = function() return require("tmux").setup() end
})The README notes that the configuration step is only necessary if you want to overwrite the defaults.
An upstream status note you should read first
The first thing in the README is a notice about the author's own workflow, and it changes how you should evaluate this plugin.
The statement is that as the author's workflow has changed over time, they no longer use tmux, and that while they will continue to maintain the plugin, they will no longer implement fixes, features or maintenance. Pull requests are always welcome and will be merged upon review.
Read carefully, that describes a project whose primary author has left the use case it was built for. The maintainer role is retained, the merge policy for contributions is stated, and the repository is not archived, and the last push was on 2026-10-16 with a CI badge and coveralls coverage badge in the README and dependabot enabled. But a plugin whose author has stopped running tmux is a plugin whose edge cases will be discovered by users rather than by its author.
The code quality signals are still good by the standards of a small Neovim plugin. There is a spec directory, so the behaviour is tested, a luacheckrc for linting, a stylua configuration for formatting, a flake for the development environment and a .dev directory. The structure is that of a project that was set up properly, and the question for an adopter is who will exercise it now.
Where tmux.nvim is the wrong tool
Three situations point elsewhere.
The first is a workflow that has moved on from tmux. That is the author's own situation, and it is the clearest evidence of the boundary. If your work is a single Neovim instance with its own splits, the whole plugin is unnecessary, because the features it provides exist to bridge two hierarchies that you no longer have.
The second is a team that wants one maintained source of truth for key bindings. The plugin's design requires the bindings to exist in two places and to match. The README says so explicitly. That is manageable for one person with one tmux configuration, and it becomes a coordination problem for a team, since a change to a binding has to be made in the Neovim configuration and in the tmux configuration and kept in step.
The third is a setup where the tmux version is not 3.2a or later. The README names that version as the one the plugin and its scripts are battle tested with, and several options are tied to specific tmux behaviours, such as the clipboard redirection that relies on tmux 3.2 and later redirecting yanks and deletes to the system clipboard. On an older tmux, or on a machine where tmux is managed by another layer, some of the options will not do what the comments say.
There is one more cost worth naming. Copy sync works by keeping state in step ahead of time, and the README says that on really slow machines this produces input lag when calling registers or pasting. A plugin that improves a workflow and then adds latency to the editor is a poor trade on a weak machine, and the fix is to disable the broader register syncing and keep only the * and + registers.
Editorial conclusion
Adopt tmux.nvim if you work with Neovim inside tmux and want one keyboard model across both, particularly if you routinely yank in one editor instance and paste in another. Do not adopt it as a maintained dependency, because the README states that the author no longer uses tmux and will no longer implement fixes, features or maintenance, with pull requests the only route forward. Verify three things first: that your tmux version matches the one the plugin was tested against, which the README names as tmux 3.2a; that your Neovim version satisfies the stated floor of 0.5 or later; and that the key bindings you configure in Neovim match the ones in your tmux configuration, because the README warns that the pass through effect depends on both sides agreeing. The licence is MIT and the last push was on 2026-10-16.
Frequently asked questions
What does tmux.nvim do?
It is a Neovim plugin that provides tmux integration for pane movement and resizing from within Neovim, with three headline features: copying between Neovim instances through tmux, navigating from Neovim into tmux panes, and resizing Neovim splits like tmux panes.
How do I install tmux.nvim?
With packer.nvim, add the plugin and call its setup function: use({ "aserowy/tmux.nvim", config = function() return require("tmux").setup() end }). The setup call is only necessary if you want to change the defaults, and the requirements are Neovim 0.5 or later and tmux 3.2a.
How does the copy sync feature work?
It uses tmux buffers as the master clipboard for the *, +, unnamed and 0 to 9 registers, without relying on temporary files and using only the given tmux API. That makes a delete in one Neovim instance pasteable in another. The README warns that on slow machines this produces input lag, and that disabling sync_registers limits the redirect to the * and + registers.
Why do I need tmux configuration as well as Neovim configuration?
The tmux bindings detect whether the pane holds a Vim-like editor and either forward the key into the editor or move the pane, and the README states that your bindings in Neovim must match the bindings defined in tmux, otherwise the pass through will not have the effect it should.
Is tmux.nvim still maintained?
The README states that the author no longer uses tmux and will no longer implement fixes, features or maintenance, while pull requests are welcome and will be merged upon review. The repository is not archived and the last push was on 2026-10-16.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/aserowy-tmux-nvim)Was this useful?