Migrate Your WordPress Site to GitHub
WordPress has a version history problem. More accurately, WordPress barely has version history at all.
The WordPress editor tracks “revisions” for post content — a list of previous versions you can browse and restore. But that is the extent of it. Theme changes, plugin configurations, widget settings, menu updates, custom CSS, header images, site options: none of these are versioned. If a plugin update breaks your site at 2am, your recovery options are “restore from a full database backup” (if you have one that is recent enough) or “figure out which of the 47 changed things caused the problem.”
When your website lives in a GitHub repository, every change to every file is tracked permanently. You get branching, pull requests, deploy previews, instant rollbacks, and collaboration tools that WordPress cannot match. This guide explains what that workflow looks like in practice and how to get there.
Git-based web development: the actual workflow
Before talking about migration, it is worth understanding what day-to-day life looks like when your website is a GitHub repo. This is not theoretical — it is how a growing number of teams manage their websites.
Making a content edit
Say you need to update the pricing on your services page. Here is the workflow:
# Open the file
code src/content/pages/services.md
# Make your edit (or tell an AI agent: "update the pricing table")
# Commit the change
git add src/content/pages/services.md
git commit -m "Update services pricing for Q2 2026"
# Push to GitHub
git push origin main
Within 30-60 seconds of that push, your hosting platform (Cloudflare Pages, Vercel, Netlify) automatically builds and deploys the updated site. No FTP. No “Publish” button. No logging into a CMS.
For non-developers, the same edit can happen through GitHub’s web interface — click the file, click “Edit,” make changes, click “Commit.” Or use a Git-backed CMS like Decap CMS or Tina CMS that provides a visual editing experience.
Experimenting with a redesign
This is where Git truly outshines WordPress. Say you want to redesign your homepage but are not sure if the new design is better:
# Create a branch — your live site is untouched
git checkout -b redesign-homepage
# Make changes (or ask an AI agent to redesign the page)
# ...
# Push the branch
git push origin redesign-homepage
When you push a branch, most hosting platforms automatically create a deploy preview — a live URL where you can see the redesigned homepage running on the actual site, with real content, on a real domain like redesign-homepage--your-site.pages.dev.
Share that preview URL with your team. Get feedback. Make more changes. When everyone is happy:
# Open a pull request on GitHub
gh pr create --title "Redesign homepage" --body "New hero section, updated testimonials"
# After review and approval, merge
gh pr merge
The moment the pull request merges into main, the production site updates. If something goes wrong:
# Revert the merge commit — site returns to previous state instantly
git revert HEAD
git push origin main
Try doing any of that with WordPress. You cannot branch a WordPress site. You cannot preview changes on a separate URL without setting up an entirely separate staging environment (which most WordPress hosts charge extra for). You cannot revert a set of changes atomically. You cannot get a diff of what changed between two versions of your site.
Collaborating across a team
With a GitHub-based site, collaboration looks like this:
- A developer creates a branch, makes changes, opens a pull request. Other team members review the code diff, leave comments, request changes, and approve.
- A content writer edits a markdown file through GitHub’s web UI or a Git-backed CMS. Their change shows up as a pull request that can be reviewed before merging.
- An AI coding agent (Claude Code, Cursor) opens a pull request with proposed changes. A human reviews the diff and merges or requests revisions.
- An external contributor forks the repo, makes changes, and submits a pull request. You review and accept or decline.
Every change has an author, a timestamp, a description, and a diff showing exactly what changed. The entire history of your website is browsable, searchable, and permanent.
Compare that to WordPress’s collaboration model: create wp-admin accounts, assign roles (Administrator, Editor, Author), and hope that nobody breaks anything. There is no review step. There is no diff. There is no way to see what changed across the entire site between last Tuesday and today.
Rollbacks and disaster recovery
WordPress rollback options:
- Restore a database backup (lose everything that changed since the backup)
- Manually undo changes in wp-admin (if you can identify what changed)
- Restore from a hosting provider’s snapshot (if available, often costs extra)
Git rollback options:
# Undo the last commit
git revert HEAD
# Undo a specific commit from 3 weeks ago
git revert abc1234
# See what the site looked like at any point in history
git checkout abc1234
# Compare any two points in time
git diff v1.0..v2.0
Every clone of a Git repository is a complete backup. If GitHub goes down (it rarely does), every developer who has cloned the repo has a full copy of the entire site with complete history. No backup plugin needed. No scheduled database dumps. No praying that your backup service actually works when you need it.
What a website in a GitHub repo looks like
The repository structure for a typical content site:
your-site/
├── src/
│ ├── pages/ # Each URL on your site
│ │ ├── index.astro
│ │ ├── about.astro
│ │ └── contact.astro
│ ├── content/
│ │ ├── blog/ # Blog posts as markdown
│ │ │ ├── first-post.md
│ │ │ └── second-post.md
│ │ └── config.ts # Content schema definitions
│ ├── components/ # Reusable UI (Header, Footer, Card)
│ ├── layouts/ # Page templates
│ └── styles/ # CSS
├── public/
│ ├── images/ # Static assets
│ └── fonts/
├── package.json # Dependencies
├── astro.config.mjs # Site configuration
└── README.md
Every file is plain text (or images). The entire site is readable, searchable, and understandable by both humans and AI tools. There is no database, no opaque plugin state, no serialized PHP objects.
How to migrate: your options
1. AI coding agents (most flexible — hours to days)
The most common approach today. Tools like Claude Code, Cursor, Windsurf, and Cline can handle the entire migration while you guide the process.
Step by step:
- Create a new GitHub repository
- Clone it locally
- Export WordPress content (Tools > Export, or use the REST API)
- Open the project in your AI coding tool
- Instruct the agent: “Convert this WordPress XML export into an Astro site. Create content collections for blog posts. Download all images. Match the current site’s layout.”
- The agent scaffolds the project, converts content, builds layouts, handles images
- Review the output, iterate on anything that needs adjustment
- Push to GitHub and connect to a hosting platform
Real-world examples:
- cursor.com migrated from Sanity CMS to code in a GitHub repo in 3 days for $260 in AI tokens. CDN costs dropped from $56,848/year to near-zero. New pages ship in minutes instead of weeks. (Source)
- Sid Bharath migrated his WordPress blog to a GitHub repo with Claude Code in 3 hours. PageSpeed went from 67 to 100. Monthly hosting dropped from $20 to $0. (Source)
- Prefect.io moved from CMS to a GitHub-based codebase in 1 week instead of the estimated 6 weeks. Landing pages now deploy in 30 minutes instead of 2 weeks. (Source)
Claude Code is particularly well-suited for this because it runs in your terminal and can execute commands directly — git init, npm create astro@latest, npm run build — iterating on build errors until the site compiles cleanly.
2. AI app builders (for non-developers — hours)
Tools like Bolt.new, v0.dev, Lovable, and Replit Agent can generate a complete website from screenshots and descriptions. You get a working codebase that you can then push to GitHub.
The workflow: screenshot your WordPress pages, paste them into the tool, describe what you want. The tool generates a project. Export it to GitHub.
Trade-offs: less control over code organization, may require iteration, and the generated code varies in quality. But you end up with a GitHub repo, which is the goal.
3. Hire a developer or agency (hands-off — days to weeks)
Freelance developers charge $500-$5,000 for a WordPress-to-static migration, depending on site complexity. Agencies charge $5,000-$25,000 for enterprise sites. Many developers now use AI tools themselves, which has reduced timelines and costs significantly.
When hiring, specify that you want the final output delivered as a GitHub repository with deployment configured. This ensures you own the code and can maintain it independently after the engagement ends.
4. Automated migration tools
Several tools automate the full migration pipeline. BrowserCat Migrate is one example — it crawls your WordPress site, extracts content, rebuilds it as code, and pushes to a GitHub repo. Other tools focus on specific steps in the pipeline.
5. WordPress export tools + manual setup
These handle content extraction, leaving the Git setup and site building to you:
- WordPress XML Export (built-in): Tools > Export in wp-admin
- WordPress REST API: Fetch content programmatically from
/wp-json/wp/v2/postsand/wp-json/wp/v2/pages - wordpress-export-to-markdown: Converts XML to markdown with frontmatter and image downloads
- wp2md: WordPress XML to markdown converter
- Simply Static / WP2Static: Export rendered HTML (good as a reference, not a maintainable codebase)
After extracting content, you create a GitHub repository, scaffold a static site project, and organize the exported content into it.
6. Manual migration (full control — weeks)
- Create a GitHub repository
- Scaffold a static site project (Astro, Hugo, 11ty)
- Export WordPress content and convert to markdown
- Build layouts and components matching your current design
- Download and organize images
- Set up redirects for changed URLs
- Connect to Cloudflare Pages, Vercel, or Netlify for auto-deploy
- Test thoroughly
This takes 2-6 weeks but gives you complete understanding of every file in your repository.
Setting up the deployment pipeline
Once your site is in a GitHub repo, connecting automatic deployment takes about 5 minutes:
Cloudflare Pages
- Go to the Cloudflare dashboard > Pages
- Connect your GitHub repository
- Set the build command (e.g.,
npm run build) - Set the output directory (e.g.,
dist/) - Deploy
Every push to main triggers a new deployment. Every push to a branch creates a preview deployment with its own URL. Free tier includes unlimited bandwidth and 500 deploys per month.
Vercel
- Import your GitHub repository on vercel.com
- Vercel auto-detects the framework and configures the build
- Deploy
Similar automatic deployments and preview URLs. Free tier includes 100GB bandwidth.
Netlify
- Connect your GitHub repository on netlify.com
- Set build command and publish directory
- Deploy
Free tier includes 100GB bandwidth and 300 build minutes per month.
All three platforms support custom domains, HTTPS (automatic), and deploy notifications. The setup is a one-time process — after that, your deployment workflow is simply git push.
GitHub-specific features for websites
GitHub Actions for automation
You can set up automated workflows that run on every push:
- Build validation: Ensure the site builds without errors before merging
- Link checking: Scan for broken internal and external links
- Image optimization: Automatically compress images when they are added
- Spell checking: Run a spell checker on markdown content
- Lighthouse audits: Run performance checks on preview deployments
GitHub Issues for content planning
Use GitHub Issues to track content ideas, bug reports, and feature requests. Link issues to pull requests so you can see which changes address which requests. This replaces the WordPress editorial calendar and gives you a more flexible planning system.
GitHub Discussions for feedback
Enable Discussions on your repository for team communication about the site. This replaces the informal “leave a comment in wp-admin” workflow with threaded, searchable discussions.
WordPress-specific migration considerations
Content extraction challenges
WordPress stores content as HTML in the database, with Gutenberg block markup embedded as HTML comments. Simple content (paragraphs, headings, lists, images) converts to markdown cleanly. Complex layouts (columns, tables, galleries, custom blocks from plugins like Kadence or Elementor) require manual conversion or custom scripts.
SEO preservation
Your WordPress SEO plugin (Yoast, RankMath) stores meta titles, descriptions, Open Graph tags, and canonical URLs in the wp_postmeta table. A standard XML export does not include all of this data. Use the REST API with the Yoast/RankMath REST extension to extract complete SEO metadata, then map it to markdown frontmatter in your new site.
Preserve URL structure to avoid broken links and ranking drops. Set up 301 redirects for any URLs that change. Submit a new sitemap to Google Search Console after migration.
Custom post types
WordPress custom post types (Portfolio, Testimonials, Team, etc.) and custom taxonomies need to become separate content collections in your static site. Each custom post type becomes a directory of markdown files with its own schema.
Forms and dynamic features
Contact forms (Contact Form 7, WPForms, Gravity Forms) need to be replaced with a form service like Formspree, Basin, or Netlify Forms. Search can be handled with client-side solutions like Pagefind or Lunr.js. Comments can move to Giscus (GitHub Discussions-backed) or Disqus.
When NOT to move to GitHub
A GitHub-based workflow is not right for every team:
- Non-technical content teams that publish frequently and need a visual editor. Git-backed CMSes (Decap, Tina) help, but they add a layer of complexity. If your team of 10 content writers publishes daily and relies heavily on the WordPress editor’s formatting tools, the transition cost may be too high.
- Sites with dynamic, user-generated content — forums, membership areas, e-commerce with user accounts. These need a backend, and a static site in a Git repo is not the right architecture.
- WordPress multisite installations where individual sub-site editors need independent access. Git’s permission model does not map well to WordPress’s per-site role system.
For everyone else — developers, small teams, businesses with marketing sites, bloggers, freelancers — a GitHub-based workflow is a significant upgrade over WordPress in virtually every dimension: version control, collaboration, deployment speed, cost, security, and AI compatibility.
Automate Everything.
Tired of managing a fleet of fickle browsers? Sick of skipping e2e tests and paying the piper later?
Sign up now for free access to our headless browser fleet…