debugprint.nvim treats print statements as a first class debugging mode
Debugging in NeoVim the print() way!
At a glance
- What is it?
- debugprint is a Neovim plugin for people who debug by inserting print statements rather than by stepping through a debugger, with forty supported languages, Treesitter-aware variable detection, keymappings in normal, insert, visual and operator-pending modes, and commands to find, comment out and delete the lines it inserted. It requires Neovim 0.11 or newer and is MIT licensed.
- Who is it for?
- Adopt debugprint.nvim if you debug by adding print statements and want that to be a mode rather than a chore, since the per-language print syntax, the register insertion and the cleanup commands are what it automates. Do not adopt it as a replacement for a step debugger, since it deliberately does not set breakpoints or inspect frames.
- 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 111 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 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A low-tech debugging workflow, taken seriously
debugprint is a NeoVim plugin that simplifies debugging for those who prefer a low-tech approach, and the plugin links a blog post arguing that printf debugging is fine.
The premise is that instead of using a sophisticated debugger such as nvim-dap, some people prefer a print-like statement to trace the output during execution. With debugprint you can insert those statements, including the values of variables, relevant to the language you are editing.
That is a small idea, and the reason it needs a plugin is that doing it by hand is tedious in a specific way. A print statement in a language other than Python looks different, and the value you want printed is often a variable that you have to find first. The plugin automates the syntax per language and the value lookup, and it remembers where the lines it inserted are.
The plugin is inspired by vim-debugstring, updated for the Neovim generation. The primary language is Lua, the licence is MIT, the last push was on 2026-07-04, and the releases are v7.1.1 from 2026-03-29, v7.1.0 from 2026-02-12 and v7.0.0 from 2025-12-14. The maintainer asks you to subscribe to a GitHub issue to be notified of any breaking changes, which is a sensible request for a plugin that has already shipped breaking changes.
Forty languages, and the value under the cursor
The feature list is specific about what is supported and what the plugin does with the code around you.
It supports 40 filetypes and programming languages out of the box, including Python, JavaScript and TypeScript, Java and C or C++, and it can be extended to support other languages or customise existing ones through the configuration examples document linked from the readme.
The variable handling is the part that saves the most typing. The plugin can output the value of variables or simple expressions, and it will detect a variable name under the cursor for some languages using Treesitter, or it will prompt with a sensible default where it cannot. It also understands Treesitter embedded languages, with JavaScript in HTML given as the example, which matters because a variable in an inline script is not in the HTML file's own scope.
Each inserted print line carries reference information: file names, line numbers, a counter which persists between Neovim sessions, a timestamp which is not added by default, and snippets of other lines to make it easier to cross-reference them in the output. Each of those can be disabled globally or on a per-filetype basis.
So the design intent is that a print line should be self-identifying when you look at a log later. The counter surviving between sessions is the detail that matters most in practice, because it tells you the order the statements ran in without relying on the order of the log lines.
The keymaps, and the ones you can remap
By default the plugin creates some keymappings and commands for use out of the box, and there is further functionality which is not mapped to any keymappings by default but could be.
The default mappings cover the modes a debug statement gets inserted in: normal, insert, visual and operator-pending. So the plugin works whether you are editing a line, selecting a range, or in the middle of a pending operator, which is what makes it usable rather than a curiosity.
The table starts with the normal mode entries. A plain debug goes below the line with g?p, and a plain debug above the line with g?P, and a variable debug with g?v. The table records whether the insertion goes above or below the line for each mapping, which is a small detail that matters when you are inserting a print before the statement that produces the value.
The plugin also supports dot-repeat, so a repeated insertion repeats the last one, and it can insert two surrounding lines at the same time, which is the pattern of a print before and a print after. It supports direct writing to Neovim registers for batch insertion of debugprint lines, so you can build up a block of statements from a register.
And it can optionally move to the inserted line, or not, which is a preference worth thinking about: staying in place is faster when you are inserting several in a row, and jumping to the line is faster when you want to run the code.
Finding, commenting and deleting the lines you added
The cleanup side of a print-based workflow is as important as the insertion side, and the plugin has more commands here than you would expect.
There are commands to delete or comment debugging lines added to the current buffer, to move between debugging lines with [g-style keybindings, to search for those lines in the current directory or project, and to add those lines to the quickfix list.
The search command is where the plugin leans on other tools, and it supports three of them: fzf-lua, telescope.nvim and snacks.nvim. So you use the picker you already have rather than the plugin bringing its own.
The quickfix integration is the piece that makes this a debugging tool rather than a text manipulation tool. Once the lines are in the quickfix list, you can move between them the way you move between compiler errors, and jump to the source of a stack trace or a log line that names one of them.
Commenting rather than deleting is the other useful mode, because it lets you keep a statement in place while silencing it, which is the difference between a debug session that takes minutes and one that takes an afternoon of re-typing.
Installation, and the dependencies that are actually optional
The requirement is Neovim 0.11 or newer, and the example configuration is for lazy.nvim:
return {
"andrewferrier/debugprint.nvim",
-- opts = { ... },
dependencies = {
"nvim-mini/mini.nvim", -- Optional: Needed for line highlighting (full mini.nvim plugin)
-- ... or ...
"nvim-mini/mini.hipatterns", -- Optional: Needed for line highlighting ('fine-grained' hipatterns plugin)
"ibhagwan/fzf-lua", -- Optional: If you want to use the `:Debugprint search` command with fzf-lua
"nvim-telescope/telescope.nvim", -- Optional: If you want to use the `:Debugprint search` command with telescope.nvim
"folke/snacks.nvim", -- Optional: If you want to use the `:Debugprint search` command with snacks.nvim
},
lazy = false, -- Required to make line highlighting work before debugprint is first used
version = "*", -- Remove if you DON'T want to use the stable version
}Every dependency in that list is marked optional in the comment next to it, and the comments say what each one buys: mini.nvim or mini.hipatterns for line highlighting, and one of the three pickers if you want the search command.
Two lines in there are not optional in the usual sense. lazy = false is marked as required, with the explanation that it is needed to make line highlighting work before debugprint is first used, which makes sense if the highlighting depends on a pattern that is registered when the plugin loads. And version = "*" is there to track the stable version, with a note to remove it if you do not want that.
Examples for other package managers, along with example and advanced configurations, are in the configuration examples document linked from the readme that can be dropped into your own configuration files.
How the project is built and tested
The repository layout shows a plugin with a real test setup rather than a script and a hope.
There is a lua directory with the implementation, a queries directory for the Treesitter queries, a tests directory, a doc directory, a demo directory, a lazy.lua file, and configuration files for the tools the project uses on itself: a .luacheckrc and a .luarc.jsonc for Lua linting and language server settings, a selene.toml for the Selene linter, a .stylua.toml for formatting, a .markdownlintrc for the documentation, and a .pre-commit-config.yaml that runs the checks before a commit.
The Makefile is one target, and the test target runs the suite in a headless Neovim:
test:
nvim --headless --clean -u tests/run.luaThat is the detail worth pausing on. A plugin that manipulates buffers, registers keymaps and depends on Treesitter cannot be tested by a plain unit test framework in a language other than Lua, because the behaviour under test is the behaviour of an editor. Running the suite inside a headless Neovim with a clean configuration means the tests exercise the plugin the way it actually runs, in the environment it actually runs in.
The demo directory has a script and a Python file, which are probably there to give a manual tester something to reproduce a real session against, and the vim.toml file at the root is the standard location for the plugin's runtime metadata.
Editorial conclusion
Adopt debugprint.nvim if you debug by adding print statements and want that to be a mode rather than a chore, since the per-language print syntax, the register insertion and the cleanup commands are what it automates. Do not adopt it as a replacement for a step debugger, since it deliberately does not set breakpoints or inspect frames. Before you install, check three things: that your Neovim is 0.11 or newer, whether you want the optional mini.nvim or mini.hipatterns dependency for line highlighting, and that you read the upgrade notes, since the maintainer asks subscribers to the breaking changes issue to be notified in advance.
Frequently asked questions
What does debugprint.nvim do?
It is a Neovim plugin for debugging by inserting print-style statements, including the values of variables, with the syntax appropriate to the language you are editing. It supports 40 filetypes and languages out of the box, and it is inspired by vim-debugstring, updated for the Neovim generation.
Which Neovim version does debugprint.nvim require?
Neovim 0.11 or newer. The plugin is MIT licensed, written in Lua, and the last push was on 2026-07-04 with v7.1.1 released on 2026-03-29.
How do I install debugprint.nvim with lazy.nvim?
Add the plugin with lazy = false, which the documentation marks as required so line highlighting works before the plugin is first used. The dependencies on mini.nvim or mini.hipatterns, and on fzf-lua, telescope.nvim or snacks.nvim, are all optional and each is needed for a specific feature.
How do I find and clean up the debug lines debugprint.nvim inserted?
The plugin provides commands to delete or comment debugging lines in the current buffer, to move between them with [g-style keybindings, to search for them in the current directory using fzf-lua, telescope.nvim or snacks.nvim, and to add them to the quickfix list.
How does debugprint.nvim find the value to print?
For some languages it detects a variable name under the cursor using Treesitter, and otherwise it prompts with a sensible default. It also understands Treesitter embedded languages, such as JavaScript inside HTML, and each inserted line can carry a file name, line number, a persistent counter, an optional timestamp and snippets of neighbouring lines.
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/andrewferrier-debugprint-nvim)Was this useful?