How to convert a Jupyter notebook to PDF

There are five routes from .ipynb to PDF. They differ mostly in what you have to install first, and in how badly they fail when something is missing.

1. Use an online converter

The fastest route if you do not want to install anything. Drop the file on the converter on the home page, check the preview, and save. The notebook is parsed by JavaScript in your own browser, so nothing is uploaded and no TeX distribution is involved.

Worth knowing: the final PDF is written by your browser’s print engine, so you pick Save as PDF as the destination in the print dialog. The upside is that the text stays selectable and searchable instead of being flattened into a picture.

2. Jupyter’s own menu

In JupyterLab: File → Save and Export Notebook As → PDF. In classic Notebook: File → Download as → PDF via LaTeX.

This calls nbconvert behind the scenes, which calls LaTeX. On a fresh machine it usually fails, because a full TeX distribution is roughly a 2 GB install that Jupyter does not ship with. If you got here after seeing 500 : Internal Server Error or nbconvert failed: xelatex not found, that is why — see fixing nbconvert PDF errors.

3. nbconvert on the command line

The classic LaTeX route:

jupyter nbconvert --to pdf notebook.ipynb

Requires nbconvert, Pandoc, and XeLaTeX. It produces genuinely beautiful, typeset output — the best of any option here — and it is the right choice for a thesis or a paper. It is the wrong choice when you just need to hand a notebook to someone this afternoon.

4. nbconvert’s webpdf exporter

Same tool, no LaTeX — it drives a headless Chromium instead:

pip install "nbconvert[webpdf]"
jupyter nbconvert --to webpdf --allow-chromium-download notebook.ipynb

This is the most reliable command-line option and the one to reach for when the LaTeX route keeps failing. It downloads a browser on first use, so the first run is slow and needs network access.

5. VS Code

VS Code can open .ipynb files natively, but its export menu also leans on nbconvert, so it inherits the same LaTeX dependency. The workaround that always works is Export → HTML, then open the HTML file in a browser and print it to PDF.

Which one should you use

Getting a clean-looking PDF

Whichever route you take, a few things make the result read better. Restart the kernel and run all cells before exporting, so the numbering is consistent and no stale output sneaks in. Clear any cell that dumps hundreds of rows — a truncated head() reads far better on paper. And if the audience does not need the implementation, hide the code cells entirely: the converter has a toggle for that, and the result reads like a report rather than a transcript.