It happened gradually, then all at once

I'm going to admit something that might get me in trouble with a few people: I used to love Jupyter Notebooks. They were the first thing I opened every morning for the better part of five years. Poke at a dataset, run a quick plot, train a model, all in one place.

None
Generated by AI

Then at some point last year, I just… stopped. I opened VS Code instead. Then I did it again the next day. And the day after that. It wasn't a conscious decision. The switch happened before I had words for why.

When I started paying attention to what other data scientists around me were doing, the same pattern kept showing up. Jupyter isn't dead. People still use it. But the automatic reach for it, that reflex of "new project, new notebook," is fading. And I think it's worth talking about why.

Project Jupyter came out of IPython back in 2014, and it solved something that genuinely needed solving. Data scientists needed a way to mix code, output, and explanation in a single document. The notebook metaphor clicked. You could hand someone an .ipynb file and they could follow your entire thought process, messy exploration and all.

For teaching, it was a game changer. Google built Colab around it. Netflix, Airbnb, and NASA wove notebooks into their workflows. Universities adopted them everywhere.

The problem with tools that become defaults is that people stop questioning whether they're still the right choice.

None of these complaints are new. But they stacked up over time until the workarounds started taking more effort than the work.

Version control just doesn't work well. Notebooks are JSON files underneath. Every time you run a cell, it updates metadata, output blobs, execution counters. Try reviewing a notebook diff in a pull request. It's a wall of noise. Tools like nbstripout and ReviewNB exist because the problem is so bad that people had to build entire products around fixing it.

Hidden state creates bugs you don't notice. Run cell 5, then cell 3, then cell 7. What are your variables doing now? Honestly, nobody knows. A 2019 study found that a large percentage of notebooks on GitHub couldn't reproduce their own outputs when run top-to-bottom. That's not a small deal.

Testing is awkward. You can technically write unit tests in a notebook. The experience is bad enough that almost nobody does. There's no natural place for a test suite, no clean way to plug into pytest or CI/CD, and the cell-based structure actively discourages the kind of modular code that makes testing possible in the first place.

Anything over a few hundred lines becomes unmanageable. Moving code into proper modules means leaving the notebook, which defeats the purpose of being in one.

Most data scientists will recognize this kind of thing:

# Cell 1: Load data
import pandas as pd
df = pd.read_csv("sales_data.csv")
# Cell 14: Feature engineering (added three weeks later)
df["revenue_per_unit"] = df["total_revenue"] / df["units_sold"]
# Cell 7: Model training (depends on cell 14, but was written first)
from sklearn.ensemble import RandomForestRegressor
model = RandomForestRegressor()
model.fit(df[features], df["target"])
# Cell 22: "Quick fix" that mutates df in place
df.dropna(inplace=True)  # Should this have run before cell 7? Who knows.

The tangled dependency graph isn't a bug in how people use notebooks. It's what the format encourages.

There's no single replacement. That's part of the point. Different workflows need different tools.

READ THE FULL ARTICLE HERE

📢 Important Update: I'm Moving My Content to a New Medium Channel

Due to some recent issues with the Partner Program, I'll be continuing my writing journey on a new space — and I'd love for you to join me there.