docs/codebase/theme-compatibility.md
Ghost themes use Handlebars templates and helpers provided by Ghost. When Ghost adds a theme feature and a theme starts using it, that theme is not compatible with older Ghost versions that do not provide the feature. When Ghost removes or changes a theme feature, older themes may stop working on the new version.
Incompatibility does not always produce a clear error. A feature may do nothing, content may disappear, the output may look wrong, or a page may return an error. People also commonly install the latest release of a theme on an older Ghost version, or update Ghost without first checking their theme.
GScan validates themes against the rules for a Ghost major version. Ghost runs GScan when it loads or uploads a theme and shows the results in Admin. Theme developers can also use gscan.ghost.org or the GScan command-line tool.
Ghost originally relied on theme developers declaring the supported Ghost
version in package.json:
{
"engines": {
"ghost": "^5.5.0"
}
}
That requires a theme developer to know which Ghost release introduced every feature the theme uses and to keep the declaration current. In practice, the version was often wrong and people still experienced broken or missing output.
GScan moves that compatibility knowledge into rules. It can recognize features that Ghost may add later, as well as features Ghost has removed or changed, and give people a clear explanation of what changed and how to respond. Usually the answer is to update Ghost or update the theme.
GScan supports messages at four levels:
Most GScan messages are non-fatal errors. They are shown when a theme is installed, but the user can choose to ignore them. Fatal errors prevent the theme from being activated.
Use a fatal error only when a theme would throw an error while rendering a page, and introduce one only in a major Ghost version. Warnings are shown in Admin in development, and when GScan is run directly, but are hidden in Admin in production.
Changes to helpers, templates, package.json fields, assets, translations, or
rendered markup may need a corresponding GScan change. Before changing a public
theme contract:
gscan dependency in ghost/core/package.json and run Ghost's
theme tests. Theme fixtures may also need updating.Version specs inherit the helpers and rules from the preceding major version. Add new compatibility information to the spec for the first Ghost major that uses it rather than rewriting an older version's contract.
Theme-facing helpers live in
ghost/core/core/frontend/helpers/,
with unit tests in
ghost/core/test/unit/frontend/helpers/.
Adding the implementation is not enough. GScan must know the helper name or it will report valid theme usage as an unknown helper. To add one:
Add the helper and its unit tests in Ghost.
Add its name to knownHelpers in the current major-version spec in GScan,
with GScan tests where needed.
Release GScan and update ghost/core/package.json to that version.
Run the Ghost helper registration and GScan compatibility test:
pnpm --dir ghost/core test:unit \
test/unit/frontend/services/theme-engine/handlebars/helpers.test.js
The compatibility test compares theme-facing helper files with GScan's
knownHelpers list. A helper that is deliberately internal or experimental
must be explicitly excluded there with a reason.
Casper and
Source are included in this repository as
Git submodules under ghost/core/content/themes/. Changes to Ghost's theme
contract must remain compatible with these themes, and the Ghost theme tests
must pass after a GScan update.