Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

manywidgets

A composable set of anywidget-based widgets for data analysis and geospatial work in notebooks. They're self-contained, link and compose, work well with lonboard, and render statically (no kernel) via the myst-anywidget-static-export MyST plugin.

Status: early but feature-complete for v1 — Chart, input controls (Slider, RangeSlider, Dropdown, Toggle, Button, NumberInput), value displays (Stat, NumberDisplay, Text), layout containers (Row, Column, Grid), the Binder linking primitive, and optional lonboard interop (LayerToggle, FilterBinder, LayerFilter).

Install

pip install manywidgets
# optional lonboard interop widgets:
pip install "manywidgets[lonboard]"

Quick start

from manywidgets import Chart, Slider, Binder
import numpy as np

chart = Chart(title="Demo", x_label="x", y_label="y", height=320)
chart.add_series(x=np.linspace(0, 10, 100), y=np.sin(np.linspace(0, 10, 100)), name="sin")
chart

Widgets

from manywidgets import (
    Chart,                                   # Chart.js charts
    Slider, RangeSlider, Dropdown, Toggle, Button, NumberInput,  # input controls
    Stat, NumberDisplay, Text, Legend,       # value displays
    Row, Column, Grid,                       # layout (arrange + keep children linked)
    Binder,                                  # linking with transforms / nested paths
)

# Optional lonboard interop (pip install "manywidgets[lonboard]")
from manywidgets.lonboard import LayerToggle, FilterBinder, LayerFilter

Linking widgets

Two complementary tools — see docs/guides/linking.md:

from ipywidgets import jsdlink

# 1. jslink / jsdlink — the canonical, kernel-free pass-through link.
slider = Slider(label="Amplitude", min=0, max=5, value=1)
jsdlink((slider, "value"), (chart, "title"))  # browser-side, works live + static

# 2. Binder — for transforms / nested paths jslink can't express.
Binder(source=slider, source_field="value",
       target=chart, target_field="height",
       multiplier=100, offset=200)

Agent skill

manywidgets ships an agent skill so coding agents can help you build widgets and dashboards. Install it into a location your agent discovers:

manywidgets install-skill            # ./.claude/skills/manywidgets/ (this project)
manywidgets install-skill --user     # ~/.claude/skills/manywidgets/ (all projects)
manywidgets install-skill --path DIR # anywhere else (other agents)

The skill (an entrypoint plus references/ on widget API, usage, and authoring) travels inside the wheel, so it always matches the installed version. The per-widget API reference is generated from widget traits — never hand-edited.

How it works / design

Every widget extends a thin BaseWidget (auto-assigns a stable widget_id) and follows the TypeScript "golden example" structure: src/index.ts bundled by esbuild into dist/widget.js, styling via the _css trait. Cross-widget resolution and the static-export safety rules live once in a shared @manywidgets/core TypeScript module that esbuild inlines into each widget.

This package has no code dependency on the static-export plugin — it just follows the rules the plugin needs (wrap save_changes, never inject <link> into the mount element, vanilla DOM, buffer-free core widgets, link via jslink/Binder). The docs site references the plugin by release URL only.

Development

npm install
npm run build          # esbuild every widget src/index.ts -> dist/widget.js
npm run typecheck      # tsc --noEmit
npm test               # vitest (JS unit tests)
pip install -e ".[dev]"
pytest

Docs

Each widget owns its docs in src/manywidgets/<name>/doc.md (prose + a {code-cell} example + an {api-table} placeholder). npm run docs:gen builds docs/widgets/<name>.ipynb from those — auto-generating the API table from trait introspection — so the per-widget pages are generated build artifacts (gitignored), not hand-maintained. The agent skill's API reference is generated the same way (npm run skill:gensrc/manywidgets/skill/references/widgets-api.md, which is committed and CI-checked for drift) — regenerate it after changing any widget's traits. Build and view:

# lonboard + geopandas + pyarrow are only needed for the lonboard interop example
pip install -e ".[numpy,lonboard]" ipykernel nbconvert nbformat geopandas pyarrow
python -m ipykernel install --user --name manywidgets-venv
npm run docs:gen       # generate docs/widgets/*.ipynb from each widget's doc.md
jupyter nbconvert --to notebook --execute --inplace docs/examples/*.ipynb docs/widgets/*.ipynb
cd docs && npx myst build --html && cd ..
npm run serve          # serve over HTTP at http://localhost:8000 (NOT file://)

Serve the built site over HTTP — opening the HTML via file:// breaks asset and widget loading (absolute paths + dynamic import()).

Releases are cut by publishing a GitHub Release (CI builds the wheel — with JS compiled by the build hook — and publishes to PyPI). The JS bundles are gitignored and rebuilt by the build; they ship inside the wheel.

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

manywidgets-0.2.0a1.tar.gz (271.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

manywidgets-0.2.0a1-py3-none-any.whl (286.6 kB view details)

Uploaded Python 3

File details

Details for the file manywidgets-0.2.0a1.tar.gz.

File metadata

  • Download URL: manywidgets-0.2.0a1.tar.gz
  • Upload date:
  • Size: 271.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for manywidgets-0.2.0a1.tar.gz
Algorithm Hash digest
SHA256 acf8e7cfb27cb5f4493a8f5728e2cef9a11a7502e0985942d7dd9fdaeafc5c6d
MD5 78fc588af4e3c440b8f3cd29060c8085
BLAKE2b-256 315dafa03674787b820c38770c5e08c4b001bdccf56a86cb946c085eb91f1074

See more details on using hashes here.

Provenance

The following attestation bundles were made for manywidgets-0.2.0a1.tar.gz:

Publisher: release.yml on developmentseed/manywidgets

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file manywidgets-0.2.0a1-py3-none-any.whl.

File metadata

  • Download URL: manywidgets-0.2.0a1-py3-none-any.whl
  • Upload date:
  • Size: 286.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for manywidgets-0.2.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 56894c24c0e527ec12a8629520df96ac1c5030264266356932326f721acd7089
MD5 ef27523628a2b0f660846e2915173196
BLAKE2b-256 18e076b8a2c19764f457cd3ab321507a2d832cc1944938f7ecfb3cb97442bb9a

See more details on using hashes here.

Provenance

The following attestation bundles were made for manywidgets-0.2.0a1-py3-none-any.whl:

Publisher: release.yml on developmentseed/manywidgets

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page