LCM Logo
Data Science

Jupyter Kernels

Installing Jupyter, and registering, listing, and removing kernels — with the current best kernel for each major language

Jupyter separates the frontend (JupyterLab, Notebook, VS Code, Positron, jupyter console) from the kernel — the process that actually executes code. Any language with a kernel implementing the Jupyter messaging protocol works in any frontend. Kernels are registered via small JSON files called kernelspecs, which is what all the commands below manipulate.

Install Jupyter

JupyterLab is the current flagship frontend; the classic Notebook (v7+) is rebuilt on the same components. Neither install below requires you to manage a Python yourself.

On macOS (and Linuxbrew), the Homebrew formula ships JupyterLab with its own bundled, isolated Python:

shell
brew install jupyterlab

Cross-platform, uv installs it as an isolated tool (downloading a managed Python if none exists):

shell
uv tool install jupyterlab    # adds the `jupyter` and `jupyter-lab` commands
# or run without installing:
uvx jupyter lab

pip install -U jupyterlab notebook or conda install -c conda-forge jupyterlab work as well. Launch with jupyter lab (or jupyter notebook).

Either way, JupyterLab lives in its own isolated environment. It does not need to share an environment with your project code — that's what per-project kernels are for (next sections).

List available kernels

shell
jupyter kernelspec list          # names + kernelspec directories
jupyter kernelspec list --json   # full detail, machine-readable
jupyter --paths                  # all directories Jupyter searches

User-level kernelspecs live in ~/Library/Jupyter/kernels (macOS), ~/.local/share/jupyter/kernels (Linux), or %APPDATA%\jupyter\kernels (Windows). Each kernel is a directory containing a kernel.json with the launch command and display name — you can edit it directly to rename a kernel or add environment variables.

Remove a kernel

shell
jupyter kernelspec remove my-project        # prompts for confirmation
jupyter kernelspec remove -f my-project     # no prompt

This only deletes the kernelspec — the underlying environment or binary is untouched. Kernels pointing at deleted environments linger in the picker until removed this way.

Python: ipykernel, one kernel per environment

ipykernel is the reference Python kernel. The standard workflow is one kernel per project environment, so notebooks run against exactly the dependencies of that project:

shell
# In a uv project
uv add --dev ipykernel
uv run python -m ipykernel install --user \
    --name my-project --display-name "Python (my-project)"

# In any activated venv/conda env
python -m ipykernel install --user --name my-project --display-name "Python (my-project)"

--name is the kernelspec identifier (what kernelspec list and remove use); --display-name is what the notebook picker shows. Re-running the command with the same name overwrites the spec, so it's safe to repeat after moving an environment.

Alternatively, skip registration entirely and launch Jupyter inside the project environment — the default python3 kernel then is the project's interpreter:

shell
uv run --with jupyter jupyter lab

R: Ark or IRkernel

Ark is Posit's modern R kernel — a native frontend to R written in Rust, the same kernel that powers Positron, with an integrated debugger. Download a release binary, put it on your PATH, then:

shell
ark --install

IRkernel is the long-standing CRAN kernel, written in R itself — still the simplest install if you're already in R:

r
install.packages("IRkernel")
IRkernel::installspec()  # name = "ir", display name "R"
# Multiple R versions side by side:
IRkernel::installspec(name = "ir45", displayname = "R 4.5")

Julia: IJulia

IJulia registers a kernel automatically when the package is installed:

julia
using Pkg; Pkg.add("IJulia")

# Extra kernel variants, e.g. multithreaded or pinned to a project
using IJulia
installkernel("Julia (8 threads)", env = Dict("JULIA_NUM_THREADS" => "8"))
installkernel("Julia", "--project=@.")

JavaScript / TypeScript: Deno

The Deno runtime ships a built-in kernel — the modern choice for both JS and TS, replacing the older ijavascript/tslab kernels. It supports TypeScript natively, npm and JSR imports directly in cells, and rich output via Deno.jupyter helpers:

shell
deno jupyter --install
typescript
import * as Plot from "npm:@observablehq/plot";   // npm imports just work
Deno.jupyter.md`# Rendered **markdown** output`;

Deno kernel cells currently run with --allow-all — no Deno sandbox permissions apply inside notebooks.

Rust: evcxr

evcxr_jupyter is the canonical Rust kernel:

shell
cargo install --locked evcxr_jupyter
evcxr_jupyter --install

Add crates inside a notebook with the :dep directive:

rust
:dep rand = "0.9"
rand::random::<f64>()

Kernels at a glance

LanguageKernelInstallKernelspec name
Pythonipykernelpython -m ipykernel install --user --name <name><name>
RArkark --installark
RIRkernelIRkernel::installspec()ir
JuliaIJuliaPkg.add("IJulia")julia-1.x
JS / TSDenodeno jupyter --installdeno
Rustevcxrevcxr_jupyter --installrust

Any kernel also works outside notebooks in a terminal REPL:

shell
jupyter console --kernel deno

On this page