Comparing Panel and ipywidgets#

Both Panel and ipywidgets (aka Jupyter Widgets) allow Python users to work with custom widgets and create apps and dashboards from Python, both in Jupyter notebooks and in standalone servers (when paired with Voila. But Panel and ipywidgets are based on different, independently developed technologies for doing so, with some implications:

  • Panel is based on Bokeh widgets and layouts, which were developed separately from the Jupyter ecosystem, and designed from the start for standalone deployments. Jupyter widgets, as the name suggests, were first developed specifically for the notebook environment, and only relatively recently (in 2019) adapted for standalone deployment (see Voila). Nowadays, both technologies have evolved to be well suited to both Jupyter and server contexts, but their different histories are still visible in the types of examples you typically see and in support for less-common operations for each library.

  • Historically, ipywidgets exposed more of the underlying HTML/CSS styling options, allowing them to be customized more heavily than Bokeh widgets, but since Bokeh 3.0 and Panel 1.0 both types of widgets support similar types of styling.

  • Panel widgets support easy embedding into static HTML pages for exporting notebooks, while ipywidgets require a separate and cumbersome “embed widget state” operation to copy state from Python into the web page source. Panel widgets are thus easier to use for HTML reports, documentation (e.g. with Sphinx), and other cases where the output needs to be readable or usable without a running Python process

  • Where appropriate, Panel supports separating your scientific/engineering/business logic from your GUI implementation, allowing you to declare information that is used to make widgets in a way that is independent of any particular GUI toolkit, web packages, browser, or any other fast-changing technology. Specifically, Panel widgets build on the Param library that allows capturing the arguments and parameters of functions and classes independently of how the user may later provide or adjust those values. Param lets you specify the name, type, docstring, and range of valid values in a generic way that has no dependencies on any GUI library (or any other library) and allows validating user input in general, not just for a specific dashboard app. Once the parameters have been declared, the code can be used for command-line applications, servers, batch jobs, or (with Panel) generating live, active widgets automatically with no further customization needed to build an app. Param has been in continuous use by multiple libraries since 2003, across many generations of GUI toolkits, and can be expected to adapt to future toolkits as they become available without needing changes to your own domain-specific codebase. Via Param, Panel can thus integrate into a large, long-lived codebase that is used in a variety of different ways at any one time or over its lifetime, such as a simulator or modeling tool, domain-specific analysis libraries, automated processing pipelines, and so on, without ever needing the code to be rewritten or having the GUI code drift out of sync with the business/scientific logic. ipywidgets were designed primarily for the final application or dashboard usage, not for this full life cycle of research or analysis code.

  • Panel widgets are reactive, allowing declarative specification of dependencies between code and widgets (or, more specifically, between code and the Param parameter values inside the widgets). This approach makes it possible to support directly accepting widget objects as arguments to Python code. That way, users never have to write explicit Python callbacks, yet the code will dynamically be executed as needed to respond to user interaction. This programming paradigm can provide highly responsive GUI applications with much less code and much simpler reasoning, as illustrated in the Datashader widget dashboard.

  • As of 9/2020, both types of widgets are now fully interoperable; you can use Panel or Bokeh widgets and panes in an ipywidgets-based app using jupyter_bokeh and you can use ipywidgets in a Panel or Bokeh app using ipywidgets_bokeh. So in practice, you can now mix and match content from either ecosystem as needed, choosing your “native” ecosystem based on other factors like deployment options (e.g. Voila vs panel serve).