Skip to content

We deleted our CMS. Claude and git replaced it

We deleted our content management system. A git repo, Claude, and a wall of build checks replaced it, and the site got faster and safer.

We deleted our content management system. No admin panel, no database, no login screen, no “content” table waiting to be filled. What runs tarmac.io now is a git repo full of markdown, Claude Code, and a wall of build checks that refuse to let a broken page reach the domain.

People hear that and assume a model is now writing our website. It isn’t. Claude did not replace our writers. It replaced the software that used to stand between a finished piece of writing and the published page. The words are still ours. What changed is everything around them.

The repo is the CMS

A content management system is, underneath the dashboard, two things: a place to keep content and a machine to publish it. We kept the first and threw away the packaging. Every post and case study is a markdown file in the repo. So is the material that decides what belongs on the site at all: the competitive analysis, the design direction, the roadmap that tracks what is done and what is next. It is all plain text, versioned next to the code, not locked in someone’s head or rented from a SaaS tool behind a login.

That matters because the content and the context now live in the same place a person edits and a pipeline reads. Nothing has to be exported, synced, or copy-pasted out of a proprietary editor. A writer opens a file. The history of every change is in git. Publishing is a merge.

The guardrails are the product

Here is the part that earns the trust. Every mechanical way a content site quietly rots is caught by a check that fails the build. Not a warning in a log nobody opens. A hard stop that turns the deploy red and keeps the page off the domain.

  • Content checks. Alt text on every image, or the build fails. A meta description outside 70 to 165 characters, fail. A title long enough to truncate in Google, fail. An image dropped where it would ship uncompressed, fail. An em-dash in new copy, which reads as machine-written, fail.
  • URL checks. Every internal link, every field of structured data, every entry in the machine-readable index has to point at the URL that actually serves, in one hop. A link that would cost a redirect fails the build before anyone clicks it.
  • Link checks. Anchor text is read the way the dumbest crawler reads it: plain text, no alt, no aria-label. Four case-study links all labelled “Case study” would satisfy a screen reader and fail here, which is the whole point.
  • Weight checks. Images run through a build pipeline that compresses them. Skip it and one post can ship at 7.6 MB instead of 213 KB, so skipping it is not possible.

Every one of those started as a real mistake. Eight imported posts once scrolled sideways on a phone. The site once shipped thousands of internal links that each cost a redirect. A page once weighed 7.6 MB. We did not fix those by writing a style guide and hoping people remembered it. We wrote a check that will not let them happen again, and now nobody can put them back: not a distracted person, and not an automated tool moving fast.

That is what a CMS was always supposed to do and mostly didn’t: guarantee the boring things. Ours guarantees them by refusing to build when they are wrong.

What Claude actually does

Claude Code is how we operate all of this. It built the site and it maintains it. When a post is ready, it does the mechanical work an admin panel used to pretend to do: it places the file, wires the frontmatter, processes the images, runs every check, and reports what fails. It fixes the redirect map when a URL moves. It refactors a component without breaking the layout. Then it opens a pull request.

It cannot merge. That line is the important one. A person reviews the deploy preview on a laptop and a phone, and the merge that publishes to www.tarmac.io is a human action with a human name on it. Claude runs the machinery of the site. People decide what the site says.

That is the honest division of labor, and it is the opposite of “the AI writes our blog.” The judgment a check can never encode, whether a piece has a point, whether it argues that point well, whether it sounds like someone who actually knows the subject, stays entirely with the people who do that for a living. Everything mechanical around that judgment is automated, enforced, and impossible to get wrong by accident.

How we work

The stack is deliberately small and boring, which is why it is fast and why there is so little to break.

  • Astro 5, static output. The production build ships no framework JavaScript, so a page is HTML and inlined CSS with nothing waiting to hydrate.
  • Markdown content collections, typed with a Zod schema. category is an enum, description has an enforced length, dates are real dates. A malformed post is a build error, not a broken page.
  • sharp for images. Drop a photo in src/assets, reference it relatively, and the pipeline emits WebP, sets width and height so the layout cannot shift, and lazy-loads it below the fold.
  • Self-hosted variable fonts (Inter and Space Grotesk), so no page makes a third-party font request.
  • Generated discovery files. The sitemap comes from an Astro integration, and the llms.txt index that AI crawlers read is a generated route, not a file anyone maintains.
  • Netlify for hosting and CI, building on Node 20.
  • Plain Node check scripts, wired into the build with nothing exotic underneath them.

The process is git the whole way down. Work happens on a branch, never on main. Before the build even compiles, prebuild generates the article thumbnails and runs the content check. After it compiles, postbuild runs the redirect, llms, and link checks against the real output in dist, not a guess about it. There is deliberately no headless browser in the build, because it would add a heavy dependency and slow every deploy, so the rule that no page may scroll sideways on a phone is held by structural CSS and one manual check at 390px. Every push to main deploys straight to the live domain, which is exactly why a failed check has to fail the deploy. Nothing broken reaches customers, because the thing that would serve it never finishes building.

We build this way for clients too. The demo is never the hard part. The system around it, the checks that make speed safe and the process that keeps a named human accountable for every consequential call, is the Tarmac 10, and it is the same reason our AI and applied ML teams ship software you can actually run in production.

Let’s build something worth taking off.

Tell us what you’re building. We’ll assemble the senior team to ship it.