Anatomy of a Ghost Blog Theme

Share this article

Ghost is an open source blogging platform that was built by writers for writers. Designed to allow you to focus on your content and not which plugin to use, Ghost is very no frills. You won’t find jQuery navigation bars or sliders. What you will find is an easy to use blogging system that puts your content first.

Ghost also uses Markdown to format your posts, again making it simple for non-developers to update their blog. Many people want to blog but are intimidated by the scope of a product like WordPress. If you want to get up and running relatively quick with a blog, Ghost could be for you.

The simple design also makes it easy to incorporate your favorite frameworks and libraries. Want to use Foundation or Bootstrap components? How about jQuery or Masonry? The scaled down design of Ghost makes it effortless to use third party tools in your custom themes.


Installation of Ghost is simple if you have Node.js installed on your system. Even if you don’t know Node.js you should have no problem installing on your platform of choice. If you don’t have Node.js installed, you can get it here. After installing Node, head on over to Ghost to download.

I want to take a moment to highlight the challenges the use of Node.js poses. Since Node is essentially server-side JavaScript, you are limited in the hosts you can use Ghost on. You will need a virtual server to run Ghost with standard hosting, an expensive proposition if you just want to start a simple blog. The most economical options are the free tier of Amazon Web services, Digital Ocean, or Ghost Pro. Amazon is free but will require the configuration of a server. Digital Ocean is five dollars a month and offers full control, again requiring configuration of a server. The Ghost Pro option, ten dollars a month, is completely managed by the Ghost team and is the easiest to get up and running.

First steps

Create a folder called Ghost and extract the zip file into it. Open the Node command prompt and navigate to the directory where you extracted the file. Run this command to install Ghost:

npm install --production

After installation, go to the Ghost folder and open config.js file and change the following line to the URL of your site:

url: '',

If you do not have a domain name you can use your IP address. You can also change the host and port although this is not necessary to get Ghost working. After you change these settings, type the following command:

npm start

This will work only if you are in the Ghost folder. Ghost will start up and let you know what domain/IP address and port it is listening on (should be the same as what you set in config.js).

Creating a theme

Out of the box, Ghost comes with the basic Casper theme. Casper is designed to be a starting point for your own themes. Ultimately you will want to design your own themes. The only limit on what you can build is the way that Ghost handles the data that makes up your blog posts.

Navigate to your the \content\themes folder in your Ghost folder. In there you will see a folder for the Casper theme. Creating a custom theme is as easy as creating a folder with the name of your theme. Inside your theme folder create a post.hbs and index.hbs file and you have a theme, although it is not very useful at this point. Lets take a deeper look at the files that make up a theme.


    "name": "Theme",
    "version" : "1.0"

The package.json file will eventually be required by Ghost. It basically tells Ghost the name and version for your theme.


<!DOCTYPE html>
    {{! Document Settings }}
    <meta http-equiv="Content-type" content="text/html" charset="UTF-8" />

    {{! Page Meta }}
    <meta name="description" content="{{meta_description}}" />
    <meta name="HandheldFriendly" content="True" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    {{! Stylesheets }}
    <link rel="stylesheet" type="text/css" href="/assets/css/pig.css" />
    <link href='' rel='stylesheet' type='text/css'>

    {{! Ghost outputs important style and meta data with this tag }}
<body class="{{body_class}}">
    <div class="pagewrapper">
    {{> footer}}
    {{! Ghost outputs important scripts and data with this tag }}
    {{! Javascript files here }}

Even though you only need a post.hbs and index.hbs file in a folder to have a theme, the glue that holds the theme together is default.hbs. This file is the main template for all pages, and all pages will load as part of default.hbs. The .hbs is a file extension used with the Handlebars template engine.

{{! Document Settings }}

Normally tags within double curly brackets are Handlebars tags. In this case the exclamation point makes this a comment.


A Handlebars tag in action, this time supplying the title of the page.


This is a special Ghost tag for outputting styles, meta data, and scripts.

<body class="{{body_class}}">

This is used to output classes based on what content is being loaded.

{{>header}}, {{> footer}}

Used to output partial files, Handlebars will look for these in the partials directory.


The most important tag on the page, this is where content will be loaded. Also note the triple curly braces. This tells Handlebars not to escape HTML and display as intended.


{{!< default}}
{{#foreach posts}}
<article class="mbox">
    <div class="i-title">
        <h2><a href="{{{url}}}">{{title}}</a></h2>
        {{date format='DD MMM YYYYY'}}
    <div class="list-post">
    <div class="i-pic">
        <p>{{content words="0"}}</p>
    <div class="i-blurb">
        <p>{{excerpt}} ... <a href="{{{url}}}">Read More</a></p>

index.hbs is first page that displays when you load a Ghost page and it’s the only page that receives data for all posts. That means that index.hbs is the only page you can have a list of posts on without hacking together a solution in JavaScript.

{{!< default}}

The above indicates to Handlebars that this page will load into default.hbs, into the {{{body}}} tag from default.hbs.

{{#foreach posts}}, {{/foreach}}

This is the Handlebars block helper that displays a list of posts. Content between tags will repeat for each post.

{{{url}}}, {{title}},{{date format='DD MMM YYYYY'}}

Handlebars tags for URL, title, and date of post.

{{content words=”0″}}, {{excerpt}}

These are special tags to output a small snippet of a post for the post listing. Normally you would use just one of these but I used both as a hack to include a picture in a post listing. The “content words” tag will output pictures but excerpt will not. Content words will output any amount of words you specify. When you choose 0, it only outputs the picture attached to the post. The “excerpt” tag is used to add a separate text area to a post, allowing you to style the picture and text independently.


{{!< default}}
<article class="art-box">
    <div class="p-title">
        <h1><a href="/">&larr; Go back</a></h1>
    <div class="p-content">
        {{#if author}}
    <div class="p-writer">
        <p>Written by {{author}}</p>

Page that displays when you click on a post, this page has access only to the contents of a single post.

{{#post}}, {{/post}}

This tells Handlebars that the page has access to a single post.

{{#if author}},{{/if}}

This checks to see if the post has an author profile; if so, it displays with the post.


<div class="head-wrap" {{#if @blog.cover}}style="background: url({{@blog.cover}});"{{/if}}>
{{#if @blog.logo}}
    <div class="h-logo">
        <a class="h-logo-style" href="{{@blog.url}}">
        <img src="{{@blog.logo}}" alt="{{@blog.title}}">
    <div class="h-title">
        <h1 class="h-title-style">
        <a title="{{@blog.title}}" href='{{@blog.url}}'>{{{@blog.title}}}
    <div class="h-description">
        <h2 class="h-description-style">{{@blog.description}}</h2>

Found in the partials directory, this is the file loaded from the {{>header}} tag in default.hbs.

<div class="head-wrap" 
     {{#if @blog.cover}}style="background: url({{@blog.cover}});"{{/if}}>

This tag checks if a blog cover has been uploaded and if so it sets it as the background.

{{#if @blog.logo}}, {{/if}}

This is used to output the blog logo if it has been uploaded.

<img src="{{@blog.logo}}" alt="{{@blog.title}}"

This displays the blog logo.

<a title="{{@blog.title}}" href='{{@blog.url}}'>{{{@blog.title}}}

Displays the blog title as a link.

<h2 class="h-description-style">{{@blog.description}}</h2>

Displays the blog description.


<div class="foot-box">
    <div class="f-social">
    <a href="{{url absolute="true"}}" target="_blank">
        <img src="/assets/images/facebook.png">
    <a href="{{url absolute="true"}}" target="_blank">
        <img src="/assets/images/google_plus.png">
    <a href="{{@blog.title}}&url={{url absolute="true"}}" target="_blank">
        <img src="/assets/images/twitter.png">
    <div class="f-cp">
    <p>© {{date format='YYYY'}} <a href="{{@blog.url}}">{{@blog.title}}</a></p>
    <div class="f-ghst">
    <p>Runs on  <a href="" target="_blank">Ghost</a></p>

Also found in the partials directory, this file loads from the {{> footer}} tag in default.hbs. No Handlebars tags you haven’t seen yet, this footer contains social media icons for sharing.

Styling the theme

As I mentioned, Ghost is very barebones. I was originally going to use Bootstrap to style pages but I decided to use a small grid system I built with Sass.

@media screen and (max-width: 600px) {
    .mbox .list-post .i-pic {
        position: relative;
        min-height: 1px;
        padding-left: 0px;
        padding-right: 0px;
        float: left;
        width: 100%;
        background-color: #f2e7e7;
        border-bottom: 3px solid #090a0a;
    .mbox .list-post .i-pic img {
        width: 100%;
        height: 100%;

@media screen and (min-width: 601px) {
    .mbox .list-post .i-pic {
        position: relative;
        min-height: 1px;
        padding-left: 0px;
        padding-right: 0px;
        float: left;
        width: 33.33333%;
        left: 33.33333%;
        background-color: #f2e7e7;
        border-bottom: 3px solid #090a0a;

In this small snippet from my .css file, I only included two breakpoints for this article, but in a real world application we would include many more. As you can see, all of the columns scale to 100% once the screen shrinks to 600 pixels.


I’ve only scratched the surface of what can be done with Ghost. If you are looking to start a blog and have the resources, I would suggest you give Ghost a try. Remember it’s built for writers by writers!

Frequently Asked Questions about Ghost Blog Themes

What is a Ghost blog theme?

A Ghost blog theme is a pre-designed template that you can apply to your Ghost blog to give it a unique look and feel. These themes are built using Handlebars.js, a simple templating language, and they can be customized to suit your specific needs. They come with various features and layouts, such as responsive design, SEO optimization, and social sharing options, among others.

How do I install a Ghost blog theme?

Installing a Ghost blog theme is a straightforward process. First, you need to download the theme file, which is usually in a .zip format. Then, log in to your Ghost admin panel, navigate to the ‘Design’ section, and click on the ‘Upload a theme’ button. Select the downloaded .zip file and click ‘Upload’. Once the upload is complete, you can activate the theme by clicking on the ‘Activate now’ button.

Where can I find Ghost blog themes?

There are several places where you can find Ghost blog themes. The official Ghost website has a marketplace where you can find both free and premium themes. Other popular sources include ThemeForest, a digital marketplace that offers a wide variety of Ghost themes, and various independent developers who sell their themes on their own websites.

Can I customize my Ghost blog theme?

Yes, you can customize your Ghost blog theme. Ghost themes are built using Handlebars.js, which allows for a high degree of customization. You can change the layout, colors, fonts, and other design elements to suit your specific needs. However, keep in mind that customizing a theme requires some knowledge of HTML, CSS, and Handlebars.js.

Are Ghost blog themes responsive?

Most Ghost blog themes are designed to be responsive, meaning they automatically adjust their layout to fit different screen sizes. This ensures that your blog looks great on all devices, including desktop computers, laptops, tablets, and smartphones. However, it’s always a good idea to check the theme’s description or demo to make sure it’s responsive before you purchase or download it.

How do I update my Ghost blog theme?

Updating your Ghost blog theme is similar to installing a new one. First, you need to download the updated theme file. Then, go to your Ghost admin panel, navigate to the ‘Design’ section, and click on the ‘Upload a theme’ button. Select the updated .zip file and click ‘Upload’. Once the upload is complete, you can activate the updated theme.

What should I look for in a Ghost blog theme?

When choosing a Ghost blog theme, consider factors such as design, responsiveness, customization options, and SEO optimization. The theme should match the style and tone of your blog, be easy to navigate, and look good on all devices. It should also be easy to customize and optimized for search engines to help your blog rank higher in search results.

Can I use a Ghost blog theme on multiple blogs?

Yes, you can use a Ghost blog theme on multiple blogs. However, keep in mind that each blog will need its own Ghost installation. Also, if you purchased a premium theme, make sure to check the license agreement, as some theme developers may limit the number of sites where you can use their theme.

Do I need to know how to code to use a Ghost blog theme?

While you don’t need to know how to code to use a Ghost blog theme, having some knowledge of HTML, CSS, and Handlebars.js can be helpful, especially if you want to customize the theme. However, many themes come with extensive documentation and support to help you set up and customize your blog, even if you’re not a coder.

Are there any free Ghost blog themes?

Yes, there are many free Ghost blog themes available. The official Ghost website offers a selection of free themes, and there are also many independent developers who offer free themes. However, keep in mind that free themes may not come with the same level of support or customization options as premium themes.

Reggie DawsonReggie Dawson
View Author

Reggie is a longtime Network Admin who has finally seen the error of his ways and has come over to the darkside: development. He likes to hack together web projects in his spare time using Angular, Compass, Sass, Bootstrap, or Foundation.

ghost blogghost themeLouisL
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week