Skip to main content

License Crates.io CI

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.88 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, skipping hidden files and directories (such as .ipynb_checkpoints) and paths ignored by Git. Paths supplied explicitly are always processed. Use --no-ignore to disregard Git ignore rules, or --hidden to include hidden files and directories. Pass both to search all directories without either restriction:

nb-clean clean --no-ignore --hidden notebooks/

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 directory search options work with check and clean:

Option Effect
--no-ignore Disregard Git ignore rules
--hidden Include hidden files and directories

The flags are independent: --no-ignore still skips hidden paths, and --hidden still respects Git ignore rules. Neither flag affects explicitly supplied files or stdin.

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: v6.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 5

check and clean now skip hidden files and directories, including .ipynb_checkpoints, and Git-ignored paths when searching directories. Previously, these notebooks were included.

To retain the version 5 directory search behaviour, add both --no-ignore and --hidden:

nb-clean check --no-ignore --hidden notebooks/
nb-clean clean --no-ignore --hidden notebooks/

The flags are independent: --no-ignore disables Git ignore rules, while --hidden includes hidden files and directories. Explicitly supplied files are still processed regardless of either restriction. Stdin, Git filters, and the standard pre-commit hook need no changes.

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 Scott Stevenson. Distributed under the ISC licence.

Metadata

Release files for nb-clean 6.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for nb-clean 6.0.0
File Actions
nb_clean-6.0.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details for nb_clean-6.0.0-py3-none-win_amd64.whl
nb_clean-6.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-6.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
nb_clean-6.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details for nb_clean-6.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
nb_clean-6.0.0-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for nb_clean-6.0.0-py3-none-macosx_11_0_arm64.whl
nb_clean-6.0.0-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for nb_clean-6.0.0-py3-none-macosx_10_12_x86_64.whl

Total release size: 5.6 MB

Release files / nb_clean-6.0.0-py3-none-win_amd64.whl

Download URL nb_clean-6.0.0-py3-none-win_amd64.whl
Size 1.1 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
f761e9539c7bdd5321a368a29a64e7c9674fa10fffb96f39a47de07ecfb6db9a
BLAKE2b-256 checksum
How to use checksums
5425fbef6225b3fc17364479148b60ed7962bfff295b2b8830006aeefd7cbca1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Release files / nb_clean-6.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL nb_clean-6.0.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.2 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
088108b14dfc57df59e1fe0f9fcabf44bf402082fb7f4a399e9f8ea3acf0a59e
BLAKE2b-256 checksum
How to use checksums
bbf88c254499ac68d02d190f32fad87bdac3288f464dc89b83b23f4f5267b783
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Release files / nb_clean-6.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL nb_clean-6.0.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.1 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
60c34f6e29157f84b718cc1f905f9f7b07a88e0fab70726c96d27ef8b7523985
BLAKE2b-256 checksum
How to use checksums
6078e95165634bd8494be258e901bec3a878c98507394007deb99764157fa94c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Release files / nb_clean-6.0.0-py3-none-macosx_11_0_arm64.whl

Download URL nb_clean-6.0.0-py3-none-macosx_11_0_arm64.whl
Size 1.1 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
66539bfbd8597ecf9380cb1d40c42e4d6bb38becce680e23fdec367ee272a6b7
BLAKE2b-256 checksum
How to use checksums
2931b9dae5fe0c55f8eface6703d8f9b3db9627a218d05d10b805ac87f682012
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Release files / nb_clean-6.0.0-py3-none-macosx_10_12_x86_64.whl

Download URL nb_clean-6.0.0-py3-none-macosx_10_12_x86_64.whl
Size 1.1 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
a789d07b8a01b91f5dba9de5fbe5a97e56af0d3f9c3bcef593cd90fca5dc1dc2
BLAKE2b-256 checksum
How to use checksums
223bddf853fcb3028fa389279fc03f226177ba3882d7b38cd9d48dd2e714d4c9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Nov 2, 2026.

Transparency log

Security for nb-clean 6.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.

Select from 5 files

Attestation for nb_clean-6.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 Nov 2, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page