nbstrip
Fast Jupyter notebook output stripper and git clean filter, in Rust with only two
dependencies (serde, serde_json). Cell outputs, execution counts, and
transient UI metadata never reach git; your working tree keeps everything for
Jupyter. Diffs stay readable, repositories stay small, and megabytes of
embedded plotly figures stop hiding real changes.
Install
Wire a repository (once per clone)
This registers the binary as the repository's clean filter for *.ipynb
(filter.nbstrip.clean + filter.nbstrip.required in the repo's git config,
the attribute line in .git/info/attributes). Nothing needs committing. From
then on git add stages notebooks stripped, git diff/git status compare
through the filter, and the working tree keeps its outputs.
Because git config never travels with a clone — by design — every clone runs
nbstrip install once. A clone that skipped it strips nothing and warns
about nothing. Teams can commit *.ipynb filter=nbstrip to .gitattributes
so the routing travels with the repo; each clone still needs the one-time
nbstrip install to define the filter itself (it is idempotent, and
filter.nbstrip.required=true then makes an unwired clone fail the git add
loudly instead of silently committing outputs).
What gets stripped
- cell outputs — cleared
- execution counts — nulled (the key stays, as the nbformat schema requires)
- transient metadata — notebook-level
signature,widgets,vscode; cell-levelcollapsed,scrolled,execution,ExecuteTime,heading_collapsed,hidden
Sources, markdown cells, and authored metadata pass through untouched. Output
is byte-compatible with how nbformat writes files (1-space indent, sorted
keys, trailing newline preserved) and stripping is idempotent, so the filter
never churns.
Keeping an output deliberately: tag a cell keep_output (or set
keep_output: true in its metadata; notebook-level metadata keeps every cell).
An explicit keep_output: false beats a tag. This is the nbstripout
convention, so notebooks move between the two tools cleanly.
Other modes
In-place mode is handy when the local file should shrink too — e.g. after a heavy plotting session; re-running the notebook regenerates everything.
Development
The lint policy is strict (pedantic/nursery/cargo plus
unwrap_used/expect_used/panic); fix findings rather than allowing them.
Releases follow docs/crate_release_process.md
via scripts/release.sh.
License
Apache-2.0. Modeled on nbstripout and nbstripout-fast; reimplemented from scratch.