← Back to blog

Notion as a git-backed CMS

How we publish this blog from Notion without giving up Git as the source of truth — a one-way sync, ~250 lines of TypeScript, and no new services.

· Updated

Every blog eventually hits the question: where should the content live?

The usual answers cluster into three camps:

For this blog we wanted the editor experience of the middle option and the durability of the first. We already live in Notion for planning docs, so the cheap answer was obvious: treat Notion as the editing surface, but keep MDX in the repo as the source of truth.

The shape

manual dispatch

pageToMarkdown + frontmatter

dispatch force=landing

Author writes in Notion

Notion DB

Notion Sync workflow

MDX files in repo

git commit to main

Deploy workflow

Vercel build + deploy

One-way sync. Notion to repo, never the other direction. Edits made directly to the MDX files get overwritten on the next sync — the repo is the artifact, not the editing surface.

What the sync does

The script is under 300 lines of TypeScript, and the moving pieces are modest:

No headless CMS, no new infra, no monthly bill. The only thing Notion contributes is the editor.

Trade-offs

The main one: hourly-at-best freshness. A Notion-triggered webhook is not a thing you can rely on for database updates, so we poll. In practice this is fine — blog posts are not Slack messages; a five-minute delay from “Status = Ready” to “live on the site” is irrelevant.

Second: images live in the repo. For a small blog this is fine; for a media-heavy one it would bloat the repo and should move to object storage. Easy to change later — the script’s image-download step is one function.

Third: round-tripping is one-way. If you prefer editing MDX in VS Code sometimes and in Notion other times, you’d want a bidirectional sync, which is a different beast. For a single author who picked Notion as the editor, the one-way model is simpler and safer.

When this makes sense

Teams already using Notion for docs. Single authors who want a browser-based editor but also want to keep their content and their deploy pipeline close to the code. Anyone who has rejected the operational cost of a headless CMS but still wants to write from a phone.

A thousand lines of infra you don’t need is a thousand lines of infra you don’t have to maintain.