Anatomy of a Ghost Theme — Part 1
This post explains a Ghost theme’s structure, its essential files, and what each file does. For a ready-made design, browse the Ghost themes collection. The themes are used by 3,000+ customers.
Handlebars
First, Ghost uses Handlebars as a template language; that’s why the theme file extension is .hbs. For example, index.hbs, post.hbs or author.hbs. There is no need to install Handlebars in a Ghost theme; it is part of Ghost.
Let’s take a quick example of how Handlebars integrated with Ghost to output data from a Ghost website.
To output post content, use the content helper. Put it inside double curly braces: {{ }}. This creates a Handlebars expression. Add {{ content }} to the theme to output the post content.
Ghost uses express-hbs to extend Handlebars. The library adds features such as partials and layouts.
File Hierarchy
Ghost chooses a template file for each page. For the homepage, it first checks for home.hbs. If that file exists, Ghost uses it. Otherwise, it uses index.hbs.
Another example for the Author page, Ghost will look for the author.hbs first and use it if it exists. If not, Ghost will use index.hbs.
From the two examples above, we can see that the index.hbs file is necessary for any Ghost theme.
Essential Files
The package.json, index.hbs, and post.hbs files are three essential files in any Ghost theme.
Let’s consider that we have a theme called anatomy; the file structure would be.
anatomy
|__index.hbs
|__post.hbs
|__package.json
Let’s see each file in more detail.
➊ package.json
The package.json is a JSON file with the .json extension. It contains name/value pairs of data. What kind of data can we add?
- Theme name and version
- Theme author data
- Ghost and Content API versions
- Theme configuration like how many posts per page to display
- Dynamic image sizes for uploaded images
- Theme NPM dependencies
Some of this data is visible on the admin side. Open Settings → Site → Theme → Change theme in Ghost Admin to see the available themes. For each theme, you can see the theme name and version.
The name and version are available as name/value pairs in the package.json file.
The name field is, of course, the name of the theme. The version is the theme version.
Apply this to the anatomy theme and add the following data to the package.json file.
{
"name": "anatomy",
"version": "1.0.0"
}
Ghost lists the theme under INSTALLED THEMES. Its name is anatomy and its version is 1.0.0.
We created our first theme by adding the package.json file, which is visible in the available themes list. Trying to activate it produces a fatal error. The other two files, index.hbs and post.hbs, are missing.
➋ index.hbs
The index.hbs is the second essential file used to show a list of posts.
As noted above, Ghost uses index.hbs for an author page when author.hbs is absent. It also uses index.hbs for a tag page when tag.hbs is absent.
➌ post.hbs
The third essential theme file is post.hbs, which outputs the post details.
We can now activate the theme after adding both index.hbs and post.hbs. Activation still reports missing CSS classes and package.json properties. If you went to the website homepage, you would see an empty page. But as a starting point and at this stage, we were able to activate the theme with the must-have files.
Further Reading
- See real‑world Ghost website examples → Showcase
- Read the docs to build and customize → Ghost theme documentation
That’s all that I wanted to share today, and I hope you find this post helpful.
More from the Blog
Latest Ghost Themes
Arish
For visual magazines that lead with photography, film, and selected stories.
Siwa
A personal publication that introduces the writer before inviting readers into the stories.
Hanoi
An image-led magazine for creative stories, rich navigation, and long-form reading.
Taba
A newsroom front page for coverage across topics, video, and story formats.
Marsa
A flexible publication homepage for featured stories, topics, and newsletters.
Hakone
For writers who want readers to browse complete posts on the homepage.