From IPython to JupyterLab
The lineage begins with IPython, Fernando Pérez's 2001 interactive Python shell, which added persistent history, inline graphics and a richer REPL to a language that Guido van Rossum had kept deliberately simple. When the browser-based notebook interface arrived in 2011, it introduced a document model built around cells — discrete, independently executable units of code, prose and output — that had no precedent in the classical IDE or in the terminal REPL.
Project Jupyter, spun out of IPython in 2014 as a language-agnostic initiative, formalised the .ipynb format: a JSON document storing code, outputs and metadata together. Each notebook connected to a kernel — a separate process running the language runtime — over a ZeroMQ messaging protocol, keeping the UI and the computation cleanly separated. That architecture is why the same JupyterLab front end can host Python, R, Julia or dozens of other languages without modification.

JupyterLab 1.0, released in 2019, moved decisively past the notebook metaphor. A left-hand file browser, a drag-and-drop tab system, an embedded terminal, a CSV viewer, a plain text editor and the notebook pane coexist in a single browser window. The result resembles a classical IDE in layout while retaining the cell-and-output document as its primary artefact rather than a source file that must be compiled away.
The notebook paradigm changed reproducibility expectations in data work. Because code, narrative and output live in one file, a notebook is simultaneously the program and its documentation — a quality Knuth's literate programming anticipated but never delivered at this scale or accessibility. The cell execution order remains a persistent source of confusion (running cells out of sequence produces different results than running them top-to-bottom), a tension the IDE conventions of linear build pipelines do not share. JupyterLab, backed by Project Jupyter under NumFOCUS, remains the dominant environment for exploratory data work and scientific computing.
