IPYNB to HTML Converter
Turn a .ipynb file into a single web page anyone can open in a browser, with no Jupyter and no internet. Charts, tables and maths are inside the file, and it carries no scripts. Nothing is uploaded.
Open a Jupyter notebook
Drop a .ipynb file here, choose one or paste it. No Jupyter, no install, no upload.
One .html file with the styles, pictures and maths inside and no scripts. It opens offline and follows the reader’s light or dark setting.
Bike rides and rain: a short walkthrough
A week of made-up numbers from a small town's bike-share scheme. It shows what a notebook can hold: Markdown, code, a table, a chart, maths, a warning and, at the end, an error.
import pandas as pd
import matplotlib.pyplot as pltrides = pd.DataFrame({
"day": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
"trips": [412, 438, 395, 451, 288, 230],
"rain_mm": [0.0, 1.2, 4.5, 0.0, 9.8, 14.1],
}).set_index("day")
rides| trips | rain_mm | |
|---|---|---|
| day | ||
| Mon | 412 | 0.0 |
| Tue | 438 | 1.2 |
| Wed | 395 | 4.5 |
| Thu | 451 | 0.0 |
| Fri | 288 | 9.8 |
| Sat | 230 | 14.1 |
How busy was the week?
The mean number of trips per day is
where is the number of days and is the number of trips on day .
mean = rides["trips"].mean()
print(f"Mean trips per day: {mean:.1f}")
print(f"Busiest day: {rides['trips'].idxmax()}")Mean trips per day: 369.0 Busiest day: Thu
import warnings
if rides["rain_mm"].max() > 10:
warnings.warn("Saturday had over 10 mm of rain; the gauge reads high in storms.")/tmp/ipykernel_4120/2715331896.py:4: UserWarning: Saturday had over 10 mm of rain; the gauge reads high in storms.
warnings.warn("Saturday had over 10 mm of rain; the gauge reads high in storms.")
Rain and riding
Fewer people rode on wet days. Pearson’s correlation coefficient measures how closely two columns move together, from −1 to 1:
fig, ax = plt.subplots(figsize=(6.4, 3.6))
ax.bar(rides.index, rides["trips"], color="#4878d0")
ax.set_ylabel("Trips")
ax.set_title("Bike-share trips per day")
plt.show()round(rides["trips"].corr(rides["rain_mm"]), 3)-0.979
A day that isn’t there
There is no Sunday in the data, so asking for it raises a KeyError. This is what a traceback looks like:
rides.loc["Sun"]KeyError: 'Sun'
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[7], line 1 ----> 1 rides.loc["Sun"] File ~/.venv/lib/python3.12/site-packages/pandas/core/indexes/base.py:3812, in Index.get_loc(self, key) 3810 return self._engine.get_loc(casted_key) 3811 except KeyError as err: -> 3812 raise KeyError(key) from err KeyError: 'Sun'
What next
- Load a week of rides
- Chart them
- Add the weekend’s weather from the town’s own gauge
Made-up data, made for this example. Any resemblance to a real town is a coincidence.
Your notebook is read on this device and never uploaded. Check it yourself
How this works: Method, 6 sources, Checked against 1 worked example,
How this works
Method
The .ipynb file is read in the browser as the nbformat JSON it is: every cell, its last outputs and its attachments. Markdown is drawn with GitHub Flavored Markdown and maths with KaTeX, code is coloured by the notebook’s language, and each output shows its richest format, as JupyterLab chooses. All HTML from the notebook is sanitised first and nothing from other sites is loaded. PDF comes from the browser’s print engine; HTML, script and Markdown files are written in the page.
Sources
How it’s tested
One worked example for this page is checked by automated tests before every release: given the inputs, the tool must show the expected answer.
Privacy
On your device. Nothing you enter or open leaves this browser. About privacy labels
Changes
- First published: open a .ipynb file with its outputs, maths and colours, and save it as PDF, HTML, a script or Markdown.
One file that opens anywhere
An HTML copy is the easiest way to share a notebook with someone who doesn’t use Jupyter. They double-click it and it opens in their browser, with the charts, tables and formatted text exactly as you saw them, and they can read it on a phone.
The file this page makes needs nothing from the internet. Its styles are written inside it, its pictures are embedded as data, and its equations are MathML, the maths markup browsers draw on their own, so there is no stylesheet or font to download. jupyter nbconvert --to html, by contrast, points to MathJax on a CDN by default to draw equations, so maths in its files needs a connection the first time it opens.
It also carries no JavaScript. Notebooks can contain HTML written by anyone, so every piece is cleaned of scripts and event handlers first, and the file declares a content security policy that forbids scripts outright. That matters if you are passing on a notebook someone else wrote: the copy can’t run code on whoever opens it.
Interactive outputs, such as widgets or a Plotly chart, are programs rather than pictures, so they appear as a short note, or as the still image the notebook saved with them. Pictures linked from other sites keep their address, so they load when the reader is online.
Good to know
- nbconvert’s HTML export loads MathJax from a content delivery network by default to draw equations; the address is its mathjax_url setting. Source: nbconvert documentation: Configuration options
- MathML, the web’s markup for maths, is drawn natively by Chrome and Edge since version 109 (2023) and by Firefox and Safari, so equations need no script. Source: MDN Web Docs: MathML
How to convert a Jupyter notebook to HTML3 steps, all on your device
- Open the notebook. Drop the .ipynb file on the card or choose it from your device.
- Choose code or outputs only. Keep the code for a technical reader, or choose Outputs only to send results to someone who doesn’t need it.
- Save the HTML file. Press Save HTML. You get one .html file that opens in any browser, offline, and follows the reader’s light or dark setting.
Frequently Asked Questions
Will the HTML file work offline?
Yes. Styles, pictures and equations are all inside the one file, so it opens with no connection. Only pictures the notebook linked from other websites need the internet.
Is it safe to send someone the HTML?
The file has no scripts: HTML from the notebook is cleaned of them, and a content security policy in the file blocks any script from running. It is a document, not a program.
Can I put it on a website?
Yes. It is a normal HTML page with its CSS inside, so you can upload it to any static host, attach it to an email or add it to a course page.
Does it look the same as in Jupyter?
Close to it: code is coloured, outputs keep their In and Out numbers, and pandas tables are styled. It follows the reader’s light or dark mode.
“Jupyter” is a trademark of Project Jupyter, used here only to say which files this viewer opens. Binary Decimal is not affiliated with or endorsed by Project Jupyter.