Substack to clean Markdown.

Bulk-export Substack posts as Obsidian-friendly Markdown using your authenticated browser session — no passwords, no copy-paste.

Substack does not let you bulk-export your reading list or subscriptions in any useful format. substack2md uses your logged-in browser via the Chrome DevTools Protocol to convert posts to clean Markdown with YAML frontmatter, image-and-embed-as-link rewriting, and [[YYYY-MM-DD-slug]] wikilinks for Obsidian.

substack2md banner: Substack posts converted to Obsidian-friendly Markdown with frontmatter and wikilinks

What it does

Run substack2md against a single post URL or a text file of URLs. It opens a Chrome tab against your local browser, reads the rendered post HTML, and writes Markdown to disk organized by publication. Your Substack session cookie never leaves your machine, and no Substack credentials are ever handled by the tool.

Browser-session auth

Uses your existing Chrome via the Chrome DevTools Protocol. No passwords stored, no Substack credentials handled by the tool.

Obsidian-friendly output

YAML frontmatter, [[YYYY-MM-DD-slug]] wikilinks for cross-references, images and embeds rewritten as plain links so your vault stays portable.

Polite and configurable

Sequential requests with configurable sleep, publication-slug-to-folder mapping, transcript cleaning, and optional paywall tagging via Substack's public API.

Designed for

You want tosubstack2md does
Archive your own newsletterWalks your archive page, exports every post with paywall status preserved.
Read newsletters offline in ObsidianOutputs Markdown with frontmatter and wikilinks ready to drop into a vault.
Build a personal corpus for search or LLM contextPlain Markdown, one file per post, structured filenames you can grep.
Stop accidentally sharing paid contentOptional paywall detection tags posts as free or subscriber-only in frontmatter.

Install

Requires Python 3.10+ and a Chrome / Chromium browser. Start Chrome with the remote debugging port, log in to Substack, then run substack2md.

Install

git clone https://github.com/snapsynapse/substack2md.git
cd substack2md
pip install .

Start Chrome with CDP

# macOS
./launch-browser.sh

# or manually
chrome --remote-debugging-port=9222 \
       --user-data-dir=/tmp/substack2md

Convert a single post

substack2md https://example.substack.com/p/some-post

Batch from a URL list

substack2md urls.txt
# one URL per line, blank lines and # comments OK

See urls.txt.example in the repo for the expected format.

AI-assisted install

substack2md ships a GuideCheck human-verifiable assistant guide (profile 0.3.0) that currently verifies at Level 3, so an AI assistant can install and run it locally under explicit human approval. Verify the guide with a conformant verifier before letting the assistant execute any [action] block.

Output shape

Each post becomes a single Markdown file with YAML frontmatter Obsidian and most static-site generators can read directly.

--- title: The case for boring infrastructure author: A. Writer publication: example url: https://example.substack.com/p/boring-infrastructure date: 2025-09-14 access: free tags: [substack, infrastructure] --- # The case for boring infrastructure Most outages are not exotic. They are the same five mistakes, made in slightly different orders. See also: [[2025-08-02-the-five-mistakes]].