Running Jupyter Notebooks from NeoVim on macOS β A Guide to Jupynium
π§ Why Jupynium?
If youβre a quant, you probably live in Jupyter notebooks for quick modeling β but also love the editing experience and keybindings of NeoVim.
The problem: VS Code handles .ipynb files, but itβs heavy and mouse-driven.
Jupynium.nvim fixes this gap.
It connects NeoVim to a live Jupyter Notebook (classic) session through Firefox automation.
You can type in NeoVim, run cells, and watch outputs β plots, widgets, DataFrames β appear instantly in your browser.
Everything stays synced to the real .ipynb, so you never lose cell outputs or run history.
βοΈ Step 1 β System Setup on macOS
# 1. Browser automation tools
brew install --cask firefox
brew install geckodriver
# 2. Jupyter classic (nbclassic is required)
conda install -n base -c conda-forge notebook nbclassic jupyter-console
# 3. Optional: register your project kernel
conda activate myenv
python -m ipykernel install --user --name myenv --display-name "Python (myenv)"
Why Firefox?
Jupynium uses Selenium WebDriver to control a browser. Only Firefox is fully supported via geckodriver β a small executable that listens for automation commands and controls the Firefox UI. Safari and Chrome wonβt work (their drivers lack required APIs).
β‘ Step 2 β Install Plugins (Lazy.nvim Example)
Create lua/plugins/jupynium.lua:
return {
{
"kiyoon/jupynium.nvim",
build = "pip3 install --user .",
dependencies = {
"rcarriga/nvim-notify",
"stevearc/dressing.nvim",
},
config = function()
local env = vim.env
local py = (env.CONDA_PREFIX and ("conda run -p " .. env.CONDA_PREFIX .. " python3")) or "python3"
require("jupynium").setup({
default_notebook_URL = "localhost:8888/nbclassic",
python_host = py,
auto_download_ipynb = true,
use_default_keybindings = false,
})
local map = vim.keymap.set
map("n", "<leader>js", ":JupyniumStartAndAttachToServer<CR>", { desc = "Start server" })
map("n", "<leader>jj", ":JupyniumStartSync<CR>", { desc = "Start sync to Notebook" })
map("n", "<leader>jk", ":JupyniumKernelSelect<CR>", { desc = "Select kernel" })
map("n", "<leader>jn", ":JupyniumRunSelectedCells<CR>", { desc = "Run selected cell(s)" })
map("n", "<leader>jr", ":JupyniumKernelRestart<CR>", { desc = "Restart kernel" })
map("n", "<leader>jo", ":JupyniumScrollToCell<CR>", { desc = "Scroll to cell" })
end,
},
}
π§© Step 3 β Daily Workflow
- Activate your environment
conda activate myenv nvim analysis.ju.py - Start Jupynium inside NeoVim
<leader>js β start Jupyter server <leader>jj β open Firefox + attach notebook <leader>jk β select kernel - Edit and run cells
- Mark code cells with
# %%. - Run the current or selected cell via
<leader>jn. - Outputs and plots appear in the Firefox tab.
- Mark code cells with
- Save
- Jupynium automatically writes an updated
.ipynbnext to your file. - All execution history and widgets are preserved.
- Jupynium automatically writes an updated
π§ Environment Control
- The controller (Jupynium + Jupyter Notebook) can live in your base environment.
- The execution kernel (your code) runs in whatever conda env you choose via
Kernel β Change Kernelor:JupyniumKernelSelect. - This separation keeps your system clean: base env handles infrastructure, each project env handles packages.
π§© Under the Hood
NeoVim (Jupynium)
β WebDriver API
geckodriver
β
Firefox (Jupyter Notebook classic)
β
IPython kernel (your conda env)
Every edit in NeoVim is sent via Selenium commands to Firefox, which updates the real notebook DOM.
Thatβs why outputs, execution counts, and widget states remain intact β youβre literally editing the real notebook.
π‘ Pro Tips
- Keep
geckodriveron your$PATH:
which geckodriverβ/usr/local/bin/geckodriver - Donβt type simultaneously in the browser and Neovim β itβs one-way sync (NeoVim β browser).
- Use
auto_download_ipynb=trueso every save keeps your.ipynbup-to-date. - Combine with
Jupytextif you want text-based diffs for code review (--sync, not--to ipynb).
π Why This Rocks for Quants
- Reproducibility:
.ipynbstays the single source of truth (outputs + metadata). - Speed: pure keyboard workflow, no mouse-dragging cells.
- Flexibility: run LightGBM, regression models, or backtests interactively while keeping Vim motions.
- Portability: notebooks still open normally in Jupyter, VS Code, or nbviewer.
π Closing Thoughts
Jupynium brings back the productivity of Vim without giving up notebook interactivity.
On macOS with conda, itβs now stable enough for daily quant research β from feature engineering to model debugging β all without leaving your terminal.
Written by Yanzhong (Eric) Huang
BagelQuant.com β Quantitative Research | Code | Coffee