Back to guides
By Khalid DanishyarAbout 6 min read

How to read a notebook when Jupyter is not installed

Reading a notebook is parsing JSON and showing saved cells. It does not require a kernel. When to use a text editor, when to use a viewer, and what not to run.

Updated

You can read a Jupyter notebook without installing Jupyter, without starting a kernel, and without trusting the file enough to execute it. The notebook is JSON plus a set of conventions for cells and outputs. Anything that can show you those cells is a reader. Execution is optional and, for a file you just downloaded, often a bad idea.

This guide is about reading. It is not about reproducing someone’s environment, training a model, or turning the notebook into a PDF. If you need a file to hand to someone else, use the comparison in what exports keep and drop after you have seen the cells. If you want a file you are allowed to experiment on, use the public sample notebook. It has no secrets and one boring output, so you can learn the interface without putting your own data in first.

What “open” should mean

When someone says a notebook will not open, they usually mean one of three different failures:

  1. The operating system has no program associated with .ipynb, so a double-click does nothing useful or opens a text editor full of braces.
  2. The JSON is invalid, so a notebook UI refuses the file before it draws cells.
  3. The JSON is valid, but running a cell fails because a package or a data file is missing.

Only the third one requires Python. The first is a file-association problem. The second is a damaged file. A reader solves the first problem. A JSON parser tells you whether you are in the second. Installing Anaconda does not fix a truncated download.

You do not need a kernel to answer: What are the headings? What code is in this cell? What did a previous run print? Is there an error traceback stored in the file? Those answers are in cells.

Reading the JSON yourself

This is the most reliable method, and the least comfortable.

  1. Download the notebook. For practice, download the sample.
  2. Open it in any editor that can handle a few hundred kilobytes of text. If your real file is 50 MB, the editor may struggle because images are stored as base64 text. That size is itself information: the notebook is heavy with outputs, not with source.
  3. Find "cells". Each element has cell_type and source.
  4. For a Markdown cell, read source. Headings start with #.
  5. For a code cell, read source for the program and outputs for the recording. A stream output’s text is what was printed. An error output’s ename and evalue are the exception. An image output is a long base64 string you will not read by eye. Note that it exists.

You will not see syntax highlighting. You will not accidentally run code. You can search for api_key, password, BEGIN PRIVATE, or a customer name before you do anything else. That search is harder in a rendered UI that hides output behind a scroll, and it is impossible in a JPEG of the notebook.

When you are done, you know the structure. You still may want a rendered view for prose and for figures. The text pass is how you know the rendered view is not hiding a cell.

A viewer that does not execute

A notebook viewer parses nbformat and draws Markdown, code, and stored outputs. A good one tells you it is showing saved outputs rather than a live kernel. It does not need the packages imported by the code, because it is not importing them.

Use a viewer when:

  • You are on a phone, a locked-down work laptop, or a computer where you cannot install Python.
  • You want to skim a notebook someone sent before you decide to run it.
  • You want to confirm a cleaned file still has its Markdown and code after outputs were stripped.

What you should check in the viewer, using the sample notebook as the test:

  • The title “Sample notebook” is a heading, not a single line of JSON.
  • The bullet list in the second cell is a list.
  • The code is monospace and includes print(2 + 2).
  • Under the code, the text Jupy Tools sample and 4 appear as output.
  • You were not asked to pick a kernel in order to see those lines.

If the sample fails that test, the viewer is not rendering this notebook. If your own file fails, compare it with the sample. A file that is not JSON will fail. A file whose code cells were never run will show code and empty output, which is correct, not a broken viewer.

A viewer will not make a widget interactive. It may show the widget’s saved view or a gap. It will not fetch data files the code expected to find on the author’s disk. If a Markdown cell says “see the CSV in the same folder,” the viewer cannot invent the CSV.

When a text editor is the better tool

Prefer the editor over a viewer when the notebook is huge, when you suspect a secret, or when the viewer shows an error and you need the line number from the JSON parser. A parser error like “unexpected end of input” means the file was cut off. No theme or extension fixes that. You need the rest of the bytes, or a repair attempt that understands notebooks, and you should keep a copy of the broken file before any rewrite.

Prefer the viewer when you need figures and formatted prose and you have already decided the file is safe to render. Rendering is not the same as executing, but HTML outputs can contain markup. A careful viewer treats notebook HTML as content to display, not as a place to run surprise scripts. If you do not trust the sender, the text editor is the conservative choice: you see the strings, and you do not hand them to an HTML renderer.

What you still cannot learn from reading

Reading shows the recording. It does not show:

  • Whether the code runs today on a current Python.
  • Whether the numbers would change if the cell were run again.
  • Data that was never printed or embedded.
  • Why a package import would fail, except when a stored traceback already says why.

If the stored traceback is the thing you needed, you have it without a kernel. If you need a new result, you need an environment, and that is a different task from reading. Do not install a stack of packages just to see a heading.

A safe order for a file you did not write

  1. Do not double-click and “run all.”
  2. Search the raw file for secrets and for data you should not possess.
  3. Open it in a viewer or read the JSON until you know the cell types.
  4. Only then decide whether execution is justified, and do that in an environment you control, with data files you meant to provide.

For a file you wrote and already trust, the same order is how you check it before you send it. The cleaning guide is that check. The sample notebook is the file you can practice on without a privacy decision, because it was written to be public and it does not print anything you would regret.

Local Jupyter is still fine

Nothing here says you should avoid Jupyter when you have it and you mean to run code. Jupyter is a better executor than a viewer, because that is what it is for. It is a worse choice as the only way to glance at a file on a computer where you will not install it, and it is a risky choice as the way to open an untrusted attachment. Use the tool that matches the job. Reading is parsing and display. Running is a kernel. They are separate, and the file format is what makes the separation possible.

If you later need a copy someone can read without any notebook tool at all, export after you have read the cells and decided which outputs belong in that copy. Exporting a file you have not looked at is how stale outputs and stray tokens leave your machine. Look first. The sample is here so the first file you practice on is not a client notebook.