hardtime.nvim: a Neovim plugin that blocks repeated key presses
Break bad habits, master Vim motions
At a glance
- What is it?
- hardtime.nvim watches your keystrokes, blocks keys pressed too many times inside a one second window, and prints a faster alternative. It is a training tool for Vim users, not a general-purpose plugin.
- Who is it for?
- Adopt hardtime.nvim if you type hjkl and arrow keys out of muscle memory and want the editor to stop you mid-habit. Skip it if you rely on the mouse, on arrow keys in a terminal without a statusline, or on long scroll sessions, because disable_mouse defaults to true and the hint message can be overwritten by the mode message.
- 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 18 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 September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The habit hardtime.nvim is built to interrupt
Most Vim advice is a list of better commands. hardtime.nvim takes the opposite route: it assumes you already know `w`, `f` and `CTRL-D`, and that the reason you press `j` eleven times is not ignorance but reflex. The plugin watches key presses, counts repeats inside a window, and refuses the ones that exceed a threshold. The README describes the goal as breaking bad habits and mastering Vim motions, and the feature list is three items long: block repeated keys within a short period of time, provide hints for faster Vim motions, and report your most common bad habits.
The intended audience is narrow and identifiable. You are a Neovim user who has moved past the tutorial stage and wants to stop reaching for `h` and `l` when `f` or `t` would land you in one press. It is not a plugin for people still learning what normal mode is; a blocked key with a hint message is confusing if you do not yet know the alternative exists. The README's recommended workflow spells out the alternatives it wants you to use: relative jumps like `5j` and `12-`, screen jumps with `CTRL-U`, `CTRL-D`, `CTRL-B`, `CTRL-F`, `gg` and `G`, word motions, and operator plus motion combinations such as `ci{`, `y5j` and `dap`.
How the repeat counter and hint messages actually work
The mechanism is a keystroke counter with a time window. Two options define the window: `max_time`, default `1000`, is the number of milliseconds inside which presses count as repeated, and `max_count`, default `3`, is how many repeats are allowed in that window. So with defaults, a fourth `j` inside one second is treated as a bad habit. `allow_different_key`, default `true`, lets a different key reset the count, which means a burst of alternating keys is not punished. The `resetting_keys` table controls which keys reset the count and in which modes.
When a key is over the limit, hardtime.nvim blocks it and, if `hint` is `true` (the default), shows a message suggesting a faster command. `notification`, also default `true`, controls the messages for restricted and disabled keys, and `timeout`, default `3000` milliseconds, controls how long they stay on screen; setting it to `false` disables the timeout. A log is written to `~/.local/state/nvim/hardtime.nvim.log`, and `:Hardtime report` summarises the hints you have triggered most often. That report is the part I find most useful in principle, because it turns an abstract complaint about your habits into a list of specific keys and counts.
The plugin is enabled by default, and the state commands are `:Hardtime enable`, `:Hardtime disable` and `:Hardtime toggle`. The `enabled` option sets the starting state instead. `disable_mouse` defaults to `true`, so mouse support is off unless you turn it back on. `disabled_filetypes` takes a table with exact names and glob patterns, and the README's example shows `lazy = false` to enable Hardtime in the lazy filetype and `["dapui*"] = false` to enable it in any filetype starting with dapui. Note the inversion in that table: setting a filetype to `false` turns Hardtime on there, because the default is to stay out of the way.
Installing hardtime.nvim and running your first report
The requirements section lists Neovim v0.10.0 or newer, and the plugin is written in Lua. The README shows installation through a package manager, with lazy.nvim as the example. The `nui.nvim` dependency is required for the notification interface, and `lazy = false` means the plugin loads at startup rather than on an event.
{
"m4xshen/hardtime.nvim",
lazy = false,
dependencies = { "MunifTanjim/nui.nvim" },
opts = {},
},With lazy.nvim, setting `opts` as above is enough, because the plugin manager calls `setup()` for you. If you install it another way, the README says to call setup yourself in `init.lua`:
require("hardtime").setup()After that, Hardtime is already active. Press a key past the default threshold and you should see a hint message on the command line, plus a notification for the blocked key. To see what you have been doing wrong, run the report command:
:Hardtime reportThe README does not show the report's exact output format, only that it lists your most frequently seen hints. If the message is replaced by the mode indicator before you can read it, the README gives three fixes: set `'showmode'` to false and put the mode on a statusline plugin such as lualine.nvim, set `'cmdheight'` to 2, or route hints through nvim-notify in the top right corner. The README also states that `'showmode'` must be false for hint messages to appear in insert and visual mode at all.
Where hardtime.nvim gets in the way
The blocking behaviour is the product, so the failure mode is the same as the feature: a legitimate sequence of repeated keys is refused. Holding `j` to scroll through a long file is the obvious case. So is a deliberate run of `x` deletions or repeated `p` pastes, both of which are normal editing, not bad habits. The escape hatches exist (`:Hardtime toggle`, `:Hardtime disable`, a longer `max_time`, a higher `max_count`, or `disabled_keys`), but every one of them is a decision you make while annoyed, which is a poor time to make it.
The mouse situation is worth stating plainly. `disable_mouse` defaults to `true`, so out of the box the plugin turns off mouse support. If your workflow depends on clicking to place the cursor, you are changing that default or turning the plugin off. The hint display is the second rough edge: the README itself documents that the hint message can be replaced by the mode message, which is why it offers the `'showmode'` and `'cmdheight'` workarounds. That is a real configuration cost for a plugin whose whole value is showing you the hint.
Finally, this is the wrong tool for anyone who has not internalised the alternatives. A blocked `j` with a suggestion to use `5j` only helps if you understand relative line numbers and counts. For a beginner, hardtime.nvim adds friction to the one activity they need most, which is moving around and getting used to the editor. The README's own framing, mastering motions, assumes the motions are already known.
Compared with mini.move and the manual approach
There is no shortage of Neovim plugins that change how you move, but most of them add a motion rather than remove a key. Plugins in the mini.nvim family, for example mini.move, give you commands to move lines and selections around; they extend your vocabulary. hardtime.nvim does the reverse. It subtracts keys from your vocabulary for a moment and leaves a message where the key would have acted. That difference matters when you choose: a motion plugin changes what you can do, while hardtime.nvim changes what you are allowed to do, and only for a second at a time.
The other alternative is doing nothing and relying on discipline. That is cheaper, has no Neovim version floor, no `nui.nvim` dependency and no log file, and it is what most people actually do. The argument for hardtime.nvim over willpower is the report: `:Hardtime report` and the log at `~/.local/state/nvim/hardtime.nvim.log` give you evidence about which keys you overuse, which is hard to self-assess while editing. If you have never looked at your own keystroke patterns, that report is the honest reason to try the plugin, not the blocking.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-13, so it is currently maintained. The release history is short and recent: v1.0.0 on 2025-05-18, v1.1.0 on 2025-05-21, and v1.2.0 on 2025-06-17. The README does not document a rollback procedure or a migration guide between these versions, so pinning a tag in your plugin manager is the only version control the documentation supports.
The licence is MIT, which is permissive and places few obligations on users who embed or redistribute the code; the repository contains a LICENSE file at the top level. That is a description of the licence, not legal advice, and the usual caveat applies if you are shipping this inside a product.
The upgrade cost is mostly configuration drift. The option table is long, and the README points to `lua/hardtime/config.lua` for the full list of `resetting_keys`, so a minor release could change a default you have come to depend on. The repository ships a CHANGELOG.md and a busted test suite under `spec/` with a `.busted` config, which means the project has tests you can run, though the README does not document how to run them. The practical upgrade check is to diff your `opts` table against the option table after each release.
What to check before adding it to your config
Three things decide whether hardtime.nvim sticks. First, your Neovim version: the requirement is v0.10.0 or newer, and there is no fallback documented for older versions. Second, your hint display: decide up front whether you will set `'showmode'` to false with the mode on a statusline, raise `'cmdheight'` to 2, or use nvim-notify, because without one of those the hint is unreliable in insert and visual mode. Third, your mouse usage, since `disable_mouse` is `true` by default.
If all three are fine, the smallest useful configuration is to leave the defaults and run `:Hardtime report` after a day of editing. The log at `~/.local/state/nvim/hardtime.nvim.log` is the raw input for that decision. The plugin is small, the licence is permissive, and the last push was on 2026-09-13, so the cost of trying it and removing it is a single entry in your plugin list.
Editorial conclusion
Adopt hardtime.nvim if you type hjkl and arrow keys out of muscle memory and want the editor to stop you mid-habit. Skip it if you rely on the mouse, on arrow keys in a terminal without a statusline, or on long scroll sessions, because disable_mouse defaults to true and the hint message can be overwritten by the mode message. Before you commit, check your Neovim version against the v0.10.0 requirement, decide whether you can set 'showmode' to false or raise 'cmdheight' to 2, and confirm that the nui.nvim dependency is acceptable in your plugin set.
Frequently asked questions
What is hardtime.nvim and what does it do?
It is a Neovim plugin that blocks repeated key presses within a short time window and shows a hint for a faster Vim motion instead. It also reports your most common bad habits with :Hardtime report.
How do I install hardtime.nvim?
The README shows installation through a package manager, with lazy.nvim as the example, listing m4xshen/hardtime.nvim with lazy = false and a dependency on MunifTanjim/nui.nvim. With lazy.nvim, setting opts is enough; otherwise the README says to call require("hardtime").setup() in init.lua.
Which Neovim version does hardtime.nvim require?
The requirements section lists Neovim v0.10.0 or newer. The repository does not document a fallback for older versions.
How do I turn hardtime.nvim off temporarily?
The README gives three state commands: :Hardtime enable, :Hardtime disable and :Hardtime toggle. The enabled option sets whether the plugin starts enabled, and it defaults to true.
Why is the hint message not showing in insert or visual mode?
The README states that 'showmode' must be false for hint messages to appear in insert and visual mode. If you want to see both, it suggests showing the mode on a statusline, setting 'cmdheight' to 2, or using nvim-notify for hints in the top right corner.
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/m4xshen-hardtime-nvim)