I Reverse-engineered the Craft CMS Control Panel so Your Plugins Can Stop Looking like Plugins
Every time I sit down to build a settings screen for a Craft plugin, the same little argument starts up in my head.
I know Craft has a class for this. I know there’s a Twig macro that spits out exactly the field wrapper I’m after, with the label and the instructions and the errors all sitting in the right place. I just can’t ever remember what it’s called, and there’s no one page I can go to that tells me. So I go digging through craftcms/cms on GitHub, find the macro, copy the shape of it, and get on with my day. Then a fortnight later, I’m on the next plugin, and I’m doing the exact same dig all over again.
I got tired of that dig. So I wrote the thing I kept wishing existed, and put it up for everyone: an unofficial UI and brand guide for the Craft CMS 5.x control panel, aimed squarely at the people building plugins and modules.
What it actually is
It’s a reference site. Design tokens, form macros, components, and copy-paste Twig, PHP and HTML for the bits of the control panel you keep needing and keep half-remembering.
The idea is simple enough: if you’re building a plugin, your settings screens, field types, and element indexes should look like they came with Craft, not like they were bolted on after. Craft already has all the CSS and all the macros to make that happen. The trouble is they’re scattered across the source, and there’s no single place that says “here’s the button, here’s the class, here’s the markup, here’s what it looks like.” Now there is.
Inside you’ll find:
- Foundations: colour, typography, spacing, and the full set of design tokens.
- Components: buttons, the field wrapper, inputs, the lightswitches, tables, tabs, toolbars, sidebars, modals, and the relation fields for Entries and Assets. Each one has a live preview sitting right next to the code you paste.
- Commerce and the advanced bits: status labels, money and price formatting, metadata sidebars, order totals, address cards, element indexes, and field-layout builder elements.
- Reference: every built-in field type, and a form-macro cheat sheet for when you just need the name of the thing.
The previews aren’t screenshots, by the way. They’re real HTML styled with Craft’s actual CSS, pulled out into its own stylesheet and scoped tight to a demo class. What you see on the page is genuinely what you’ll get in the control panel (more or less).
Where the numbers came from
This is not official Craft documentation. Pixel & Tonic didn’t hand me a spec. I derived the whole lot by reading the open-source source: craftcms/cms on the 5.x line, plus craftcms/commerce and craftcms/shopify for the Commerce and integration pieces. The class names and the tokens are Craft’s own. All this project does is document how to use them and show you what they look like.
Which means the usual caveat applies: when Craft changes, this could well drift. If you spot something that’s gone stale, or a value that doesn’t match what you’re seeing in a current install, that’s exactly the kind of thing I want to hear about. Fidelity is the entire point of the reference, so corrections are genuinely welcome. Open an issue or a PR, and I’ll get on it.
Have a poke around
The site’s here: john-henry.github.io/craft-cp-ui-guide
And the source is on GitHub: github.com/john-henry/craft-cp-ui-guide
It’s built with MkDocs, so if you’d rather run it locally and read it offline, it’s the following two commands:
pip install -r requirements.txt
mkdocs serve
# open http://127.0.0.1:8000While I’m here, thanks to Michael Thomas for the early feedback, and for his own Craft CMS Claude Skills, which are well worth a look if you’re pointing an AI at your Craft work.
I built this for myself first, honestly. It’s the page I open on my second monitor now whenever I’m starting a plugin, so I never have to go spelunking through the source for the field-wrapper macro again. But the whole reason it’s public is that I’m plainly not the only one who’s been doing that dig. If it saves you the same half-hour it’s been saving me, it’s done its job.

