Jupytext
Jupyter ecosystem · open source

Your notebooks,
as plain text.

Jupytext saves Jupyter notebooks as .py or .md files — easy to edit in any IDE, friendly to version control, and trivial for AI assistants to read and refactor.

Script formats
Markdown formats
Jupyter
# %% [markdown]
# # Quarterly Sales
# A look at Q4 revenue by region.

# %%
import pandas as pd
df = pd.read_csv("sales.csv")

# %%
df.groupby("region")["revenue"].sum().plot.bar()

Explicit # %% cell markers — understood by VS Code, PyCharm, Spyder, supported in 30+ languages.

Quarterly Sales

A look at Q4 revenue by region.

[1]:
import pandas as pd
df = pd.read_csv("sales.csv")
[2]:
df.groupby("region")["revenue"].sum().plot.bar()
NorthSouthEastWest

Text notebooks render exactly the same in Jupyter. Outputs are not saved — pair with an .ipynb to keep them.

What Jupytext enables

Get more done with text notebooks

</>

Edit anywhere

Open notebooks in VS Code, PyCharm, Vim — any editor, with full language tooling.

Ready for AI

Coding agents read and edit the clean text form — so AI can refactor, explain and extend your notebooks.

PR

Review like code

No outputs, no base64 blobs — just clean diffs your team can actually review in a pull request.

Raise the quality bar

One pre-commit hook — ruff check and ruff format — and every notebook commit meets the same standard as your production code.

Getting started

Create your first text notebook

$pip install jupytext

Then restart your Jupyter server to activate the extension.

+

New text notebook

In JupyterLab, use File → New Text Notebook to start fresh with a .py or .md file — or ask your AI assistant to write one.

Open as a notebook

Right-click any .py, .md, or .qmd file in the JupyterLab file browser and choose Open With → Notebook.

!

Auto-reload isn't universal. In Jupyter, use File → Reload Notebook from Disk to pick up changes made to the .py file in another editor.

Paired notebooks

Best of both worlds

Text notebooks don't store outputs. Pair them with an .ipynb and Jupytext keeps both in sync on every save — commit the text, keep the outputs. The text file always has precedence, and Jupytext raises an error if the .ipynb was modified outside of Jupyter.

Menu

In JupyterLab open the .ipynb notebook, then use:

File → Jupytext → Pair Notebook with percent Script

or

File → Jupytext → Pair Notebook with MyST Markdown

And if you opened the text notebook as a notebook, the same menu lets you pair it with an .ipynb. No terminal needed.

jupytext.toml

Drop a config file at your project root to pair all notebooks at once:

# jupytext.toml
formats = "ipynb,py:percent"

or

# jupytext.toml
formats = "ipynb,md:myst"

pyproject.toml

Or add a [tool.jupytext] section to your existing config:

[tool.jupytext]
formats = "ipynb,py:percent"

or

[tool.jupytext]
formats = "ipynb,md:myst"
Keeping in sync

Syncs wherever you work

Pair a text notebook with an .ipynb and Jupytext keeps both in sync automatically.

In Jupyter

Sync happens automatically on save — both files are written together. On load, inputs come from the text file, outputs from the .ipynb.

VS Code

The Jupytext-Sync extension by Victor Negîrneac syncs both files whenever either one is saved — no terminal needed.

pre-commit

Wire jupytext --sync into a pre-commit hook to keep pairs in sync on every commit.

New superpower

Notebooks your AI assistant can actually work with

AI assistants are right at home with scripts and Markdown files. As a text notebook is just that, they read, edit and refactor it as fluently as any other source file — no JSON wrangling, no special tooling.

  • Ask an agent to refactor a cell — it edits the .py file, you reload in Jupyter.
  • Outputs stay safe in the paired .ipynb while the text gets edited.
  • Easily 1,000x more concise than .ipynb — so your AI grasps not just one notebook, but your whole collection at once.
Edit with AI
analysis.py
# %% [markdown]
# ### Refactor: vectorize the loop 🤖

- totals = []
- for r in regions:
-     totals.append(df[df.region==r].sales.sum())
+ totals = df.groupby("region").sales.sum()
7.2k
GitHub stars
3.3M
Downloads / month
30+
Languages supported
100+
Contributors
MIT
Open source

Keeping in touch

Jupytext was created by Marc Wouts. Follow Marc on LinkedIn for updates on Jupytext, his other open-source projects, and the occasional random topic.

Jupytext is completely free and open source under the MIT license. What keeps us going is the excitement of learning through interactions with users and experts, and the satisfaction of sharing solutions with the community.

Have a question, a bug report, or an idea? Join us on Discord, or open an issue or start a discussion on GitHub.