## The Problem
I've been running a static blog with Astro for a while. The writing experience was... not great. My workflow looked like this:
- Open VS Code
- Create a new markdown file
- Copy frontmatter from another post because I can never remember the format
- Write the post
- Realize I messed up the date format
- Fix it
- Drag image into the folder, figure out the relative path
- Commit and push
Not the end of the world, but enough friction that I kept procrastinating on writing.
I tried Keystatic as a headless CMS. Spent a weekend configuring it, and honestly it felt like overkill. The UI was clunky and I still had to deal with a bunch of config files.
So I did what any reasonable developer would do - I spent way more time building my own solution.
## What I Built
A web-based editor that connects to your GitHub repo directly. You login with GitHub OAuth, pick your blog repo, and start writing. Posts save as regular markdown files, so you're not locked into anything.
Here's what it looks like:
The core features:
Just write - A clean BlockNote-based editor with live preview. No distractions.
Images that just work - Drag an image into the editor, it uploads to your repo and inserts the markdown. Also auto-optimizes images so you don't accidentally commit a 5MB photo.
Frontmatter without the YAML headaches - Fill out a form for title, description, date, tags. It generates the frontmatter for you.
Draft recovery - This one saved me multiple times. The editor auto-saves to localStorage every few seconds. Accidentally close the tab? Your draft is still there when you come back.
Dark mode - Because of course.
## Tech Stack
I wanted to keep it simple:
Backend: FastAPI (Python)
- GitHub OAuth flow
- PyGithub for repo interactions
- Pillow for image processing
Frontend: Next.js 14
- App Router
- shadcn/ui for components
- TailwindCSS
- Zustand for state
- React Query for data fetching
The frontend proxies API requests to the backend, so in production you can deploy them separately (I use Vercel + Railway).
## How It Works
The flow is pretty straightforward:
- User logs in with GitHub OAuth
- Backend stores the access token in session
- User selects which repo contains their blog
- Frontend fetches the list of markdown files from the repo
- When editing, we parse the frontmatter and content separately
- On save, we commit directly to the repo via GitHub API
The "database" is literally just your GitHub repo. No extra infrastructure needed.
## Self-Hosting
If you want to run your own instance:
bash
# Backend
cd blog-editor-api
pip install -r requirements.txt
# Set up .env with your GitHub OAuth credentials
uvicorn app.main:app --reload --port 8000
# Frontend
cd blog-editor-web
npm install
npm run dev
You'll need to create a GitHub OAuth app and configure the callback URL. Full instructions in the repo README.
Try It
- Live demo: https://editor.deploy.re
- Source code: https://github.com/DanielHallx/static-blog-editor
It works with any static site generator that uses markdown files - Astro, Hugo, Jekyll, Eleventy, Gatsby, etc.
---
This started as a tool for myself but figured others might find it useful. If you have feedback or feature ideas, let me know in the comments or open an issue on GitHub.
And yes, I wrote this post using the editor itself.

Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.