nb-clean cleans Jupyter notebooks for version control. It removes cell metadata, execution counts, outputs, and the notebook's language version. It can check notebooks in CI, clean files in place, or run as a Git filter or pre-commit hook.
Installation
Install a published release from PyPI with uv:
uv tool install nb-clean
For a single invocation:
uvx nb-clean check notebooks/
Wheels contain the native executable and require Python 3.10 or later for installation. They are built for macOS and Linux on ARM64 and x86-64, and Windows on x86-64. Linux wheels require glibc 2.17 or later. Use Cargo or binary archives on other platforms.
Install a published release from crates.io with Cargo:
cargo install nb-clean --locked
Building requires Rust 1.85 or later.
Download binary archives from
GitHub releases for macOS
(Apple Silicon and Intel), Linux (ARM64 and x86-64), and Windows (x86-64).
Extract the archive and put nb-clean or nb-clean.exe on your PATH. Linux
archives are built on Ubuntu 22.04 and use glibc. Build from source for systems
incompatible with those binaries. Running nb-clean does not require a Python
installation. Git is needed only for filter configuration.
Checking and cleaning
nb-clean check notebook.ipynb
nb-clean check notebooks/
nb-clean clean notebook.ipynb
nb-clean clean notebooks/ another.ipynb
Directories are searched recursively for .ipynb files. Overlapping inputs and
symlink aliases are processed once. Directory symlinks encountered during
recursion are skipped; an explicitly supplied directory symlink is traversed.
Notebook file symlinks are followed, and cleaning updates their targets while
preserving the links.
check reports unwanted content and exits with status 1 if any notebooks are
dirty. Cells are numbered from zero. clean updates changed files while
preserving their permissions. Already-clean files are left untouched. If a file
fails, remaining files are still processed and the command returns an error
status.
With no paths, both commands read stdin. Cleaning writes the notebook to stdout:
nb-clean check < notebook.ipynb
nb-clean clean < original.ipynb > cleaned.ipynb
Clean stdin is passed through unchanged. Changed notebooks are written with
sorted keys, one-space indentation, Unicode text, and a trailing newline,
following nbformat's JSON layout.
nb-clean supports nbformat 4. It checks the structure needed for cleaning, keeps unknown fields, and does not upgrade notebooks or repair cell IDs. Empty source means an empty string or an array whose strings are all empty. Whitespace-only cells are retained.
Options
These options work with check, clean, and add-filter:
| Option | Effect |
|---|---|
-e, --remove-empty-cells |
Remove empty cells, or report them in checks |
-M, --remove-all-notebook-metadata |
Remove all notebook metadata |
-m, --preserve-cell-metadata |
Preserve all cell metadata except transient fields |
--preserve-cell-metadata-field FIELD |
Preserve a selected cell metadata field; repeat for more fields |
-o, --preserve-cell-outputs |
Preserve cell outputs |
-c, --preserve-execution-counts |
Preserve cell and output execution counts |
-n, --preserve-notebook-metadata |
Preserve notebook metadata except transient fields |
By default, notebook metadata is retained except language_info.version and
transient fields. Preserving outputs with -o still clears output execution
counts unless -c is also supplied.
For example, preserve cell tags and slideshow settings:
nb-clean clean --preserve-cell-metadata-field tags \
--preserve-cell-metadata-field slideshow notebook.ipynb
Following nbformat, nb-clean always removes notebook metadata orig_nbformat,
orig_nbformat_minor, and signature, and cell metadata trusted.
Preservation options do not override this rule. Their presence makes a notebook
dirty.
-M conflicts with -n. Preserving all cell metadata conflicts with selecting
individual fields. Use nb-clean --help or nb-clean clean --help for help,
and nb-clean --version for the version.
Git filter
From a Git working tree:
nb-clean add-filter
# Or configure the filter with cleaning options:
nb-clean add-filter --preserve-cell-metadata-field tags
nb-clean remove-filter
The filter is configured in the local Git configuration and
.git/info/attributes. Staging cleans the notebook in the index; the working
copy keeps its outputs. Installation and removal are idempotent and preserve
unrelated settings and attributes. The executable must be on PATH when Git
stages notebooks.
Pre-commit
Add this to .pre-commit-config.yaml:
repos:
- repo: https://github.com/srstevenson/nb-clean
rev: v5.0.0
hooks:
- id: nb-clean
args: [--preserve-cell-metadata-field, tags]
Pre-commit builds the executable. The hook cleans notebooks in the working directory, so their outputs are removed on disk.
Jujutsu
Add this to ~/.config/jj/config.toml, then run jj fix:
[fix.tools.nb-clean]
command = ["nb-clean", "clean"]
patterns = ["glob:'**/*.ipynb'"]
Append cleaning options to the command array as needed.
Exit statuses
| Status | Meaning |
|---|---|
0 |
Success, or all checked notebooks are clean |
1 |
At least one checked notebook is dirty |
64 |
Invalid command-line arguments |
65 |
Malformed notebook or unsupported format version |
66 |
Input cannot be opened or a directory cannot be traversed |
69 |
Git executable is unavailable |
73 |
Output cannot be created or replaced |
74 |
Other read or write failure |
78 |
Git repository or configuration error |
Errors take precedence over dirty results. If several files fail, the status corresponds to the first error in sorted processing order. Errors go to stderr; check findings go to stdout.
Migrating from nb-clean 4
nb-clean was ported from Python to Rust in version 5. PyPI wheels install the native executable; the Python library API is removed. The installed command supports Git filters and pre-commit as before.
Use nb-clean --version instead of nb-clean version. To preserve selected
metadata, replace --preserve-cell-metadata tags slideshow -- with
--preserve-cell-metadata-field tags --preserve-cell-metadata-field slideshow.
The bare -m option now accepts no field arguments and can appear before paths.
An execution count of zero is now reported as dirty. Transient metadata is also reported explicitly. Processing errors use the statuses above, and clean files are no longer rewritten just to normalise formatting. Unsupported notebook major versions are rejected.
Development
See the contribution instructions.
Copyright
Copyright Scott Stevenson. Distributed under the ISC licence.
Metadata
Release files for nb-clean 5.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| nb_clean-5.0.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details for nb_clean-5.0.0-py3-none-win_amd64.whl |
| nb_clean-5.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details for nb_clean-5.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| nb_clean-5.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details for nb_clean-5.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
| nb_clean-5.0.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details for nb_clean-5.0.0-py3-none-macosx_11_0_arm64.whl |
| nb_clean-5.0.0-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details for nb_clean-5.0.0-py3-none-macosx_10_12_x86_64.whl |
Total release size: 2.6 MB
Release files / nb_clean-5.0.0-py3-none-win_amd64.whl
| Download URL | nb_clean-5.0.0-py3-none-win_amd64.whl |
|---|---|
| Size | 490.8 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c012cd06304605427c9ce8387d4fa290d2983964a766f1b4fe4efd98f2535cad
|
|
BLAKE2b-256 checksum How to use checksums |
3b37563b8edc808d587aec22a9ce4b4c98b5e30befd05b14b96de76702176bf2
|
| 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 Oct 25, 2026.
Transparency logRelease files / nb_clean-5.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | nb_clean-5.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 553.6 kB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
3001effac236d10ad2e4f92c096c03d7de5b1ad61a05c4589096549a744fb92d
|
|
BLAKE2b-256 checksum How to use checksums |
83676b8c2a586323d10a5034cffd7d52b29afa932ae6cb2d2aaca05c073afa95
|
| 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 Oct 25, 2026.
Transparency logRelease files / nb_clean-5.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | nb_clean-5.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 515.7 kB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
2343a5f96230bc904fc3baf206040a5593ff3e16ece88d791446ea01e7b76712
|
|
BLAKE2b-256 checksum How to use checksums |
9a486a9ddc7c6595c6f2f78533d29939ea9045ec87b581767309f22c771939ea
|
| 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 Oct 25, 2026.
Transparency logRelease files / nb_clean-5.0.0-py3-none-macosx_11_0_arm64.whl
| Download URL | nb_clean-5.0.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 507.3 kB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
4e239bbbc722ba43818dc32be0cdbbd4789df41bcbd1967e07878847d4195030
|
|
BLAKE2b-256 checksum How to use checksums |
afce8ffbfd9529544898e28942eff12dd8331118bbbe0ecadf1215dee5218262
|
| 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 Oct 25, 2026.
Transparency logRelease files / nb_clean-5.0.0-py3-none-macosx_10_12_x86_64.whl
| Download URL | nb_clean-5.0.0-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 535.4 kB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
935629e39aabbed773b4a220b37ff4456296daee5f5e443592dd44f3d5fa4a2c
|
|
BLAKE2b-256 checksum How to use checksums |
5c99db2a18f97b3b9eb63945e919b801849f7fd1169f585c8dddf54134dcee3c
|
| 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 Oct 25, 2026.
Transparency logSecurity for nb-clean 5.0.0
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.
Full provenance
All 5 files in this release have been uploaded with provenance metadata.
Attestation for nb_clean-5.0.0-py3-none-win_amd64.whl
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 Oct 25, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.