jupyterlab-a11y-checker
jupyterLab-a11y-checker is a JupyterLab extension that helps authors detect and fix accessibility issues in Jupyter Notebooks, aligning with WCAG 2.1 AA guidelines. It enables authors to identify accessibility issues in their notebooks and provides actionable suggestions to fix them. It combines the strengths of axe-core, a widely used accessibility engine, with custom notebook-specific detection algorithms that address issues axe cannot reliably cover in JupyterLab.
Here's how the extension looks like:
Tool Description
Issue Detection
While there are many possible a11y issues in Jupyter Notebooks, we prioritized the issues discussed in a study on Jupyter Notebooks, Notably Inaccessible — Data Driven Understanding of Data Science Notebook (In)Accessibility. To address them, we implement custom detection logic for the issues listed in Rule Description. In addition, we integrate axe-core to detect other standard accessibility issues beyond these main issues, which are listed in Axe Rule Description.
Issue Resolution
We provide a user interface tailored to each issue, such as a text field for adding alt-text, a dropdown for fixing header issues, etc. The fix interfaces are listed in Fix Interface Description.
AI Assistance
To simplify the remediation process, we integrate both a Large Language Model (LLM) and a Vision-Language Model (VLM) to generate accessibility recommendations within several fix interfaces. Users can configure these models by providing their API endpoint, API key, and model name in: Settings > Settings Editor > A11y Checker Settings.
Getting Started
Installing
You can install the extension directly via pip:
pip install jupyterlab-a11y-checker
Find the package on PyPI. Link to PyPI Package.
CLI Usage
If you need to run checks offline or in CI, the repository now ships a CLI that uses the same detection logic as the extension.
-
Build the library to populate
lib/cli/index.js:jlpm clean:lib && jlpm build:lib
-
Optionally link it so the
jupyterlab-a11y-checkcommand is available system-wide:jlpm link jupyterlab-a11y-check docs/examples/notebooks/Demo.ipynb
(Undo with
jlpm unlinkwhen done.) -
To produce only the LLM-friendly JSON summary (no human-friendly log), run:
jupyterlab-a11y-check --json test_notebooks/Demo.ipynb
The CLI output matches what the extension returns, so you can pipe the JSON directly into downstream LLM/automation workflows.
Contributing
We’re building this tool for the community, and we’d love your help! Whether it’s adding new accessibility checks, or refining the fix suggestions, your contributions can help this project make a broader impact.
Build from Scratch
# Create an environment using anaconda navigator: <env-name>
conda activate <env-name>
pip install cookie cutter
python -m pip install jupyterlab notebook --pre
mamba install -c conda-forge nodejs=18
node -v #to check version
# <pull code>
OR
cookiecutter https://github.com/jupyterlab/extension-cookiecutter-ts --checkout 4.0
jlpm
jlpm run build
jupyter labextension develop . --overwrite
python -m pip install -e .
pip list #to verify it has been installed in editable mode
jupyter labextension list #to verify it has been installed
jupyter lab --no-browser #run a jupyterlab server
#Run jlpm run build, then jupyter lab --no-browser to test your code after each change
Build from Temp Distribution
jlpm build:prod
npm pack #creates a tarball (*.tgz file) containing your project as it would be uploaded to the npm registry. This file can be shared and installed locally.
jupyter labextension install </path/to/your-package.tgz>
# ALTERNATIOVELY IF GIVEN A tar.gz file:
conda activate <env-name>
jupyter labextension install </path/to/your-package.tgz>
jupyter lab #this will open a local server of jupyterlab with all current extensions installed.
Pip Distribution
pip install twine
# create a ~/.pypirc file at root and add this to it:
[distutils]
index-servers =
pypi
[pypi]
repository: https://upload.pypi.org/legacy/
username: __token__
password: your-api-token
#run this command and publish to pip.
twine upload your-package.whl
Development uninstall
pip uninstall jupyterlab_a11y_checker
Testing in a JupyterHub setup
- Build the Jupyter Lab extension with the latest changes
jlpm
jlpm build
jupyter lab build
- Package the extension as a wheel file (.whl)
python -m build
.whl file gets generated in the dist/ directory
-
Copy the .whl file to the server where JupyterHub is installed (or include it in a Dockerfile if using Docker)
-
Install the .whl file:
pip install /path/to/your-extension.whl
- If the identical version of the extension is already installed then
pip uninstall extension-name
pip install /path/to/your-extension.whl
- Refresh the page for the changes to apply
In development mode, you will also need to remove the symlink created by jupyter labextension develop
command. To find its location, you can run jupyter labextension list to figure out where the labextensions
folder is located. Then you can remove the symlink named jupyterlab-a11y-checker within that folder.
Acknowledgements
Fix the hackmd file for me
Acknowledgements
| Name | Role | GitHub Handle |
|---|---|---|
| Chanbin Park | Student Developer | @chanbinski |
| Vivian Liu | Student Developer | @vzliu |
| Shreyas Rana | Student Developer | @ranashreyas |
| Balaji Alwar | Project Lead | @balajialg |
| Ryan Lovett | Volunteer (Jupyter Consultant) | @ryanlovett |
| Joe Feria Galicia | Volunteer (a11y expert) | NA |
Metadata
Release files for jupyterlab-a11y-checker 0.2.9
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jupyterlab_a11y_checker-0.2.9.tar.gz | 256.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jupyterlab_a11y_checker-0.2.9-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 732.3 kB
Release files / jupyterlab_a11y_checker-0.2.9.tar.gz
| Download URL | jupyterlab_a11y_checker-0.2.9.tar.gz |
|---|---|
| Size | 256.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e3991dae0fac054cb4428e9308cd5cfb2cc61dd72ead23ec25ca2747bcdef0ed
|
|
BLAKE2b-256 checksum How to use checksums |
7939c76f1f5dc852ae6e4a23f24e9eaec80e4a1dd11c2541af6ec9527ee80059
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency logRelease files / jupyterlab_a11y_checker-0.2.9-py3-none-any.whl
| Download URL | jupyterlab_a11y_checker-0.2.9-py3-none-any.whl |
|---|---|
| Size | 476.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a59ca15ea8fb71f81f24e466e97c60d3397caaa9b99838f91451d9e8a72f5cdc
|
|
BLAKE2b-256 checksum How to use checksums |
3a9c1529b7a559c09f7bdf45ca9f7339c9cdda014916f7efe34131dbab83edae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency log