package-info.nvim: dependency versions and installs without leaving Neovim
✍️ All the npm/yarn/pnpm commands I don't want to type
At a glance
- What is it?
- package-info.nvim is a Neovim plugin that shows outdated dependency versions as virtual text next to your package.json entries and runs the install, upgrade and remove commands for npm, yarn, pnpm or bun in the background. It detects your package manager from the lock file, and it is still marked as beta with its last release in 2021.
- Who is it for?
- package-info.nvim suits a Neovim user who wants dependency state visible in the file and wants the common package manager operations bound to a key, because the detection walks up to the workspace root, which makes it work in a monorepo without configuration.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 52 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 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A plugin that runs the package manager for you
The description in the project notes is blunt about the intent: these are the npm, yarn, pnpm and bun commands the author does not want to type. The feature list is short. Latest dependency versions are displayed as virtual text, so the version you have and the version available sit next to each other in the buffer. A dependency on the current line can be upgraded to the latest version, deleted, or replaced with a different version, and new dependencies can be installed. The package manager is detected automatically, and there is a loading hook you can put in a status bar.
That is the whole product, and it is worth being clear about what it is not. It is not a dependency updater. It does not decide that a major version bump is safe, and it does not open a pull request. It puts four mutating operations one keystroke away from wherever you are in your package.json, which is exactly the trade: convenience in exchange for removing a deliberate step.
The plugin is written in Lua for Neovim, requires Neovim 0.9.0 or newer, and needs npm present on the machine. A patched font is required if you want the icons, and the yq tool is an optional extra needed for pnpm workspace support.
npm outdated in the background, cached for an hour
The version display works by running npm outdated with the json flag in the background, comparing the output with the versions in your package.json, and turning the differences into virtual text. There is a caching rule that catches people out: after the first outdated dependency fetch, the plugin shows the cached results for the next hour instead of re-fetching every time.
The reason for that is obvious once you think about the cost, since npm outdated is a network call to a registry and it is not fast, and a virtual text that flickers on every cursor move is worse than one that is slightly stale. The escape hatch is a second command, PackageInfoShowForce, which re-fetches every time it is called. The normal command is bound like this:
vim.keymap.set({ "n" }, "<leader>ns", "<cmd>PackageInfoShow<cr>", { silent = true, noremap = true })and the forcing variant differs only in the command name. The virtual text is styled by state, with a separate highlight for a dependency that is up to date, one that is outdated, and one that is invalid, so the visual signal is the colour as much as the version string.
The four mutating commands, and what they actually run
Three commands change your dependencies, and each one maps to a different invocation per package manager, which is the detail worth knowing.
Deleting a dependency runs yarn remove, npm uninstall, pnpm uninstall or bun remove, in the background, and then reloads the buffer. Installing a different version of the dependency on the current line runs npm install with the dependency and version, yarn upgrade with the same arguments, pnpm update with the dependency, or bun add with the dependency and version. Installing a new dependency runs npm install, yarn add, pnpm add or bun add, again followed by a buffer reload.
The commands are named for what they do: PackageInfoDelete, PackageInfoChangeVersion and PackageInfoInstall, each bound with the same keymap shape as the show command, for example:
vim.keymap.set({ "n" }, "<leader>nd", "<cmd>PackageInfoDelete<cr>", { silent = true, noremap = true })The buffer reload after each operation is what keeps the virtual text honest, since the file on disk has changed. The notifications are on by default and dismiss after a timeout, and that timeout is configurable.
Detection walks up to the workspace root
The package manager detection is the part that makes the plugin work in a monorepo, and the configuration comments explain it precisely. The plugin looks for yarn.lock, package-lock.json, bun.lock or pnpm-lock.yaml, starting in the directory of the package.json and walking up to the root of the repository, so a package inside a monorepo picks up the lock file of the workspace root rather than a local one that does not exist.
If no lock file is found anywhere on that walk, it falls back to the package manager provided in the configuration, and if nothing is provided there either, it uses npm. The configurable value can be npm, yarn, pnpm or bun, and it is used for the delete, install and change operations.
Two related settings control what you see rather than what you run. hide_up_to_date keeps the virtual text for dependencies that are already current out of the way, and hide_unstable_versions hides unstable versions from the version list, with the example given being a canary build. And autostart, on by default, means the plugin starts when a package.json is opened.
Configuration, and the 256 colour fallback
The plugin is configured by calling its setup function, and the defaults are all in one table:
require('package-info').setup()The highlights section is where most of the tuning happens, with one entry per state:
highlights = {
up_to_date = { -- highlight for up to date dependency virtual text
fg = "#3C4048"
},Icons can be disabled entirely, which matters if you have not installed a patched font. Notifications and the autostart behaviour are both switches, and the timeout controls how long a notification stays on screen.
There is a detail for terminals that do not do truecolor. If the vim option termguicolors is false, the plugin switches to 256 colour mode, where cterm colour numbers are used instead of hex codes, with the defaults given as 237 for up to date, 173 for outdated and 196 for invalid. The migration notice at the end of the documentation is also worth reading if you have an older configuration: the old colours table with plain hex strings is deprecated in favour of the highlights table with the fg key, and the change is one of shape rather than of value.
Status line integration for the loading state
The plugin exposes a status function that returns the current loading state, and it can be called from anywhere in Neovim with require of the plugin and a call to get_status. The documentation shows it wired into two status line plugins, one of them using a section of the left column and the other using a component in the right column with a highlight applied to it.
That is a small feature with a real purpose, since every mutating operation runs a package manager in the background and a package manager is slow enough that the user needs to know something is happening. The status is a string returned by the provider, and the surrounding status line configuration decides where it appears and how it is coloured.
Installation is a single plugin specification for packer, and the plugin needs the nui component library:
use({
"vuki656/package-info.nvim",
requires = "MunifTanjim/nui.nvim",
})Beta status and a release trail that stopped in 2021
The maintenance picture needs stating plainly. The published releases are version 1.0 in August 2021 and version 2.0 in September 2021, and the status badge in the project notes still says beta. The last push to the repository was on 2026-09-02, so work continues in the tree, but there has been no tagged release since 2021 and the plugin is not published with a version stream a user would expect.
For a plugin whose whole job is running commands in your project, that gap between the last release and the last commit is the thing to weigh. The code that runs npm and yarn for you is exactly the code you want to be able to read, and reading it is easier when the release you installed is the code you can find in a tag.
The repository is small and tidy. The source is in a lua directory, there is a doc directory for the help pages, the Makefile runs the test suite through headless Neovim with a minimal init file and the MiniTest runner, and the lint target checks formatting with stylua, runs luacheck, and checks the markdown files with prettier. There is a stylua configuration and a luacheck configuration at the root, plus a licence file, a claude instructions file, and a Makefile clean target that removes the test and temp directories.
Editorial conclusion
package-info.nvim suits a Neovim user who wants dependency state visible in the file and wants the common package manager operations bound to a key, because the detection walks up to the workspace root, which makes it work in a monorepo without configuration. It is the wrong choice for a team that wants a maintained dependency surface, since the last published release is 2.0 from September 2021 and the project still labels itself beta, even though the last push was on 2026-09-02. It is also the wrong choice if you cannot accept a plugin that runs a package manager on your behalf, since the mutating commands execute install, upgrade and remove operations without a confirmation step. Before you bind those keys, decide which of them you actually want, and remember that the outdated data is cached for an hour after the first fetch, so use the force variant when you need current numbers. The licence is GPL-3.0 and the plugin needs Neovim 0.9 or newer.
Frequently asked questions
How do I install package-info.nvim?
With packer, as a plugin specification naming vuki656/package-info.nvim with MunifTanjim/nui.nvim as a requirement, and then call require of the plugin and its setup function. The plugin needs Neovim 0.9.0 or newer and npm on the machine.
Which package managers does package-info.nvim support?
npm, yarn, pnpm and bun. The manager is detected automatically from yarn.lock, package-lock.json, bun.lock or pnpm-lock.yaml, starting in the package.json directory and walking up to the repository root, so a package in a monorepo picks up the workspace lock file, with npm as the final fallback.
How do I see which dependencies are outdated?
Run the PackageInfoShow command, which runs npm outdated with the json flag in the background and shows the differences with your package.json as virtual text. Results are cached for an hour after the first fetch, and PackageInfoShowForce re-fetches every time.
What does the plugin need besides Neovim?
npm on the machine, and a patched font if you want the icons. The yq tool is an optional requirement, needed for pnpm workspace support. The plugin also depends on the nui component library for its interface.
How do I show the plugin's loading status in my status line?
Call require of the plugin and get_status from your status line provider, as in the examples for Galaxyline and Feline in the documentation. The function returns the current loading status of the plugin.
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/vuki656-package-info-nvim)Was this useful?