The Ghost Themes Developer Hub

Welcome to the Ghost Themes developer hub. You'll find comprehensive guides and documentation to help you start working with Ghost Themes as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    


Keep up to date with the latest changes

The following document acts as a reference for developers who want to keep their theme up-to-date with the latest changes in the Ghost theme API.

Got ideas?!

If you have bright ideas for improvements we could make to our theme API, or use cases that aren't quite working, please tell us about it! We have a special themes category in our forum.

Keeping up to date

The best way to keep up-to-date with the changes is to subscribe to the developer blog. All theme related blog posts are tagged with 'themes', so you can subscribe to an RSS feed of only theme related posts if you prefer.


Ghost will validate your theme on boot and you can run the same tests either online at GScan or by using gscan as build tool when developing your theme. GScan will output a summary of any errors, warnings or recommendations plus how to fix them so that your theme is compatible with the latest version of Ghost.


GScan is also used to validate your theme when uploaded to Ghost Admin. If your theme fails with any fatal errors, you won't be able to upload or activate it. Fatal errors prevent a theme from being used because they could cause pages of your site to render a 500 error.

Ghost 2.0.0

(16th August 2018)


  • All package.json files should include ghost-theme in the keywords array.
  • Koenig is now the default editor, themes are required to add support for the new image/embed markup and image sizes


  • The {{content}} helper no longer outputs a <div class="kg-card-markdown"> element that surrounds the content. Ensure your theme works without it, typically this can be achieved by adding your own wrapper around {{content}} and swapping any .kg-card-markdown selectors in your CSS to match your wrapper's class.
  • @blog.permalinks has been removed


If a theme is using deprecated syntax or features it will output warnings when scanned in gscan or when uploading the theme in the admin area. It's recommended to fix your theme as soon as possible because deprecations will become fatal errors in the next major release.

  • The {{author}} helper has been deprecated, it should be replaced with {{authors}} or {{primary_author}} dependent on the use-case
  • {{error.statusCode}} and {{statusCode}} have been deprecated, they should be replaced with {{error.code}} and {{code}} respectively

Ghost 1.23.0

(22nd May 2018)


  • Our new Koenig editor has been released in beta and requires CSS changes to add support.

Theme's CSS should be prepared for content that has been edited with Koenig, for a complete example check the Casper Koenig implementation.

Content wrapper

  • All existing posts created with the Ghost 1.0 markdown editor are rendered in a wrapper element with .kg-card-markdown CSS class (no change here but this class will be deprecated in the future).
  • All posts edited or saved with the Koenig editor enabled are wrapped in an element with .kg-post class instead of .kg-card-markdown.

Image classes

  • Koenig allows images to be rendered as "wide" or "full-width" as well as adding captions to images but your theme needs to support this for the styles to work in your published posts
  • Add support for the <figure> and <figcaption> elements (see below)
  • Add support for .kg-image-wide and .kg-image-full classes

The full HTML structure for rendered image cards is as follows:

<figure class="kg-image-card">
   <img src="..." class="kg-image (kg-image-wide|kg-image-full)">

Ghost 1.22.4

(24th April 2018)


  • The translatable options for seconds in the {{reading_time}} helper got removed. See the reading time helper and i18n docs for full details.

Ghost 1.22.0

(27th March 2018)

In Ghost 1.22.0 we've shipped multiple authors. Single author functionality is deprecated. Therefore we've added or extended functionality for multiple authors.


  • We've added a new shiny {{authors}} helper (same behaviour as our tags helper). The helper is a new formatting helper, which helps outputting multiple authors.
  • We've added an additional {{primary_author}} data helper.



Ghost 1.21.2

(14th Feb 2018)


  • {{#get}} helper filters can now use dates

Ghost 1.17.0

(7th Nov 2017)


  • {{reading_time}} helper that calculates and renders the estimated reading time for a post. See the reading time helper docs for full details.

Ghost 1.15.0

(19th Oct 2017)


  • {{#next_post}}{{/next_post}} & {{#prev_post}}{{/prev_post}} now support in="author"

Ghost 1.14.0

(13th Oct 2017)


  • {{#next_post}}{{/next_post}} & {{#prev_post}}{{/prev_post}} now support in="primary_tag"

Ghost 1.13.0

(10th Oct 2017)


  • Custom post templates can now be added by naming post templates custom-{{template-name}}.hbs, any such templates are selectable on a per-post basis by post authors in the admin area's post settings menu. See the custom template docs for full details.
  • Filter posts by primary_tag

Ghost 1.7.0

(22nd Aug 2017)


  • The {{#has}} helper has been extended with another two comparison attributes:
    • any and all attributes to match against multiple properties
      See the has helper docs for full details.

Ghost 1.6.0

(15th Aug 2017)


  • The {{#has}} helper is now able to do more comparisons:
    • number and index matching inside of foreach loops, including "nth" support
    • slug and id matching inside of posts, authors, tags, etc
      See the has helper docs for full details. More changes coming soon!

Ghost 1.5.0

No theme-related changes.

Ghost 1.4.0

(2nd Aug 2017)


  • We have added a new feature to be able to set custom code injections per post.
  • So {{ghost_head}} and {{ghost_foot}} helpers output both the global and the per post code injection if available.

Ghost 1.3.0

(1st Aug 2017)


  • The {{excerpt}} helper will now default to outputting the posts new custom_excerpt property if there is one. If custom_excerpt is not set the behaviour is the same as before.
  • Posts now have a {{custom_excerpt}} property which contains the user-provided custom excerpt.

Ghost 1.2.0

(31st July 2017)


  • Posts now have a {{primary_tag}} dynamic property that can be used to access the first tag associated with any post.

Ghost 1.0.2

(27th July 2017)


  • Posts now have a {{comment_id}} dynamic property that must be used when creating a unique post identifier for Disqus.

Ghost 1.0.0

(23rd July 2017)

Strong requirements around package.json

  • name is required
  • version is required
  • is required, author.url and are optional
  • 'Posts per page' will no longer be a setting in Ghost Admin, but a recommended property for the package.json file of the theme: posts_per_page [is highly recommended]
  • Further optional properties will be possible to use, see here

Theme config

  • {{@blog.posts_per_page}} as global data attribute will be replaced with {{@config.posts_per_page}}, which is now set in the theme's package.json, instead of in settings. See config.

Image properties & helper renamed

  • The {{image}} helper has been removed. Use {{img_url}} instead. See here
  • {{author.image}} -> replace with {{author.profile_image}}. See here
  • {{author.cover}} -> replace with {{author.cover_image}}. See here
    • {{post.image}} -> replace with {{post.feature_image}}. See here
    • {{@blog.cover}} -> replace with {{@blog.cover_image}}. See here
    • {{tag.image}} -> replace with {{tag.feature_image}}. See here

Deprecated features removed

  • The usage of {{meta_description}} in <head> will be deprecated. It's going to be included in the {{ghost_head}} helper.
  • Removal of deprecated {{pageUrl}} helper. Use {{page_url}} instead.
  • Removal of deprecated {{body_class}} classes. Use only classes listed in the Context Overview. Classes that are deprecated include:
    • .archive-template appearing on paginated pages, use .paged
    • .post-template and .page appearing on static pages, use .page-template
    • .page-template-{{slug}} appearing on static pages, use .page-{{slug}}
    • Also note, .page-{{slug}} used to only appear on pages with custom templates, in 1.0.0 they will be ever present, the same as .tag-{{slug}} or .author-{{slug}}.


  • All themes are validated by GScan, and can only be activated if they are valid.
  • Favicon is now an upload in settings, rather than a theme feature. Favicons included in themes will no longer work.
  • The {{get}} helper's {{else}} condition is now only triggered for errors, not empty results, instead please use {{else}} on the block helper you use inside the {{#get}} helper.

Ghost 0.x.x

(13th Jan 2014 -> 23rd July 2017)

See the Ghost 0.x to 1.x changelog


Keep up to date with the latest changes