Open-source project
jupyter-widgets/ipywidgets avatar
jupyter-widgets/ipywidgets

ipywidgets: the two-language contract behind Jupyter's interactive controls

Interactive Widgets for the Jupyter Notebook

3,335 stars974 forksTypeScriptBSD-3-Clause

At a glance

What is it?
A slider in a notebook cell is not a browser widget. ipywidgets is the Python and TypeScript pairing that makes it work, and the packaging around it is the interesting part.
Who is it for?
ipywidgets is best understood as a protocol plus a build system rather than a widget gallery. The core controls are the thin part, useful because they prove the channel; the real leverage is the cookiecutter template and the comm protocol that bqplot, ipyleaflet and pythreejs all build on.
Can I use it commercially?
Yes. BSD-3-Clause 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 49 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Core widgets are the smallest useful part of the library

The README positions the project as interactive HTML widgets for Jupyter notebooks and the IPython kernel, and it lists what it ships as the fundamental set: sliders, progress bars, text boxes, toggle buttons, checkboxes and display areas. The framing the project uses is that notebooks come alive, that users gain control of their data, and that a researcher can see how changing an input moves the output. That is an accurate description of what a slider wired to a plot does, and it is worth noticing that the value proposition is about the feedback loop, not about rendering.

The demonstration notebook at `docs/source/examples/Index.ipynb` is linked as the overview. The `examples/` directory in the tree holds five separate subprojects named `embed-amd`, `web1`, `web2`, `web3` and `web4`, which suggests the frontend has been exercised against several embedding targets over time rather than only against the current JupyterLab shell.

None of these controls would be hard to draw. The hard part is the part described next.

Installing is one line, and it is misleading about the work

The stable package installs through either of the two standard channels:

sh
pip install ipywidgets
sh
conda install -c conda-forge ipywidgets

What you get from that is a Python package plus a frontend extension that JupyterLab discovers. The README keeps the two badge rows separate for a reason: the `main` row is labelled future 8.0 and points at a Binder image built from `main`, while the Stable row tracks the published PyPI and conda-forge versions. Release 8.1.9 shipped on 2026-08-18, one day before the last push recorded on 2026-08-19, so the stable line and the trunk line are close but not identical.

Release 8.1.9 also drops JupyterLab 3 support, which is the kind of change that matters more than a bug fix. The same set of notes upgrades the build to TypeScript 6 and moves docs onto JupyterLite 0.8.x. Dropping a whole major version of the host application is what eventually makes it possible to keep the frontend on a current TypeScript.

A monorepo that publishes Python and npm packages from one tree

The repository root is a Yarn workspace with Lerna driving the packages, and the workspace list in `package.json` names the four globs that matter:

json
"workspaces": [
    "packages/*",
    "python/widgetsnbextension",
    "examples/*",
    "python/jupyterlab_widgets"
]

That is the whole architecture in four lines. `packages/*` holds the TypeScript implementations that get bundled into the frontend. `python/widgetsnbextension` is the classic notebook extension. `python/jupyterlab_widgets` is the JupyterLab 4 extension. `examples/*` are consumers of the published packages rather than part of the library, which is why the build script excludes them:

json
"build": "lerna run build --stream --ignore \"@jupyter-widgets/example-*\""

The scripts section is a good map of the release mechanics. `yarn build` builds libraries while ignoring examples, `yarn build:examples` does the reverse with `--include-filtered-dependencies`, and `yarn build:labextension` exists as a separate target because the Lab extension bundle is produced differently from a notebook extension bundle. There is also `yarn integrity`, which runs `node scripts/package-integrity.js`, and a pinned TypeScript resolution of `~6.0.3` in `resolutions` so that every workspace agrees on the compiler version. A dependency on one Lerna version across two languages is exactly the failure mode that pin exists to prevent.

Writing your own widget means shipping two packages in step

The README points custom widget authors at a cookiecutter template in `jupyter-widgets/widget-ts-cookiecutter`, and the pitch is that it produces a project following current best practices with a working Hello World widget as the example. The README then names three libraries that follow the same template and directory structure: `bqplot` for 2D data visualisation with custom interaction, `pythreejs` as a Three.js wrapper for the notebook, and `ipyleaflet` as a Leaflet map widget.

Those three are the proof that the template is not aspirational. They are also the reason to read ipywidgets rather than to treat it as a dependency you never inspect: when a map and a 3D engine and a plotting library all line up through one contract, the contract is doing real work, and your library will be the fourth thing measured against it.

The cost side is what the README is honest about. It states that installing from source is more complicated, requires a developer install, and needs yarn version 3 or later from the root directory. For anyone building a custom library, the developer install page in `docs/source/dev_install.md` is the document that matters, because it is where the frontend and backend version negotiation gets explained.

Governance, licensing and what the repository shows

The project sits under the Jupyter-Widgets software subproject, which puts it inside Jupyter's governance process rather than leaving it as an unaffiliated library. It is BSD-3-Clause licensed and carries a `LICENSE` file at the repository root, along with `CODE_OF_CONDUCT.md` and `CONTRIBUTING.md`, the standard pair for a project in that position.

The repository is not archived, has 3,330 stars, and lists `jupyter-notebooks` and `jupyterlab-extension` as its topics. It is written primarily in TypeScript with a Python distribution alongside, which matches the tree: `packages/`, `tests/`, `ui-tests/` and `scripts/` on one side, `python/` on the other, plus `docs/`, `examples/` and a `.github/` directory for workflows.

Two supporting directories deserve a mention because they answer questions the README leaves open. `ui-tests/` indicates the frontend is exercised as a user interface rather than only at the module level, and `tsconfig.typedoc.json` alongside `typedoc.json` shows that API docs are generated from TypeScript sources, with `yarn docs` wired to `typedoc`. For a library whose consumers are spread across frontend and backend, generated API documentation from the same source of truth is a reasonable thing to depend on.

Where the README stops and the documentation begins

The README is an orientation page and it does its job: what the project is, what ships in core, how to install the stable build, and where the template and the example libraries live. Every operational question goes elsewhere. The widget API, the comm protocol and the frontend-backend version compatibility rules are on ipywidgets.readthedocs.io, which the badges link separately for latest and stable, matching the two branches the README itself distinguishes.

That split is the practical thing to know before choosing this route. If you want interactivity inside a notebook, `pip install ipywidgets` and the core widgets are enough, and the documentation site is where you go when you need a specific control's options. If you intend to publish a widget library, the README gets you a template and the docs get you the rest, and the repository itself, with its workspace layout and its separate build targets, is the best explanation of why a two-language package is harder to ship than a pure Python one.

Editorial conclusion

ipywidgets is best understood as a protocol plus a build system rather than a widget gallery. The core controls are the thin part, useful because they prove the channel; the real leverage is the cookiecutter template and the comm protocol that bqplot, ipyleaflet and pythreejs all build on. If you need one interactive control in an analysis notebook, installing the wheel and using a core widget takes minutes. If you are packaging a widget library for others, read the developer install page and the typedoc output in `packages/` first, because that is where the frontend and backend versions have to agree, and the README does not settle it.

Frequently asked questions

How to install ipywidgets in Python?

Through pip with `pip install ipywidgets`, or through conda-forge with `conda install -c conda-forge ipywidgets`. Both install the stable release. A source install is a separate path that needs a developer install and yarn 3 or newer.

What does IPython stand for?

IPython is the interactive Python shell that Jupyter's notebook kernels are built on, and it predates the notebook itself. ipywidgets targets that kernel interface, which is why the same widget can appear in a notebook, in the IPython terminal, or in another front end that speaks the same kernel protocol.

Can I build my own widget library on top of ipywidgets?

That is the main extension path. A cookiecutter template at `jupyter-widgets/widget-ts-cookiecutter` produces a project with a working Hello World widget following the current layout, and bqplot, pythreejs and ipyleaflet all use the same structure.

Why did ipywidgets drop support for JupyterLab 3?

Release 8.1.9 removed JupyterLab 3 support, and the same release moved the build to Jupyter Builder and upgraded to TypeScript 6. Dropping an older host major is what frees the frontend to track current tooling.

Does ipywidgets work outside JupyterLab?

The README describes the project as widgets for Jupyter notebooks and the IPython kernel, not for JupyterLab alone. The tree also keeps `python/widgetsnbextension` alongside `python/jupyterlab_widgets`, and the examples directory contains several `web` projects plus an `embed-amd` case, so embedding outside the standard shell is part of what gets built.

Official sources

  1. jupyter-widgets/ipywidgets on GitHub
  2. License: BSD-3-Clause
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jupyter-widgets-ipywidgets.svg)](https://hysenlabs.com/projects/jupyter-widgets-ipywidgets)