Published
Pages CMS: a CMS for static sites that lives in your GitHub repository
What Pages CMS is, how it works, who it is for, and the limits worth knowing before you hand it to a client.
A static site is fast, cheap to host and very hard to break. The trouble starts the day the client wants to change their opening hours, swap a photo or post some news. Either they call me, or I install a WordPress they never needed. Pages CMS sits right in that gap, which is why I have been trying it out.
What it is
Pages CMS is an open source CMS (MIT licence) for GitHub repositories. It does not keep content in a database of its own: it reads and writes the Markdown, YAML, JSON and image files already in the repository. Every save in the editor is a commit.
It does not replace your site generator or your hosting. It is only the editing layer on top of a site built with Astro, Hugo, Jekyll, Eleventy, Next.js, Nuxt, Docusaurus and the like. Your existing pipeline still builds and publishes the site.
How it works
It connects through a GitHub App with access to the repositories you choose. After that you only need a .pages.yml file at the root of the repository describing what is editable: where images live, which collections exist and which fields each entry has.
media: media
content:
- name: posts
label: Posts
type: collection
path: content/posts
fields:
- name: title
label: Title
type: string
- name: date
label: Date
type: date
- name: cover
label: Image
type: image
- name: body
label: Body
type: rich-textWith that, the client sees a list of posts, a form with a title, date, image and a rich-text editor, and a media manager with drag-and-drop uploads. When they save, Pages CMS makes the commit; your Cloudflare, Vercel or Netlify sees the push and republishes the site.
What you get out of the box
- Fourteen field types: string, text, number, boolean, date, image, file, select, code, rich text, UUID, objects, blocks and references to other entries.
- Collections and single files: a folder of posts, or one file of site settings such as contact details and opening hours.
- Collaborators by email: you invite the client by email and they sign in without a GitHub account.
- Actions: buttons in the editor that trigger GitHub Actions workflows, such as "Deploy to production".
- Search and a mobile interface: a typo can be fixed from a phone.
Who it is for, and who it is not for
This is the part that matters most, because Pages CMS is very good at one specific job and weak outside it.
Good fit
- Freelancers and agencies handing a static site to a non-technical client who only needs to edit text, images and not much else.
- Local business sites, portfolios, landing pages, documentation and small Markdown blogs.
- Teams already living on GitHub who want every content change in the history, revertible like any commit.
- Anyone who wants a free CMS with no content database to maintain and no vendor who might change the price tomorrow.
Poor fit
- Repositories on GitLab, Bitbucket or a self-hosted Git server. It only works with GitHub.
- Online shops, customer portals or any site with dynamic data created by visitors.
- Editorial teams that need drafts with approval, scheduling or a live preview before publishing.
- Large video libraries or high-resolution image archives, which should not live inside a Git repository.
The limits worth knowing
None of these are hidden flaws. They follow directly from "the content lives in Git". But you should know them before you promise a client anything.
- GitHub only. It is the only supported repository provider. If the project lives elsewhere, it is out.
- It does not build or deploy the site. Every save is a commit; publishing depends on having an automatic deploy wired to every push. Without one, the client saves and nothing changes online. Also allow for the seconds, or minutes, the build takes.
- Images go into the repository. Everything the client uploads stays in Git forever, even after it is deleted. Over time the repository grows. External storage on AWS S3 or Cloudflare R2 is listed on the site as "Soon" at the time of writing.
- No documented editorial workflow. I could not find drafts with approval, pull-request based editing or a live site preview in the documentation. Scheduled publishing, granular permissions per content type, analytics and comments are all marked "Soon".
- Collaborators have limited powers, and the commits are not theirs. People who sign in by email can edit content and media, but cannot touch the configuration or manage other collaborators. By default, commits carry the GitHub App's identity; to show the editor's name you have to enable
commit.identity: userin the settings. - Someone has to write the
.pages.yml. The client does not configure anything alone. Fields, collections and paths are the site builder's job, and they change whenever the content structure does. - Self-hosting takes work. Version 2 needs PostgreSQL, a GitHub App you create yourself, auth secrets and an email provider (Resend or SMTP) for invitations and sign-in. The database stores users, collaborators and a cache of the files from GitHub.
Hosted or self-hosted
There are three routes, all free: use the hosted version at app.pagescms.org, deploy it to Vercel in one click, or run it on your own server. For most client sites the hosted version is enough and there is nothing to maintain. Self-hosting makes sense when you want control over the editor's domain, where the emails come from, or where collaborator data is stored. If you do, remember that collaborators live in the database, not in the repository, so moving to a new instance means migrating them.
Verdict
For the "I delivered a static site and the client wants to update the content without calling me" case, Pages CMS is one of the simplest options there is: one config file, one email invitation, and the site stays static, fast and cheap. When a project needs an editorial workflow, dynamic data or a lot of media, the problem is no longer a static-site CMS problem, and you are better off picking a different tool from the start.