Open-source project
RoboStack/jupyter-ros avatar
RoboStack/jupyter-ros

jupyter-ros, bringing ROS topics into a Jupyter notebook

Jupyter widget helpers for ROS, the Robot Operating System

614 stars114 forksPythonBSD-3-Clause

At a glance

What is it?
jupyter-ros is a set of Jupyter widgets for the Robot Operating System, letting a notebook subscribe to topics, publish messages and animate a turtlesim without leaving the browser. It solves the Qt-versus-notebook tension in an unusual way, and its release line is old enough that you should read the version table before you install it.
Who is it for?
jupyter-ros suits a robotics developer or student who wants to explore ROS interactively in a notebook, subscribe to a live topic and plot it, or drive the turtlesim from a cell without writing a Qt node. It does not suit a production robotics stack, since the last release predates ROS 2 and the project has seen no push since 2026-04-02.
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?
Activity is slowing. The repository last received commits 6 months 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem is that ROS tooling is Qt tooling

jupyter-ros exists to bridge a specific gap, and the project states the gap plainly. The Jupyter ecosystem has been widely adopted by the Data Science and Machine Learning community, the robotics community has not jumped on the band wagon yet, and most tools around ROS, the Robot Operating System, are built using Python and QT.

That last fact is the whole problem. Using QT separates the user away from the code. A ROS developer working in a traditional setup writes a node, runs it, and inspects the output through a separate tool, a log window, a plotting application, a terminal running a subscriber.

The project's answer is a set of ROS tools for the Jupyter notebook, trying to promote a rich, interactive experience for robotics developers utilizing the power of the notebook. The headline capability is that with jupyter-ros it is possible to easily create widgets for custom message types to send messages, so a notebook cell can construct a message of a type defined in your own `.msg` files and publish it, rather than a node doing that on the side.

The audience is a robotics developer or a student, and the setting is exploration rather than deployment. A notebook that can talk to a live ROS graph is a good way to understand what a topic actually carries, to prototype a message type, or to teach.

The project is part of the RoboStack organisation, its documentation is hosted on readthedocs, and the licence is BSD-3-Clause with a shared copyright model that lets contributors keep copyright on their contributions. The last push to the repository was on 2026-04-02, and the recorded releases are 0.7.0 from 2023-12-13, 0.7.0a0 from 2023-03-06 and 0.6.1 from 2022-10-19.

ROS first, notebook second, and the environment that has to exist first

The installation story starts with a prerequisite that is not a Python package. You need a ROS environment with rospy, and the documentation recommends using RoboStack, which allows you to install ROS in a conda environment.

That recommendation is the reason to use this project at all rather than a plain pip install of a widget library. Putting ROS inside conda means the ROS distribution, its Python bindings and the notebook stack live in one environment you can create and destroy, which is the difference between this working and not working on a machine that already has a system ROS install.

The runtime dependencies are listed and each maps to a feature. `numpy` and `bqplot` are required for the live plotting, `ipywidgets` for the interactive widgets, and `ipycanvas` for the Turtlesim animations. `pyyaml` is necessary for rospy.

bash
    conda install jupyter bqplot pyyaml ipywidgets ipycanvas

And the package itself comes from the robostack channel.

bash
    conda install jupyter-ros -c robostack

The dependency set is worth reading as a specification of what the thing does. A library that needs bqplot is doing live plotting of numeric series. One that needs ipycanvas is drawing the turtlesim in the browser rather than in a Qt window. That is the mechanism behind the claim in the project description about avoiding the Qt separation, and it is worth understanding that the turtlesim you see in the notebook is a browser-side canvas, not the real turtlesim node's GUI.

The `js/` directory in the repository holds the JavaScript side of the widgets, and there is a `python jupyros/ros3d.py` script mentioned for regenerating the `defaults.js` javascript, which is a hint that the widget definitions are generated rather than hand-written.

One package, two notebook frontends, and the nbextension step

jupyter-ros is a Python package named `jupyros` on PyPI, and the packaging metadata shows a project that knows it has to satisfy both notebook frontends.

The classifiers list JupyterLab 3, JupyterLab 4 and the JupyterLab Extensions classifiers, and the build configuration installs the frontend assets into two different places depending on which one you use.

toml
[tool.hatch.build.targets.wheel.shared-data]
"jupyros/labextension" = "share/jupyter/labextensions/@robostack/jupyter-ros"
"jupyros/nbextension" = "share/jupyter/nbextensions/@robostack/jupyter-ros"

So a JupyterLab 4 user gets a prebuilt lab extension, and a classic notebook user gets an nbextension, and both come out of the same wheel. The build system is hatchling with the nodejs version hook, and the version number is read from `js/package.json`, which is why the project has a JavaScript build step at all.

The classic notebook path needs two extra commands that the labextension path does not, and this is the part that trips people up.

bash
    git clone https://github.com/RoboStack/jupyter-ros.git
    cd jupyter-ros
    pip install -e .
    jupyter nbextension install --py --symlink --sys-prefix jupyros
    jupyter nbextension enable --py --sys-prefix jupyros

The `--sys-prefix jupyros` argument is the important detail, because it tells Jupyter to install the extension into the environment rather than into the user directory, which matters when you have several conda environments. The development installation requires npm, and the environment is created with conda and mamba.

bash
conda create -n jupyros -c conda-forge python nodejs=14 jupyterlab=3 jupyter bqplot pyyaml ipywidgets ipycanvas

Note the pinned `nodejs=14` and `jupyterlab=3` in that environment recipe, which tells you the versions the project was developed against.

The Python side needs 3.8 or newer, and the runtime dependencies in the manifest are `ipywidgets` at 7.7.2 or later but below 8.0.0, plus bqplot, numpy, rospkg and ipycanvas.

Troubleshooting tells you what actually breaks

The troubleshooting section is short and covers the two failures you will hit, which makes it a better guide to the real constraints than the feature list.

The first is the ROS environment warning.

The warning text is the one you get when the kernel cannot see ROS: the rospy package is not found in your $PYTHONPATH, and subscribe and publish are not going to work, so you need to activate your ROS environment.

The documentation says this is harmless during installation, but that if you see it in a notebook you should check that your ROS environment is activated. There is a way to set the path from inside the notebook itself, which is the escape hatch when the environment is not activated in the kernel.

python
import sys
sys.path.append('/opt/ros/melodic/lib/python2.7/dist-packages/')

# The next line should now work!
import jupyros

That path is ROS Melodic with Python 2.7 in it, and it is worth pausing on. The example is written for the older ROS distribution, and the notebook is running a Python 2 era path. It works as a demonstration of the mechanism, but it is a snapshot of the pre-ROS 2 era, and the fact that the project's own troubleshooting text reaches for `python2.7/dist-packages` is a good signal about which generation of ROS this integration was built for.

The second failure is the widget display error, the one about a failed to display Jupyter Widget of type VBox, and the fix is a one-liner that enables the widgets nbextension for the environment: `jupyter nbextension enable --py --sys-prefix widgetsnbextension`.

Again the `--sys-prefix` is the point, for the same reason as above.

So the two things that actually break are the ROS environment not being visible to the kernel and the classic notebook frontend not having the widgets extension enabled. Neither is a bug in the widgets themselves, and both are consequences of the environment-mixing problem that the whole project exists to solve.

What the ROS 1 era integration does not cover

The version facts in the repository are the most important thing to check, and they are not favourable to a new project.

The recorded releases are 0.6.1 from October 2022, 0.7.0a0 from March 2023 and 0.7.0 from December 2023, with the version scheme still on the 0.x line. The last push to the repository was on 2026-04-02, so there has been no commit in more than six months.

The documentation's own example path points at ROS Melodic with Python 2.7, and the troubleshooting text describes a problem where subscribe and publish do not work because rospy is not on the Python path. The library talks to ROS 1 through rospy.

That is a genuine boundary, and it is not a small one. A team working on ROS 2 with rclpy, which is the generation in active use for new robotics work, cannot use this integration as it stands. The extension would need to be ported, and the port would touch every part that talks to a node.

The 0.7.0 line is also a JupyterLab 3 and 4 line, and the project still ships a classic nbextension path with the `jupyter nbextension install` and `enable` commands, which is the mechanism Jupyter deprecated in favour of prebuilt extensions. The manifest's dev environment pins `jupyterlab=3` and `nodejs=14`, both of which are well behind current versions.

So the honest description of this project is that it is a well-executed bridge between the ROS 1 world and the notebook world, built at a point when the notebook extension model was the current one, and it has not been carried forward since. The code is still worth reading, and the idea is still the right one, but the ecosystem around it has moved.

The alternative is the notebook talking to ROS directly

The realistic alternative is not another widget library. It is writing the notebook cell yourself with rclpy or rospy, which is a few lines and has none of the extension machinery.

The difference in approach is worth stating precisely. jupyter-ros gives you a graphical widget for constructing and sending messages of a custom type, plus live plotting of a topic and a canvas-rendered turtlesim. The direct approach gives you a Python object you can inspect, assert on, and drive with the full power of the language, at the cost of writing that plumbing per notebook.

For an instructor demonstrating a message type, or a student learning what a topic carries, the widget is a real improvement over a subscriber node and a plotting window. For an engineer who wants to compute something over a stream of messages, the direct approach is often shorter, because you can use a list comprehension and a scatter plot rather than configuring a widget and reading its output.

There is also the option of a JupyterLab extension built on a newer messaging stack, or of using the rosbridge or WebSocket bridges to talk to a ROS graph from the browser without a ROS Python environment at all. Those change the dependency picture in a different direction, moving the ROS side out of the kernel and onto a bridge process, which has its own latency and deployment consequences.

The common factor across all of these is that the hard part was never the widgets. It is the environment. A notebook that can import rospy has to live in an environment where rospy is importable, and every approach above inherits that constraint, whichever frontend it uses.

Editorial conclusion

jupyter-ros suits a robotics developer or student who wants to explore ROS interactively in a notebook, subscribe to a live topic and plot it, or drive the turtlesim from a cell without writing a Qt node. It does not suit a production robotics stack, since the last release predates ROS 2 and the project has seen no push since 2026-04-02. Verify first that your ROS distribution matches the environment you are installing into, that the notebook frontend you use is one the extension registers for, since the package ships both a JupyterLab extension and a classic nbextension, and that you are prepared to run from source if the published conda package does not match your setup.

Frequently asked questions

How do I install jupyter-ros?

You need a ROS environment with rospy first, and the documentation recommends RoboStack, which installs ROS in a conda environment. Then run conda install jupyter-ros -c robostack, with numpy, bqplot, pyyaml, ipywidgets and ipycanvas also required.

What does jupyter-ros actually add to a notebook?

It lets a notebook create widgets for custom message types and send messages, provides live plotting with bqplot, and renders the Turtlesim animations with ipycanvas. The project frames it as a way to keep ROS work in a notebook rather than in separate Qt-based tools.

Why do I see a warning that the rospy package is not found in my PYTHONPATH?

It means the ROS environment is not active in the kernel, so subscribe and publish will not work. The documentation says the warning is harmless during installation, and suggests either activating the ROS environment or appending the ROS Python path from inside the notebook.

How do I fix a failed to display Jupyter Widget of type VBox error?

Run jupyter nbextension enable --py --sys-prefix widgetsnbextension. The classic notebook frontend needs the widgets nbextension enabled for the environment, and the sys-prefix argument points it at the environment rather than the user directory.

Does jupyter-ros work with ROS 2?

The documentation's own example points at the ROS Melodic path with python2.7 in it, and the library talks to ROS through rospy, so the integration as documented is for ROS 1. The recorded releases are 0.7.0 from 2023-12-13 and earlier, and the last push was on 2026-04-02.

Official sources

  1. License: BSD-3-Clause
  2. Project website
  3. README
  4. Releases
  5. RoboStack/jupyter-ros on GitHub
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/robostack-jupyter-ros.svg)](https://hysenlabs.com/projects/robostack-jupyter-ros)

Was this useful?