A WebGL-powered Jupyter Widget for Niivue based on anywidget
See the codeThis is a Jupyter Widget for Niivue based on anywidget. It is designed to visualize neuroimaging volumes, meshes, streamlines and connectomes and their corresponding statistical maps. This repository is designed for advanced developers to build and extend ipyniivue. The minimal installation end users is pip install ipyniivue. Most users will likely find the example jupyter notebooks the ideal introduction to the capability.
ipyniivue is a Jupyter widget for the Niivue. It enables interactive visualization of neuroimaging data directly in Jupyter environments, including volumetric images, surface meshes, streamlines, connectomes, and their associated statistical maps.
This repository is intended solely for advanced developers who want to build and extend ipyniivue. For others, the example Jupyter notebooks provides a simple installation.
For most users, the best introduction to ipyniivue’s capabilities is the collection of example Jupyter notebooks. However, the minimal installation is simply:
pip install ipyniivue
See the Documentation for usage.
ipyniivue uses the recommended hatchling build system, which is convenient to use via the hatch CLI. We recommend installing hatch globally (e.g., via pipx) and running the various commands defined within pyproject.toml. hatch will take care of creating and synchronizing a virtual environment with all dependencies defined in pyproject.toml.
These steps set up a local development environment for ipyniivue with live JavaScript rebuilding via anywidget.
hatch installed (e.g. via pipx install hatch)ipyniivue is not already installed in your Python environmentMake sure hatch is available and ipyniivue is not installed:
hatch --version
pip show ipyniivue || echo "ipyniivue not installed (good)"
git clone https://github.com/niivue/ipyniivue.git
cd ipyniivue
From the repository root:
npm install
hatch shell
This activates the project’s Python development environment.
pip install -e ".[dev]"
This activates the project’s Python development environment.
In the same terminal:
cd js
npm run dev
This runs the JavaScript build in watch mode, rebuilding the widget automatically when files change.
Leave this terminal running.
Open a second terminal tab/window, again from the ipyniivue repository root.
hatch shell
ipyniivue in editable modepip install -e .
This ensures Python picks up the locally built widget assets.
jupyter lab
You can now open an example notebook and develop ipyniivue with live JavaScript updates.
export ANYWIDGET_HMR=1
before launching JupyterLab.npm run dev is still runningpip install -e . was run after starting the JS buildnpm run dev.Run these commands from the root of the project:
| Command | Description |
|---|---|
hatch run format | Format the project with ruff format . and apply linting with ruff --fix . |
hatch run lint | Lint the project with ruff check . |
hatch run test | Run unit tests with pytest |
hatch run docs | Build docs with Sphinx |
Alternatively, you can manually create a virtual environment and manage installation and dependencies with pip:
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
This is an anywidget project, meaning the codebase is a hybrid of Python and JavaScript. The JavaScript code resides under the js/ directory and uses esbuild for bundling. Whenever you make changes to the JavaScript code, you need to rebuild the files under src/ipyniivue/static.
You have two options:
Build Once: Build the JavaScript code one time:
npm run build
Start Development Server: Start a development server that automatically rebuilds the code as you make changes:
npm run dev
We recommend this approach for a smoother development experience.
Working with Jupyter
Once the development server is running, you can start JupyterLab or Visual Studio Code to develop the widget. When you're finished, stop the development server with Ctrl+C.
Note: To have
anywidgetautomatically apply changes as you work, set the environment variableANYWIDGET_HMR=1. You can set this directly in a notebook cell:%env ANYWIDGET_HMR=1or in the shell:
export ANYWIDGET_HMR=1
Releases are automated using GitHub Actions via the release.yml workflow.
Commit Changes: Ensure all your changes are committed.
Create a Tag: Create a new tag matching the pattern v*:
git tag -a vX.X.X -m "vX.X.X"
git push --follow-tags
Workflow Actions: When triggered, the workflow will:
antfu/changelogithub.ipyniivue includes tooling to generate a static HTML gallery from example notebooks.
Each notebook is:
All generated artifacts live in a test-only output directory and are never committed.
tests-out/
html/ # generated static HTML per notebook
gallery/
thumbnails/ # canvas thumbnails
index.html # gallery page
The entire tests-out/ directory is gitignored and safe to delete at any time.
npm run gallery
This will:
examples/tests-out/html/tests-out/gallery/index.htmlYou can open the gallery locally:
open tests-out/gallery/index.html
To remove all generated HTML, thumbnails, and executed notebooks:
npm run clean:generated-html
To preview what would be removed:
npm run clean:generated-html:dry
ipyniivue uses Playwright to run end-to-end tests against pre-executed static HTML, rather than interacting with live Jupyter notebooks.
This approach provides:
The E2E pipeline consists of two steps:
npm run test:e2e
This runs:
scripts/prepare-e2e.cjs # executes notebooks → static HTML in tests-out/
playwright test # loads static HTML and runs assertions
For each notebook:
<canvas> element is renderedSnapshots are stored under:
e2e-tests/__screenshots__/
These snapshot images should be committed, as they define the visual baseline.
When a visualization changes intentionally:
npx playwright test --update-snapshots
This regenerates the baseline screenshots.
All generated HTML and intermediate files are written to:
tests-out/
This directory is:
npm run clean:generated-htmlWe intentionally avoid driving the JupyterLab UI in tests.
Static HTML testing provides:
This is the recommended approach for testing interactive notebook-based visualization libraries.
613 followers · starred Nov 2025
486 followers · starred Apr 2026
25 followers · starred Apr 2025
A WebGL-powered Jupyter Widget for Niivue based on anywidget
See the codeThis is a Jupyter Widget for Niivue based on anywidget. It is designed to visualize neuroimaging volumes, meshes, streamlines and connectomes and their corresponding statistical maps. This repository is designed for advanced developers to build and extend ipyniivue. The minimal installation end users is pip install ipyniivue. Most users will likely find the example jupyter notebooks the ideal introduction to the capability.
ipyniivue is a Jupyter widget for the Niivue. It enables interactive visualization of neuroimaging data directly in Jupyter environments, including volumetric images, surface meshes, streamlines, connectomes, and their associated statistical maps.
This repository is intended solely for advanced developers who want to build and extend ipyniivue. For others, the example Jupyter notebooks provides a simple installation.
For most users, the best introduction to ipyniivue’s capabilities is the collection of example Jupyter notebooks. However, the minimal installation is simply:
pip install ipyniivue
See the Documentation for usage.
ipyniivue uses the recommended hatchling build system, which is convenient to use via the hatch CLI. We recommend installing hatch globally (e.g., via pipx) and running the various commands defined within pyproject.toml. hatch will take care of creating and synchronizing a virtual environment with all dependencies defined in pyproject.toml.
These steps set up a local development environment for ipyniivue with live JavaScript rebuilding via anywidget.
hatch installed (e.g. via pipx install hatch)ipyniivue is not already installed in your Python environmentMake sure hatch is available and ipyniivue is not installed:
hatch --version
pip show ipyniivue || echo "ipyniivue not installed (good)"
git clone https://github.com/niivue/ipyniivue.git
cd ipyniivue
From the repository root:
npm install
hatch shell
This activates the project’s Python development environment.
pip install -e ".[dev]"
This activates the project’s Python development environment.
In the same terminal:
cd js
npm run dev
This runs the JavaScript build in watch mode, rebuilding the widget automatically when files change.
Leave this terminal running.
Open a second terminal tab/window, again from the ipyniivue repository root.
hatch shell
ipyniivue in editable modepip install -e .
This ensures Python picks up the locally built widget assets.
jupyter lab
You can now open an example notebook and develop ipyniivue with live JavaScript updates.
export ANYWIDGET_HMR=1
before launching JupyterLab.npm run dev is still runningpip install -e . was run after starting the JS buildnpm run dev.Run these commands from the root of the project:
| Command | Description |
|---|---|
hatch run format | Format the project with ruff format . and apply linting with ruff --fix . |
hatch run lint | Lint the project with ruff check . |
hatch run test | Run unit tests with pytest |
hatch run docs | Build docs with Sphinx |
Alternatively, you can manually create a virtual environment and manage installation and dependencies with pip:
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
This is an anywidget project, meaning the codebase is a hybrid of Python and JavaScript. The JavaScript code resides under the js/ directory and uses esbuild for bundling. Whenever you make changes to the JavaScript code, you need to rebuild the files under src/ipyniivue/static.
You have two options:
Build Once: Build the JavaScript code one time:
npm run build
Start Development Server: Start a development server that automatically rebuilds the code as you make changes:
npm run dev
We recommend this approach for a smoother development experience.
Working with Jupyter
Once the development server is running, you can start JupyterLab or Visual Studio Code to develop the widget. When you're finished, stop the development server with Ctrl+C.
Note: To have
anywidgetautomatically apply changes as you work, set the environment variableANYWIDGET_HMR=1. You can set this directly in a notebook cell:%env ANYWIDGET_HMR=1or in the shell:
export ANYWIDGET_HMR=1
Releases are automated using GitHub Actions via the release.yml workflow.
Commit Changes: Ensure all your changes are committed.
Create a Tag: Create a new tag matching the pattern v*:
git tag -a vX.X.X -m "vX.X.X"
git push --follow-tags
Workflow Actions: When triggered, the workflow will:
antfu/changelogithub.ipyniivue includes tooling to generate a static HTML gallery from example notebooks.
Each notebook is:
All generated artifacts live in a test-only output directory and are never committed.
tests-out/
html/ # generated static HTML per notebook
gallery/
thumbnails/ # canvas thumbnails
index.html # gallery page
The entire tests-out/ directory is gitignored and safe to delete at any time.
npm run gallery
This will:
examples/tests-out/html/tests-out/gallery/index.htmlYou can open the gallery locally:
open tests-out/gallery/index.html
To remove all generated HTML, thumbnails, and executed notebooks:
npm run clean:generated-html
To preview what would be removed:
npm run clean:generated-html:dry
ipyniivue uses Playwright to run end-to-end tests against pre-executed static HTML, rather than interacting with live Jupyter notebooks.
This approach provides:
The E2E pipeline consists of two steps:
npm run test:e2e
This runs:
scripts/prepare-e2e.cjs # executes notebooks → static HTML in tests-out/
playwright test # loads static HTML and runs assertions
For each notebook:
<canvas> element is renderedSnapshots are stored under:
e2e-tests/__screenshots__/
These snapshot images should be committed, as they define the visual baseline.
When a visualization changes intentionally:
npx playwright test --update-snapshots
This regenerates the baseline screenshots.
All generated HTML and intermediate files are written to:
tests-out/
This directory is:
npm run clean:generated-htmlWe intentionally avoid driving the JupyterLab UI in tests.
Static HTML testing provides:
This is the recommended approach for testing interactive notebook-based visualization libraries.
613 followers · starred Nov 2025
486 followers · starred Apr 2026
25 followers · starred Apr 2025