# ipykernel: the Python process behind every Jupyter cell

> ipykernel is the IPython kernel Jupyter starts to execute Python cells, and it is a source-first package with a pinned dependency stack, a hatchling build, and a pytest suite. It fits teams that want a predictable kernel runtime, and it will frustrate anyone hoping for a one line wheel install.

**ipython/ipykernel** — IPython Kernel for Jupyter

- Repository: https://github.com/ipython/ipykernel
- Website: https://ipykernel.readthedocs.io/en/stable/
- Stars: 733 · Forks: 412
- Language: Python
- License: BSD-3-Clause
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/ipython-ipykernel

## What ipykernel actually runs when you click Run

The project states its job in one sentence: "This package provides the IPython kernel for Jupyter." That means ipykernel is not a notebook editor, not a notebook file format, and not a web server. It is the Python side of the arrangement, the process that a Jupyter front end talks to when a user runs a cell.

The dependency list shows how that conversation is wired. jupyter_client>=8.9.0 and jupyter_core>=5.1,!=6.0.* appear in pyproject.toml as the protocol and core layers the kernel depends on, and pyzmq>=25 and tornado>=6.5.7 sit alongside them. ipython>=7.23.1 is also required, since the kernel is an IPython session rather than a bare interpreter.

The audience is stated in the project classifiers: Developers, System Administrators, and Science/Research. That fits the picture. A team that ships a notebook experience to internal users, a group that needs a Python runtime inside a data pipeline UI, or a platform engineer debugging kernel behaviour all land in the same place. A person typing at a terminal does not need this layer at all, and the README makes that distinction plain when it says that after installation all normal ipython commands will use the newly installed version of the kernel.

## A source install, not a wheel install, with pip 25.1 as the gate

The README gives exactly one installation route, and it is a development route. There is no pip install ipykernel line anywhere in the documentation. Instead you are told to clone the repository, change into the ipykernel directory, and run an editable install with the test dependency group attached:

`git clone`

`cd ipykernel`

`pip install -e . --group test`

The README adds a hard constraint on that last command: it needs pip 25.1 or later. On an older pip the dependency group syntax is not understood, so the documented path simply stops working. That is a real operational floor, not a formality, and it is the kind of detail worth checking before a build image is frozen.

The build backend is declared in pyproject.toml:

```toml
[build-system]
requires = ["hatchling>=1.22", "jupyter_client>=6"]
build-backend = "hatchling.build"
```

So building requires hatchling 1.22 or newer, and the build environment pulls in jupyter_client at version 6 or above even though the runtime dependency asks for 8.9.0 or above. The package version is dynamic, taken from the version hook path in pyproject.toml rather than written as a literal string.

## The dependency floor that decides whether the kernel starts

The project block in pyproject.toml carries the metadata that an adopter actually reads first:

```toml
[project]
name = "ipykernel"
dynamic = ["version"]
authors = [{name = "IPython Development Team", email = "ipython-dev@scipy.org"}]
license = "BSD-3-Clause"
readme = "README.md"
description = "IPython Kernel for Jupyter"
keywords = ["Interactive", "Interpreter", "Shell", "Web"]
classifiers = [
    "Intended Audience :: Developers",
    "Intended Audience :: System Administrators",
    "Intended Audience :: Science/Research",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3",
]
```

One line above that block, requires-python is set to >=3.11, and the classifiers list only Python 3. Any interpreter older than 3.11 is outside the supported range, and the absence of a Python 2 classifier confirms the package is not maintaining that compatibility.

The runtime dependencies are unusually specific for a kernel: debugpy>=1.6.5 for debugging, ipython>=7.23.1 for the session itself, comm>=0.1.1 and traitlets>=5.4.0 for configuration, jupyter_client>=8.9.0 and jupyter_core>=5.1,!=6.0.* for the protocol side, tornado>=6.5.7 and pyzmq>=25 for transport, matplotlib-inline>=0.1 for inline plotting, and packaging>=22. Two entries carry explicit platform logic. nest_asyncio2>=1.7.0 is annotated in the file as being for tk event loop support only, and appnope>=0.1.2 is gated on platform_system=="Darwin".

Those floors are the practical compatibility surface. A deployment that pins jupyter_client below 8.9.0, or jupyter_core to a 6.0.x release, cannot satisfy this package.

## The test suite you run with pytest from the repository root

Testing is a first-class activity in this repository rather than an afterthought. The README says to follow the source installation steps first, then run pytest from the root directory:

```bash
pytest
```

A coverage variant is documented in the same shape, with coverage flags and a duration report:

```bash
pytest -vv -s --cov ipykernel --cov-branch --cov-report term-missing:skip-covered --durations 10
```

The test dependency group in pyproject.toml backs this up with pytest>=7.0,<10, pytest-cov, flaky, ipyparallel, pre-commit, psutil>=5.7, pytest-asyncio>=0.23.5 and pytest-timeout. The pytest-xvfb entry is present but commented out and marked for platform_system == "Linux", so a headless display dependency is available to the Linux path but not enabled by default.

Two consequences follow. First, the suite is expected to run against async behaviour, since pytest-asyncio is a required test dependency rather than an optional extra. Second, the timeout plugin is in the group, which fits a package whose components involve event loops and network messaging.

For contributors, the repository also carries a .pre-commit-config.yaml at the top level, alongside CONTRIBUTING.md, RELEASE.md and CHANGELOG.md. The presence of a dedicated RELEASE.md tells you releases are a documented procedure rather than an ad hoc tag.

## The ipython terminal as the lighter alternative to the kernel path

The comparison that matters here is not against another vendor's kernel. It is between the plain ipython command and the kernel that Jupyter drives, because the README covers both and the difference is a design choice rather than a feature gap.

In terminal mode, a person talks to an IPython session directly and the process lifecycle is their own. In kernel mode, a separate client owns the session, requests execution over the Jupyter messaging layer, and can be on the other side of a network boundary. The kernel path therefore buys you remote execution, a session that outlives the person who started it, and a front end you do not control. It also costs you the dependency stack listed above, and it puts a protocol layer between your code and the interpreter.

The README notes that once the source install is in place, all normal ipython commands use the newly installed version of the kernel, so the two modes share the same underlying code rather than diverging into separate implementations.

For a data science team already living in notebooks, that extra layer is the entire point and nothing is wasted. For a team that only needs a Python shell on a server, installing a kernel package to get a REPL is a lot of machinery for the job.

## What the documentation leaves unanswered

The README is short, and its silences matter for an adopter. It does not document how to install the package from a published wheel or from PyPI, even though the build system is configured for it. It does not explain where kernel spec files are written, how a Jupyter server discovers this kernel, or how to register it under a custom name. It does not document a rollback procedure, a version compatibility matrix, or a troubleshooting path for a kernel that starts and then fails to execute.

The practical effect is that an adopter must read pyproject.toml, the docs directory and the examples directory to fill those gaps. The repository does contain an examples/embedding folder, and a top level ipykernel_launcher.py file, which are the natural places to look for how the kernel is launched as a process and how it is embedded in a host application. The documentation homepage is at ipykernel.readthedocs.io, so the long form guidance lives there rather than in the README.

There is also a version constraint that catches teams in the middle of a migration: pip 25.1 or later is needed for the documented install command, and requires-python is >=3.11. Neither is negotiable without changing the documented path.

## Release cadence and the BSD-3-Clause licence terms

The project is not archived, and the last push was on 2026-10-19. Three tagged releases sit in the recent history: v7.4.0 on 2026-09-29, v7.3.0 on 2026-06-10 and v7.2.0 on 2026-02-06. Those dates put a release roughly every two to four months across the observed window, which is a slow, deliberate rhythm for a package that sits underneath most notebook installs.

Licensing is BSD-3-Clause, declared both in the project metadata and in the LICENSE file at the repository root. The copyright model is collective rather than individual, and the README spells out the banner the project asks contributors to place in source files:

```
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
```

Each contributor keeps copyright over their own contributions, and the README notes that contributions are typically only changes to the repositories, so the source code as a whole is the collective copyright of the IPython Development Team. Contributors who want a record of specific contributions are asked to say so in the commit message of the change.

For an organisation choosing a kernel runtime, that means the permissive terms and the shared copyright model apply to the code you ship and modify. Review the LICENSE file yourself for the exact terms; no legal advice is offered here.

## Conclusion

Adopt ipykernel when you are running Python on behalf of someone else through a Jupyter client and want a dependency floor you can read in one file. Do not adopt it for a plain terminal session, where the ipython command already covers the work without the protocol layer. Before committing, check that requires-python >=3.11 fits your fleet, that your existing jupyter_client and jupyter_core pins sit above the 8.9.0 and 5.1 floors, and that pip 25.1 or later is available for the dependency group installs.

## FAQ

### How do I install ipykernel from source?

Clone the repository, change into the ipykernel directory and run pip install -e . --group test, which needs pip 25.1 or later. The README documents no other installation route, so there is no wheel or PyPI step in the documentation.

### What Python version does ipykernel require?

pyproject.toml sets requires-python to >=3.11, and the classifiers list only Python 3 with a Python :: 3 marker. The runtime dependencies also carry lower bounds, including jupyter_client>=8.9.0 and jupyter_core>=5.1,!=6.0.*.

### How do I run the ipykernel test suite?

Install the package from source with the test dependency group, then run pytest from the repository root. A coverage run is also documented, using pytest with the --cov ipykernel and --cov-branch flags and a term-missing report.

### What licence is ipykernel released under?

The package is licensed BSD-3-Clause, declared in pyproject.toml and in the LICENSE file at the repository root. The README describes a shared copyright model in which the IPython Development Team holds collective copyright over the source.

## Sources

- [ipython/ipykernel on GitHub](https://github.com/ipython/ipykernel)
- [License: BSD-3-Clause](https://github.com/ipython/ipykernel/blob/main/LICENSE)
- [Project website](https://ipykernel.readthedocs.io/en/stable/)
- [README](https://github.com/ipython/ipykernel/blob/main/README.md)
- [Releases](https://github.com/ipython/ipykernel/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ipython-ipykernel
