nbmirror
nbmirror builds static HTML mirror pages for Jupyter notebooks in repositories that use a simple structure:
index.htmlat repository root- notebooks under
notebooks/ - generated mirrors under
notebooks_html/
It is designed for static hosting such as GitHub Pages. It does not run a Python server, and it does not execute notebooks by default.
Why
Notebook links in static sites are awkward to maintain when you want rendered pages with rich outputs. nbmirror converts stored notebook outputs into browsable HTML pages that can be linked from your root index.html.
In the past I used nbviewer a for this purpose, but recently it very often gives 503 Error: Service Unavailable / GitHub API rate limit exceeded. Try Again Later.
Also, I prefer to have the possibility to hide the code of the notebooks, for a lean reading experience.
Expected repository layout
.
├─ index.html
├─ notebooks/
│ └─ ... .ipynb
└─ notebooks_html/
└─ ... .html (generated)
Features
- Maps notebook paths to stable mirror paths:
notebooks/eda.ipynb->notebooks_html/eda.htmlnotebooks/sales/q1.ipynb->notebooks_html/sales/q1.html
- Preserves markdown cells and stored outputs
- Keeps code hidden by default
- Adds per-cell code toggle controls with
aria-expanded - Adds Home buttons at top and bottom of each page
- Computes correct relative Home links back to root
index.html - Preserves rich outputs such as pandas HTML tables and Plotly output content
Installation
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS/Linux
# source .venv/bin/activate
pip install -e .
CLI usage
nbmirror build notebooks/nb_example.ipynb
nbmirror build-many notebooks/a.ipynb notebooks/sub/b.ipynb
nbmirror install-hook
Options (where relevant):
--repo-root(default:.)--notebooks-dir(default:notebooks)--output-dir(default:notebooks_html)--home-target(default:index.html)--verbose
Examples:
nbmirror build notebooks/sales/q1.ipynb --verbose
nbmirror build-many notebooks/a.ipynb notebooks/b.ipynb --output-dir notebooks_html
Plain Git hook installation
Install a pre-commit hook directly into .git/hooks/pre-commit:
nbmirror install-hook
Behavior:
- The hook rebuilds mirrors only for staged notebook paths.
- If generated mirror files are updated, the hook auto-stages
notebooks_html/changes and exits nonzero. - Re-run the same commit command once; the second attempt should pass with staged mirror updates included.
pre-commit framework integration
This repository ships .pre-commit-hooks.yaml with hook id nbmirror.
Example .pre-commit-config.yaml:
repos:
- repo: https://github.com/your-org/nbmirror
rev: v0.1.0
hooks:
- id: nbmirror
args: ["--repo-root", "."]
Note on generated files:
- Framework-managed hooks that modify files generally require re-stage/re-commit. That is expected.
Static hosting notes
Generated HTML pages are static files suitable for GitHub Pages and similar hosts.
Limitations and tradeoffs
- Notebooks are not executed. Only stored outputs are rendered.
- Deleted notebooks do not automatically remove stale mirror HTML files.
- Layout and toggle behavior are intentionally minimal to keep generated pages deterministic and maintainable.
Development
pytest
Metadata
Release files for nbmirror 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| nbmirror-0.1.0.tar.gz | 13.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nbmirror-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 24.2 kB
Release files / nbmirror-0.1.0.tar.gz
| Download URL | nbmirror-0.1.0.tar.gz |
|---|---|
| Size | 13.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
131fe514852b917ebe5a54ea04a294891fc5ec3e585232d6d75b33bcbbe8b4df
|
|
BLAKE2b-256 checksum How to use checksums |
8949700d78b383e20cdcedf67ba67a17a17499917a68143e9686ce2ce195a061
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Release files / nbmirror-0.1.0-py3-none-any.whl
| Download URL | nbmirror-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a184ae907069e5e528c3f0cb149232d300b5dcf27d8004a931483c0bc1f8afa6
|
|
BLAKE2b-256 checksum How to use checksums |
04fafd9d706cd2c17cdb91e06abd4559751ccb99c20ac2b8901b318ce8e9bef0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.2
|
Security for nbmirror 0.1.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.