Jupyter to Markdown: 4 Fast Ways to Convert .ipynb to .md

Written by Alex Chen, Lead Data Systems Engineer β specializing in Jupyter toolchains, AST document parsers, and LLM data ingestion.
The fastest way to convert Jupyter to Markdown is the online Jupyter to Markdown converter β drag in your
.ipynb, no install needed. For automation or batch jobs, use the CLI:jupyter nbconvert --to markdown notebook.ipynb. Both preserve code cells and outputs cleanly.Why Convert a Jupyter Notebook to Markdown?
A
.ipynbfile is really a JSON blob under the hood β that's how Project Jupyter stores cells, metadata, and outputs together β which makes it clumsy for anything outside the notebook environment. Markdown, on the other hand, renders natively almost everywhere developers actually publish their work.You'll typically need this conversion when:
- Writing a GitHub README β notebooks don't render cleanly as project documentation, but a
.mdexport does.- Publishing technical blog posts on Hugo, Jekyll, Gatsby, or any static site generator that expects Markdown source files.
- Feeding docs into a wiki or knowledge base (Notion, Confluence, GitBook) that ingests Markdown but chokes on raw notebook JSON.
- Sharing analysis with non-technical stakeholders who just need to read the narrative and see the outputs, not open Jupyter.
- Compiling a finished report downstream β once your notebook is clean Markdown, it's a straightforward hop to a polished PDF or Word document; see our guide to converting Markdown to PDF, Word, and HTML for that leg of the pipeline.
- Working the pipeline in reverse β if your notebook started life as code pulled out of a research paper, our PDF to Markdown guide covers extracting that text and code before it ever reaches a notebook.
The good news: you've got five solid ways to do it, and none of them require deep Python expertise.
How to Convert / Export a Jupyter Notebook to Markdown (5 Methods)
Whether you're working on a single notebook or scripting a batch export, one of these five methods will fit your workflow.
Method 1: Instant Online Tool (Zero-Setup)
If you just need to export a Jupyter notebook to Markdown once β no CI pipeline, no repeated automation β skip the terminal entirely.
β‘ Fastest Method: Online Jupyter to Markdown Converter
Three steps, no terminal required:
- Upload your
.ipynbβ drag the file into the browser window, or click to select it.- Instant browser parsing β the tool reads the notebook's JSON structure client-side and converts code cells, outputs, and images on the spot.
- Download clean
.mdβ grab the finished Markdown file, ready to drop into a README, static site, or wiki.It works identically on Windows, macOS, or Linux β useful if you're on a locked-down work laptop where
pip installisn't an option.This is the method to reach for when a colleague sends you a notebook and asks "can you just get me the Markdown version," and you don't want to spin up a virtual environment for a thirty-second task.
Method 2: Command Line Using
nbconvertFor anyone converting notebooks regularly, jupyter nbconvert markdown is the standard tool. It ships with most Jupyter installations, and it's scriptable, which matters if you're generating docs as part of a build pipeline. Full flag reference lives in the official nbconvert documentation.
bash
# Install nbconvert (skip if it's already bundled with your Jupyter install) pip install nbconvert # Convert a single notebook to Markdown jupyter nbconvert --to markdown notebook.ipynb # Re-run every cell first, so the Markdown reflects fresh calculations rather than stale saved outputs jupyter nbconvert --to markdown --execute notebook.ipynb # Send the output to a specific folder instead of the notebook's directory jupyter nbconvert --to markdown notebook.ipynb --output-dir ./docs # Convert every notebook in a folder in one pass jupyter nbconvert --to markdown *.ipynbRunning this command creates
notebook.mdalongside a folder (usuallynotebook_files/) holding any extracted images. Keep that folder β more on why in the troubleshooting section below.Cleaning Up Output with a Custom Jinja Template
By default,
nbconvert's Markdown exporter is fairly clean, but if you're feeding the output into a documentation wiki, you may still want to strip execution-count prompts likeIn [1]:that survive from the notebook's cell metadata.nbconvertrenders every format through Jinja2 templates, and the Markdown exporter's base template lives atmarkdown/index.md.j2β you extend it rather than edit it in place.Create a small custom template:
jinja
{# templates/basic/index.md.j2 #} {% extends 'markdown/index.md.j2' %} {% block in_prompt %}{% endblock in_prompt %} {% block output_prompt %}{% endblock output_prompt %}Overriding
in_promptandoutput_promptwith empty blocks removes theIn [1]:/Out[1]:markers entirely, leaving just the code and its rendered output. Pointnbconvertat the folder containing it by name:bash
jupyter nbconvert --to markdown --template=basic notebook.ipynbNote that
basichere is the name of your template folder, not somethingnbconvertships out of the box β the built-in named templates (lab,classic,reveal) are for the HTML exporter. For Markdown output, you're always extending the basemarkdown/index.md.j2template yourself, which is exactly what makes this approach flexible: you decide what gets stripped.Method 3: JupyterLab / Classic Notebook UI
Already have the notebook open? You don't need the terminal at all.
- Open your notebook in JupyterLab or the classic Notebook interface.
- Go to File β Save and Export Notebook Asβ¦ (classic Notebook: File β Download as).
- Select Markdown (.md).
- The file downloads directly to your browser's default download folder.
It's slower than the CLI for bulk jobs, but it's convenient when you're already mid-session and just need one clean export.
Method 4: Inside VS Code
If your workflow lives in VS Code with the Jupyter extension installed, exporting takes two clicks.
- Open the
.ipynbfile in VS Code.- Click the Export icon in the notebook toolbar (or open the Command Palette with
Ctrl+Shift+P/Cmd+Shift+Pand search "Export").- Choose Markdown as the export format.
- VS Code writes the
.mdfile to the same directory, images included.This keeps you in one editor for the entire workflow β write code, run cells, export docs β without switching windows.
Method 5: Quarto CLI (Modern, Reproducible Workflows)
If you're working with computational notebooks in 2026, there's a good chance Quarto is already part of your stack β it's the open-source publishing system built on Pandoc that grew out of the R Markdown ecosystem and now handles Jupyter notebooks natively. It's worth reaching for when plain
nbconvertisn't enough: you need fresh output on every render, a custom template, or GitHub Flavored Markdown specifically (rather than nbconvert's default flavor).bash
# Render a notebook straight to GitHub Flavored Markdown quarto render analysis.ipynb --to gfm # Re-execute every code cell before rendering, so outputs are never stale quarto render analysis.ipynb --to gfm --execute # Apply a custom Pandoc template instead of Quarto's default quarto render analysis.ipynb --to gfm --template=basicThe
--executeflag matters more than it looks: without it, Quarto renders whatever outputs are already saved in the.ipynbfile, which is fine for a notebook you just ran, but stale if you're rendering an older file in a CI job. Full flag reference and format options are in the GFM output guide in Quarto's docs.Like
nbconvert, Quarto extracts figures and images into a sibling directory rather than inlining them β the naming convention just differs slightly. A renderedanalysis.ipynbproduces a tree like this:project/ βββ analysis.ipynb βββ analysis.md βββ analysis_files/ βββ figure-gfm/ βββ cell-3-output-1.png βββ cell-7-output-1.pngSame rule applies as with
nbconvert'snotebook_files/folder: moveanalysis.md, andanalysis_files/has to travel with it or every image reference breaks.Mastering Markdown Inside Jupyter Notebooks
Converting notebooks is only half the picture. Most developers also want to know how to Markdown in Jupyter Notebook cells themselves, so the narrative reads well before it's ever exported.
How to Create a Markdown Cell in Jupyter Notebook
There are two ways to add a Markdown cell, and the keyboard shortcut is worth memorizing if you write a lot of documentation inline.
- Keyboard shortcut: Click a cell to select it, press
Escto enter command mode, then pressM. The cell switches from Code to Markdown instantly.- Toolbar/GUI: Use the cell-type dropdown in the toolbar (it usually reads "Code" by default) and select Markdown from the list. In JupyterLab, you can also use the + Markdown button below any existing cell.
Press
Shift+Enterto render the cell once you're done editing it.Core Markdown Formatting Syntax
Standard Markdown syntax works inside Jupyter's Markdown cells:
markdown
# Header 1 ## Header 2 ### Header 3 **bold text** *italic text* > This is a blockquote β useful for callouts or quoted material. `inline code` β```python # fenced code block with syntax highlighting def hello(): print("Hello, notebook!") β``` | Column A | Column B | |----------|----------| | Value 1 | Value 2 |Tables and code fences render exactly the way you'd expect on GitHub, so there's no learning curve if you've written Markdown anywhere else.
How to Underline in Markdown Jupyter Notebook
Here's a gap that trips up a lot of people: standard Markdown has no native underline syntax. Asterisks give you bold and italics, but there's nothing built in for underlining.
The workaround is to drop into raw HTML, which Jupyter's Markdown renderer supports directly inside the same cell:
html
<u>This text is underlined</u> <ins>This also renders as underlined</ins>Both tags work.
<u>is the more common choice;<ins>carries slightly different semantic meaning (it signals "inserted text") but renders identically in the notebook.How to Add an Image to Jupyter Notebook Markdown
You've got three practical options here, depending on whether you need a quick embed or precise control over sizing.
1. Standard Markdown syntax (relative path):
markdown
This is the cleanest option and the one that survives export to Markdown or GitHub without modification.
2. HTML syntax for custom width or height:
html
<img src="images/plot.png" width="500"/>Reach for this when the default image size is too large for the surrounding text, or when you need consistent dimensions across multiple images in the same document.
3. Cell attachment (drag-and-drop):
Double-click a Markdown cell to enter edit mode, then drag an image file straight from your file explorer into the cell. Jupyter embeds it as a base64-encoded attachment inside the notebook's JSON β no separate image file to manage. It's convenient, but worth knowing: attached images bloat the
.ipynbfile size and can behave inconsistently once exported, since some converters don't unpack attachments the same way they handle linked files.Companion folder vs. inline data URI β which should you actually use? This comes up constantly once you're past a single example image. A companion folder (
notebook_files/,analysis_files/) keeps the Markdown source small and lets Git diff cleanly β you can see exactly which figure changed between commits, and the images are cacheable as separate HTTP requests if you're publishing to a static site. The trade-off is that the.mdfile is no longer self-contained; move it without the folder and every image breaks, which is precisely the failure mode covered below. Inline Base64 data URIs () solve the portability problem β one file, nothing to lose in transit β at the cost of a Markdown source that's borderline unreadable in a diff or a plain-text editor, and a file size that balloons fast with more than a couple of plots. As a rule of thumb: use companion folders for anything that lives in version control or gets published, and reserve inline Base64 for one-off exports you're pasting into a single Slack message or email where portability trumps everything else.Writing Math Equations
Jupyter renders LaTeX through MathJax, right inside Markdown cells:
markdown
Inline equation: $E = mc^2$ Display equation: $$ \int_{a}^{b} f(x) \, dx = F(b) - F(a) $$Single dollar signs render inline with the surrounding text; double dollar signs center the equation on its own line. This is standard for anyone documenting a data science or research notebook where the math itself is part of the explanation.
Common Pitfalls & Troubleshooting
Even a straightforward export can go sideways. Here's what usually breaks, and how to fix it.
Broken images after export. When
nbconvertpulls inline or attached images out of a notebook, it dumps them into a sibling folder β typicallynotebook_files/. If you move the.mdfile without that folder, every image link breaks. Keep the folder in the same relative location, or update the image paths manually after moving files.Raw cells vs. code cell formatting. Raw NBConvert cells pass through to the Markdown output completely unformatted β no code fences, no syntax highlighting. If a section of your export looks oddly plain compared to the rest, check whether that cell was set to "Raw" instead of "Code" in the original notebook.
The
nbconvert/ Pandoc dependency error. A common one: runningjupyter nbconvert --to markdownthrowsPandoc wasn't foundor a similarNoSuchFileerror, because some export paths lean on a separate Pandoc binary that pip doesn't install automatically. Fixing it means installing Pandoc system-wide (apt install pandoc,brew install pandoc, or the Windows installer) and making sure it's on yourPATHβ an extra dependency most people don't expect. The online converter sidesteps this entirely, since there's no local environment or missing binary to debug in the first place.Mixed-format documentation projects. Notebooks rarely exist in isolation β most teams are also converting PDFs, Word docs, or LaTeX files into the same documentation set. If that's your situation, it's worth knowing the free Markdown conversion tools suite handles this too: the platform hosts 16 specialized conversion tools for developers, covering HTML, PDF, DOCX, and LaTeX to Markdown, so you're not juggling five different tools for one documentation pipeline.
Method Comparison: Which Should You Use?
Method Speed Installation Required Ideal Use Case Online Tool (MD-Convert) Instant None One-off conversions, no dev environment, locked-down machines CLI ( nbconvert)Fast (seconds) Python + pip install nbconvertAutomation, batch conversion, CI/CD pipelines JupyterLab / Notebook UI Fast Already bundled with Jupyter Exporting while already working in the notebook VS Code Extension Fast VS Code + Jupyter extension Developers who live in VS Code all day Quarto CLI Fast (seconds) Quarto install Reproducible pipelines, fresh output on every run, custom templates Frequently Asked Questions
How do I convert .ipynb to .md without installing Python?
Use an online Jupyter to Markdown converter β upload the
.ipynbfile in your browser and download the converted Markdown directly. No Python environment, nopip install, and it works the same across Windows, macOS, and Linux.How do you underline text in Jupyter Markdown?
Standard Markdown doesn't support underlining, so you need raw HTML inside the Markdown cell:
<u>your text</u>or<ins>your text</ins>. Both tags render as underlined text once the cell is executed.Why are my images broken after exporting to Markdown?
nbconvertextracts images into a separate folder (commonlynotebook_files/) alongside the.mdfile. If that folder gets left behind or moved separately from the Markdown file, every image reference breaks. Always move the folder and the.mdfile together.How do I switch a code cell to a Markdown cell quickly?
Select the cell, press
Escto enter command mode, then pressM. The cell type switches from Code to Markdown immediately, and you can start typing standard Markdown syntax right away.Do I need nbconvert if I just want a quick one-time conversion?
No β installing
nbconvertonly makes sense if you're converting notebooks repeatedly or scripting the process. For a single file, the online converter does the job in seconds without any setup.