Rebuilding onygo with Claude Code
18/09/2026 · 8 min read
I recently rebuilt onygo, and one thing about the process matters because of what it did not involve: I never opened Figma. I did not create polished screens somewhere else and then reproduce them in WordPress. That is not an argument against Figma; I was working completely on my own, with no additional alignment requirement with designers, developers or stakeholders, so in this project the working product itself could be the place where the design happened.
That only worked because I already knew reasonably well what I wanted. Before touching onygo itself, I had built Dessau as a white-label design system and derived Neon from it for my personal brands, including onygo and martin gude. Claude Code therefore did not start with an empty page and a vague request to make me a nice blog; it started with rules, patterns and a visual language already expressed in code.
TL;DR
I rebuilt onygo with Claude Code around a code-first design system, the real existing WordPress installation, a local Docker environment, issue-first development, screenshots for communication, proper local testing and manually triggered deployment. The result is not a new WordPress site but the same installation, cleaned up, simplified and brought under much tighter control. The broader lesson for me is that every artefact should move the product forward, and documentation should be minimum necessary — with the emphasis firmly on necessary.
Build the system first
I did not start with a fresh WordPress installation. I took the existing onygo setup, with all the history and accumulated decisions that came with it, created a GitHub repository for the theme and surrounding development work, and gave Claude Code the current theme and installation to analyse before changing anything. That analysis was one of the most useful parts of the whole exercise because it meant we were working from what the product actually did, not from assumptions about what a WordPress blog usually looks like.
I also created a local development environment with Docker and imported the real content into it. That means roughly 20 years of actual onygo posts, rather than three neat demo articles whose headings all happen to fit beautifully into every component. Old content brings strange lengths, historical formatting, edge cases and decisions nobody remembers making, so if I want to know whether the cleaned-up site still works as onygo, the real history of onygo is a much better test fixture than Lorem ipsum.
The existing installation also had more than 20 plugins. Rather than automatically carrying them all forward, I used the analysis to understand what jobs they were actually doing and whether each one still needed to exist as an external dependency. Two-click embeds, Matomo integration, autolinking, the privacy banner, typography and reading time are now handled directly by the theme, and I am down to fewer than ten external plugins.
That is not an ideological position against WordPress plugins. If a plugin solves a problem well and saves me from maintaining something unnecessarily, I will happily use it. I simply want external dependencies to have a reason for being there rather than surviving forever because somebody once clicked “install”.
The same applies to new functionality. I decided that I want my LinkedIn posts available on onygo as well, so I built an importer for them rather than trying to bend an unrelated generic plugin into that workflow. I also have a content workflow around the site and will probably add another piece later that creates LinkedIn shares automatically when I publish a post, but the general idea stays the same: keep the parts that are specific to my workflow understandable and under my control while using external components where they genuinely earn their place.
One rule became important very quickly: Claude Code does not get to start coding without an issue. Before implementation begins, there needs to be a reasonably clear statement of what we are trying to achieve. That might sound like process theatre for a personal project where developer, product owner, designer and person approving the budget are all the same bloke, but it forces me to think about intent before an agent starts producing code at considerable speed.
That matters because AI makes implementation cheap enough that it becomes very easy to solve the wrong problem efficiently. A good issue is not there to tell Claude Code exactly which line to change or how to implement every detail. It establishes the problem, the desired outcome and enough context for the agent to work within the system rather than improvising a new one.
Screenshots helped a lot with that communication. Sometimes text is the best way to describe what I want, but sometimes a screenshot makes a visual problem obvious immediately and saves a paragraph of tortured explanation about spacing, alignment or behaviour. I never needed a full design handoff, but I did need ways to communicate intent precisely, and screenshots often turned out to be the lightest useful artefact.
Testing is non-negotiable in this workflow. Changes run locally first, and I use automated tests, including Playwright, to make sure important behaviour still works before anything gets near production. Earlier in the project I ran more of those tests through GitHub Actions, but I moved much of that work back to the local environment because there is little reason to burn GitHub Action minutes on tests my own machine can run perfectly well before I push.
Deployment follows the same principle. Claude Code built the GitHub Actions setup and a dedicated FTP user whose access is restricted to the theme directory, so the mechanics of deployment are automated and deliberately constrained. But deployment itself is always triggered manually after I have tested the result and decided that I actually want this version on the live site.
That distinction matters to me: automate execution, not judgement. “Human in the loop” is not quite how I would describe this workflow. Most of the time, I was human on the loop: defining the intent and boundaries, watching what happened, stepping in when necessary, testing the result and keeping the final release decision.
Only keep the artefacts that help
This brings me back to Figma and to artefacts more broadly. I did not need a separate design artefact here because there was no communication problem that a Figma file would have solved better than the design system, issues, screenshots and working software already did. In a team, that could be completely different: a scribble on a whiteboard might be enough, a small design might be useful, or the interaction may be complicated enough that a fully fledged Figma or Axure prototype is exactly the right tool.
The point is not to avoid artefacts. The point is to ask what each artefact contributes to product progress. Does it create shared understanding, answer an open question, enable a decision, reduce risk, preserve knowledge, support an operational need or satisfy an external obligation? If yes, make it as detailed as the job requires; if not, its existence does not become more valuable because somebody spent another two days polishing it.
About a year ago, I described diagrams that nobody actually works with as expensive wallpaper. I still like that description, and I think it applies to almost every product artefact. A beautiful journey map nobody uses, an elaborate prototype created after the decision has already been made, or a presentation produced solely because the process says there should be one are all variations of the same problem.
That is also why two lines from the Agile Manifesto still feel very current to me: “individuals and interactions over processes and tools” and “working software over comprehensive documentation”. I do not read that as an argument against documentation at all. Documentation is important, because decisions need to remain understandable, systems need to be operable, people need to be able to take over work, and sometimes you need a record simply because future-you will otherwise wonder what past-you was thinking.
My preferred phrase is minimum necessary documentation, and necessary is the important word. Minimum necessary does not mean writing as little as possible. It means writing enough for the job the documentation needs to do, whether that is understanding, alignment, traceability, operations, handover or something else.
Sometimes that amount will be tiny, and sometimes it will be extensive. Regulation can also decide what necessary means, whether we enjoy that work or not. Sometimes requirements such as DORA force you to document controls, responsibilities, dependencies or evidence that you would probably not create for the joy of it; some of that work may genuinely suck, but it is still necessary, and the job then is to fulfil the requirement properly in the lightest sensible way that avoids unnecessary drag and still allows the product to move forward.
Documentation is important. Completeness fetishism is not. That is the same basic thought as the expensive wallpaper line: once the extra detail stops increasing understanding, reducing risk or helping the product move forward, it stops earning its place. The challenge is not to produce as little as possible, but to produce what is actually needed and no more than that.
What actually made it work
Looking back, Claude Code obviously mattered. It analysed an old system, wrote a lot of code, helped remove unnecessary plugins, built tests and deployment infrastructure, and made it possible for me to work directly in code in a way I could not have done on my own before. But simply adding a coding agent to the project would not have produced the same result.
The design system reduced ambiguity, the analysis replaced assumptions with context, the real content kept the work honest, and issues, screenshots and tests created a fast feedback loop. That is probably the most useful lesson I would take into the next project: before asking an agent to build something, work out what good looks like and how you are going to recognise it. The AI did a lot of the building, but the workflow made that useful.
