Search for a Ghost theme detector and you will find a dozen tools promising to name the theme behind any Ghost publication. We built one too. Then we tested it properly, and found that most of those promises cannot be kept.
We checked every official theme demo in Ghost's marketplace against the public HTML a detector can actually see. Two themes are reliably identifiable. The other fifteen are not. Not "hard to detect" — not identifiable at all from the outside, by us or by anyone else.
This post explains what we tested, what Ghost actually exposes, and why a tool that confidently names a Ghost theme is usually telling you something it cannot know.
What a detector can actually see
A theme detector is not magic. It fetches the same HTML your browser gets, then looks for fingerprints — file paths, class-name conventions, generator tags, runtime JavaScript objects.
WordPress makes this easy. Every theme lives at /wp-content/themes/<theme-name>/, and that path appears in the page source as soon as the theme loads a stylesheet. The theme names itself, in public, on every page. That is why WordPress theme detection is close to a solved problem.
Ghost does not work that way.
What Ghost exposes
Ghost is generous with one signal and silent on the other.
It tells you it is Ghost. Most publications ship a generator tag:
<meta name="generator" content="Ghost 5.x" />They also load Ghost's Portal bundle and serve compiled assets from /assets/built/. Confirming that a site runs Ghost is straightforward and reliable.
Naming the theme is a different problem. Ghost compiles themes at build time into a bundle in /assets/built/, and the bundle is not named after the theme. Most themes emit a generic main.min.js. Not edition.min.js. Not solo.min.js. Just main.
The test
We took every official theme from Ghost's marketplace and checked its demo site for anything in the public HTML that names the theme:
- the compiled bundle filename in
/assets/built/ - the compiled CSS, including its header comments
- the CSS source map
- class-name prefixes and structural conventions
- the generator tag and any other meta tags
Two themes name themselves:
| Theme | Signal |
|---|---|
| Source | ships /assets/built/source.js |
| Casper | ships /assets/built/casper.js |
Every other official theme ships main.min.js and nothing else that distinguishes it. The compiled CSS carries no theme header — unlike WordPress, where style.css is required to declare the theme name, version, and author in a comment block. Ghost has no equivalent requirement. And the CSS source map, which sometimes leaks original filenames, only references @tryghost/shared-theme-assets — the shared build tooling, identical across themes.
So there is no theme name in the bundle path, no theme name in the CSS, and no theme name in the source map. There is nothing left to read.
Why other tools still show you a name
If the information is not there, how do competing tools produce a confident answer?
Some fall back to a value that is present but means something else. The most common substitution is Ghost's JSON-LD block, which every publication emits:
{
"@type": "WebSite",
"name": "Coding Horror"
}That name field is the publication's name — the title of the blog. It is not the theme. Read it as a theme name and you will report that Coding Horror runs a theme called "Coding Horror," when it is actually running Source.
We know this because the codebase we started from did exactly that, and we removed it. A publication name dressed up as a theme name is not a detection. It is a field swap that happens to produce a plausible-looking string.
Other tools guess from layout. If a publication has a large hero image and a two-column grid, it "looks like" a popular theme, so that is what gets reported. That is pattern-matching on visual convention, and Ghost themes borrow heavily from each other. A guess presented without uncertainty is worse than no answer.
What we report instead
Our Ghost detector distinguishes between two outcomes, because they are genuinely different:
Theme identified. The bundle is source.js or casper.js. We name it.
Publication confirmed, theme not identifiable. The site is definitely Ghost — generator tag, Portal bundle, /assets/built/ assets — but the bundle is generic. We say so, name the publication, and tell you the theme cannot be read from public HTML.
The second outcome is not a failed scan. It is the correct answer for fifteen of seventeen official themes, and for most custom themes too. A tool that never returns it is either guessing or substituting a different field.
How to check a Ghost site yourself
You do not need a tool for this. Open any Ghost publication, view source, and search for /assets/built/.
<script src="/assets/built/main.min.js?v=a1b2c3"></script>If the filename is source or casper, that is your theme. If it is main, the theme is not recorded anywhere in the page, and no amount of inspection will recover it. You can stop looking.
Worth noting: a hashed suffix like source.a1b2c3.js is still Source. Ghost appends a cache-busting hash that varies between builds; the base name is the part that matters.
What this means if you are theme-shopping
People usually ask "what theme is this?" because they want the same look for their own publication. If the answer is unavailable, here is what still works:
Ask. Ghost publications are usually run by individuals rather than corporations, and most will tell you. This has a far higher success rate than people expect.
Look for a credit. Many themes include a footer link back to the developer. It is not universal, but it costs nothing to check.
Search the marketplace by layout. Ghost's official marketplace is small — dozens of themes, not thousands. Browsing by structure is genuinely practical at that scale, in a way it never is for WordPress.
Check if it is custom. A large publication with an unusual layout has often commissioned a bespoke theme. In that case there is no product to buy, and identifying it would not help you anyway.
The broader point
Detection is only as good as what a platform chooses to expose. WordPress puts the theme name in a URL path on every page. Shopify exposes a Shopify.theme object with an ID and role. Ghost exposes almost nothing, deliberately or otherwise.
A detector that reports the same confidence for all three is not measuring the same thing in each case. When we cannot tell, we say we cannot tell — because a made-up theme name is not a smaller error than no answer. It is a bigger one, since you will act on it.
If you want to confirm a site runs Ghost and see whether its theme is one of the two identifiable ones, run it through our Ghost detector. And if you are curious how detectors get platform identification wrong in the other direction, we wrote about why a Ghost site gets misreported as Shopify.