jupynium.nvim: a Jupyter Notebook live preview inside Neovim
Selenium-automated Jupyter Notebook that is synchronised with Neovim in real-time.
At a glance
- What is it?
- Jupynium drives a real Jupyter Notebook in Firefox with Selenium and mirrors your Neovim buffer into it, so editing a notebook looks like editing a text file while the browser renders the result. It deliberately talks to the Notebook front end rather than the kernel, which is what lets it work with remote and university-hosted notebooks and with other kernels such as R, and it is a one-way sync that only Firefox supports.
- Who is it for?
- Adopt jupynium.nvim if you edit notebooks as source in Neovim and want the browser preview without leaving the editor, especially if your kernel or notebook server lives somewhere else, since the front-end-only approach makes that work. Do not adopt it if you need to edit in the browser and have the changes come back, because the README states the sync does not go from Notebook to Neovim, or if you are on Chrome or Safari, since only Firefox is supported.
- 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 36 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A notebook preview that behaves like a markdown preview
The README's pitch is a comparison you can check: it is just like a markdown live preview, but it is Jupyter Notebook live preview.
The mechanics are stated plainly. Jupynium uses Selenium to automate Jupyter Notebook, synchronising everything you type on Neovim, and the instruction is to never leave Neovim, switching tabs on the browser as you switch files on Neovim.
So the workflow is a split screen in spirit and one application in practice. You keep the notebook cell source in a Neovim buffer with all your editing tooling, and a browser tab shows the executed notebook as you work. When you edit a cell and save, the browser updates.
The direction of the sync is the first thing to understand, and the README is direct about it: it does not sync from Notebook to Neovim, so you should only modify from Neovim. The browser is a viewer of your buffer, not a second editor. Anyone who tries to fix a cell in the browser and then switches back to Neovim will find their change gone, and the documentation says so before you hit it.
The audience is people who already live in Neovim and who find the browser notebook interface to be the wrong tool for writing code, but who still want to see results. It is a plugin written in Python and Lua, on the MIT licence, with the last push on 2026-09-20 and releases v0.2.8 from that date, v0.2.7 from 2025-11-14 and v0.2.6 from 2025-02-18.
The server, the buffer copy and the Selenium session
The How does it work section gives the architecture in three steps. The Jupynium server receives events from Neovim, keeps a copy of the buffer, and applies that to the Jupyter Notebook using Selenium browser automation.
That middle step, keeping a copy of the buffer, is what makes the tool usable. The plugin does not send a diff on every keystroke and hope the browser keeps up. It maintains server-side state that mirrors the buffer, and the browser session is driven against that state. When a file is switched, the plugin has something coherent to synchronise the notebook to rather than a stream of partial edits.
The Selenium part is what makes this unusual. The Jupynium server opens a real Firefox window and drives the Jupyter Notebook interface as a user would, typing into cells and running them. The alternative would have been to talk to the kernel directly, but the README explains that it interacts only through the front end so it does not require installing extensions on the kernel.
That constraint is the source of the tool's reach. Because nothing is installed on the kernel, it becomes possible to develop locally and run remotely or the other way round, to use a university-hosted Jupyter Notebook, and to use any other languages or kernels such as R.
Those three consequences are worth separating, because they are different kinds of value. The first is a workflow convenience. The second removes an installation barrier entirely: a shared lab server that already runs notebooks needs no changes to become editable from your editor. The third is the strongest, since supporting a kernel means driving the standard web interface rather than implementing per-language integration.
Firefox only, and geckodriver has to match
The requirements section is where this project is most constrained, and the first constraint is the browser.
The plugin requires Firefox, and the README is explicit that other browsers are not supported due to their limitation with Selenium, with a link to issue 49 and a comment explaining the details. That is a hard boundary rather than a preference, and it means a Neovim user on Chrome or Safari is out of luck unless they install Firefox alongside.
Mozilla geckodriver is the other half of that requirement, and it may already be installed with Firefox, which the README suggests you check with geckodriver -V. The driver is the bridge between Selenium and the browser, and a mismatch between the geckodriver version and the Firefox version is a classic source of failures here.
Beyond that, the environment needs Neovim 0.8 or newer, Python 3.9 or newer and Jupyter Notebook 6.2 or newer. Jupyter Lab is not supported at all, which is a separate and larger constraint than the browser one, since some teams have standardised on Lab rather than the classic Notebook server.
The operating system list is generous: Linux, macOS and Windows, with CMD, PowerShell and WSL2 all named. So the plugin is not limited by the platform, only by the browser and the notebook server flavour.
Notebook 7 is not supported, and nbclassic is the way in
There is a section with an exclamation in the heading, and it is the single most important practical detail for anyone installing this today.
Jupynium does not support Notebook 7 yet. The workaround given is to change the default_notebook_URL = "localhost:8888/nbclassic" setting in the setup call to use the classic Notebook 6 interface, and the README states that this is the new default setting from now on. You also need to upgrade your notebook and install nbclassic, with the command given as pip install --upgrade notebook nbclassic.
The optional piece is jupyter-console, which is used for the :JupyniumKernelOpenInTerminal command. The install line groups them:
pip install notebook nbclassic jupyter-consoleSo the practical setup is that you keep a Notebook 6 interface available through nbclassic and point the plugin at it. The reason for the incompatibility is implicit in the design: the plugin drives the classic Notebook interface with Selenium, and a rewritten front end in Notebook 7 breaks the selectors and the structure the automation relies on.
That is worth stating plainly for an evaluation. A project that automates a user interface is coupled to that interface, and the coupling surfaces exactly here, as a version wall that requires a compatibility package rather than a code change on your side.
Installing the Python side and the plugin
There are two installations, a Python environment for the server side and a plugin manager entry for the Neovim side, and the plugin entry can install the Python package for you.
The Python environment can be uv, which downloads Python and creates a virtual environment:
# This downloads python 3.13 if it doesn't exist.
uv venv ~/.virtualenvs/jupynium --python=3.13or Conda:
conda create -n jupynium python=3or the system Python, in which case the README advises upgrading pip, noting that pip 23.0 or newer is recommended and that this solves many problems:
# pip >= 23.0 recommended
pip3 install --upgrade pipThe plugin side is installed with any of the usual managers. The README shows vim-plug, packer.nvim and lazy.nvim variants, each with a build step that installs the Python package into the environment you chose, including commented alternatives for uv and Conda. The lazy.nvim form looks like this:
{
"kiyoon/jupynium.nvim",
build = "pip3 install --user .",
-- build = "uv pip install . --python=$HOME/.virtualenvs/jupynium/bin/python",
-- build = "conda run --no-capture-output -n jupynium pip install .",
},
"rcarriga/nvim-notify", -- optional
"stevearc/dressing.nvim", -- optional, UI for :JupyniumKernelSelectTwo optional plugins appear alongside. nvim-notify is for notifications and dressing.nvim provides a user interface for the kernel selection command, so the plugin can work without either but looks better with them.
The package manifest adds a detail to the Python side. The project installs two console scripts, jupynium itself and ipynb2jupytext, which is a converter for moving between notebook format and a plain text representation. Having that as a shipped command rather than a documented snippet means it can be used in scripts.
The settings that decide where things run
The setup defaults are documented in full, and reading them tells you how the tool is wired.
The first is python_host, which defaults to vim.g.python3_host_prog or python3 and decides which interpreter runs the server side. The comment notes that a Conda user needs to change it to execute using the conda command instead, giving the array form {"conda", "run", "--no-capture-output", "-n", "jupynium", "python"}. This is the setting that decides whether the plugin talks to the same Python that has your notebook stack installed.
The second is default_notebook_URL, which as discussed points at the nbclassic path. The third is jupyter_command, a jupyter executable that Jupynium will use to open a server for you when you call :JupyniumStartAndAttachToServer and no notebook is open, which only applies when the notebook URL is on localhost. There is a commented Conda variant of that command too.
The fourth is notebook_dir. The comment explains that it is used when the notebook is launched by jupyter_command, and that if it is nil or empty the notebook opens at the git directory of the current buffer while still navigating to the buffer's directory. That is a neat detail: the server root follows your repository, but the notebook you land on follows the file you were editing.
The last two are about the browser rather than the server. firefox_profiles_ini_path points at the Firefox profiles.ini used to remember the last session, with the example paths given for a standard install and a snap install, and firefox_profile_name selects which profile to use, where nil means the profile marked Default=1.
The pattern across all of these is that the plugin tries to be invisible. It picks the interpreter you already configured, it follows your working directory, and it reuses the browser session you already have, so the only thing you are asked to change is the notebook URL.
Packaging, tests and where the approach strains
The repository is a hybrid project and the packaging reflects that. The top level holds lua/ for the Neovim plugin, src/ for the Python package, after/ for the files that run after installation, plugin/, deps/, scripts/, docs/ and tests/, along with a .stylua.toml for the Lua formatting.
The Python side builds with hatchling, and the version is produced by a tool called version-pioneer, which reads the version from src/jupynium/_version.py and writes it back into the source and wheel files. Dependencies are not written by hand: the build reads deps/requirements.in through the hatch-requirements-txt hook, and there is a separate dev requirements file. That is a sensible arrangement for a project whose Python dependencies differ between the runtime and the test environment.
The continuous integration badges tell you what is checked on every push: Ruff for linting, StyLua for Lua formatting, pytest for tests, and a uv workflow that checks that the pip compile output stays in sync with the input requirements. The Python floor is 3.9, and the classifiers list 3.9 through 3.14.
The limitation to keep in view is the one the design creates. Driving a browser means the plugin depends on the structure of the Notebook interface, which is why Notebook 7 is a wall and why the project still sits at version 0.2.x. Any release of Notebook that changes the DOM can break the automation, and the fix will always be to update the selectors. The alternative approach is to edit the notebook file itself, as a JSON or in a plain text format such as the one the ipynb2jupytext command works with, and that path has no browser in it at all. Jupynium buys you execution and the rendered output, and it charges for that in coupling to the front end.
Editorial conclusion
Adopt jupynium.nvim if you edit notebooks as source in Neovim and want the browser preview without leaving the editor, especially if your kernel or notebook server lives somewhere else, since the front-end-only approach makes that work. Do not adopt it if you need to edit in the browser and have the changes come back, because the README states the sync does not go from Notebook to Neovim, or if you are on Chrome or Safari, since only Firefox is supported. Before you start, install nbclassic and set default_notebook_URL to the nbclassic path, because Notebook 7 is not supported, and check the geckodriver version, since the browser automation is the layer that fails first when something changes.
Frequently asked questions
What does jupynium.nvim do?
It uses Selenium to automate Jupyter Notebook and synchronises everything you type in a Neovim buffer into it, so you edit notebook cells in Neovim while a browser shows the executed result. It interacts only through the notebook front end, so no extensions are installed on the kernel.
Which browsers does jupynium.nvim support?
Only Firefox. The README states that other browsers are not supported because of their limitation with Selenium, and you also need Mozilla geckodriver, which may already be installed with Firefox and can be checked with geckodriver -V.
Does jupynium.nvim work with Jupyter Notebook 7?
Not yet. The README says Jupynium does not support Notebook 7, and the workaround is to set default_notebook_URL to "localhost:8888/nbclassic" in the setup call and to install nbclassic with pip install --upgrade notebook nbclassic.
Does editing in the browser update the Neovim buffer?
No. The README notes that it does not sync from Notebook to Neovim, so you should only modify from Neovim. The browser tab is a viewer of your buffer rather than a second editor.
How do I install jupynium.nvim with lazy.nvim?
Add the plugin entry with a build step that installs the Python package, for example build = "pip3 install --user .", with commented alternatives for uv and Conda, and optionally add nvim-notify and dressing.nvim for notifications and the kernel selection interface. The Python side needs Python 3.9 or newer, and the README advises upgrading pip.
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/kiyoon-jupynium-nvim)Was this useful?