/Create a WordPress Starter Theme from Scratch
create a wordpress strater theme

Create a WordPress Starter Theme from Scratch

In the following tutorial I will guide you through the entire process of creating a WordPress starter theme from scratch, integrating SASS and Bootstrap.

It seems like most of the people that claim to be “Wordpress developers” are actually “Wordpress implementers”, meaning they take readymade WordPress themes, add some style to it, add a logo, add a bunch of WordPress plugins and walla – they have a site.

Seeing how WordPress is becoming more and more popular by the minute, it should be important for anyone giving WordPress services to be at the top of their game. Meaning, you need to be able to build basically anything a client asks you to, and not be dependent on things that were already built. For that reason, basically any project I take, will be built with a starter theme. So basically I create a WordPress theme from scratch for any project.

Create a WordPress Theme from Scratch – Easier said than done?

Perhaps. In order to be an actual “Wordpress developer” you will need to be fluent in:

  • HTML
  • CSS
    • SASS (Will be discussed later on)
  • Javascript
  • jQuery
  • PHP
  • MYSQL (the amount of MYSQL written in WordPress varies, depending what you are building)

WordPress theme file structure

In order to start building a WordPress starter theme, we will need to understand the structure of a WordPress theme.  So let’s start!

Download WordPress to your local machine from WordPress.org and unzip the files. What we are interested in, is located in: wp-content -> themes

Creating the Starter Theme from Scratch

You will see a few pre-installed themes. In our current location we will create a new folder with the name of the theme that I want to build. Since I’m planning on building a clean starter theme based on Bootstrap, I’m going to call it ScanWP_starter .

The first file a theme has to have is a style.css  file. At the top of the file we must enter a few comments, letting WordPress know what our theme name is, there are many more optional comments, Here is an example of what I’m adding to my starter theme:

Theme Name: ScanWP_starter
Theme URI: http://scanwp.net
Author: Avi Klein
Author URI: https://x2clickseo.com
Description: A clean starter theme based on Bootstrap
Version: 1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: SASS, clean, bootstrap
Text Domain: ScanWP_starter


Here is an explanation of the comments:

  • Theme name: pretty self-explanatory, this is the name of your theme that you will see in your admin
  • Theme URI: the URI that the theme could be downloaded from
  • Author: the name of the actual developer
  • Description: write anything you want about the theme, who it’s meant for etc.
  •  Version: version number if you are planning to upload your theme to the WordPress Repository or any other WordPress Theme store like Themeforest and keep updating it.
  • License: I leave the comment with the GNU license assuming it’s for free use.
  • Same as license URI
  • Tags: If you look through WordPress.org for themes you will see lots of tags such as these. This is where they come from.
  • Text Domain: we won’t talk about this much but it’s the name used by translators of your theme.

Ok, so now that we’ve got that out of the way, we only have 2 more files to add before we can actually activate our new theme: functions.php  and index.php .

You could actually add these 2 files without one letter of code in them. Now your theme can be activated.

However, in order to activate the theme, we need to have an active WordPress installation. If you have one, you can skip ahead, if not – here are your options.

WordPress Local or Server Development

  1. Local development with XAMPP / WAMP / LAMP
  2. Local development with Desktop Server
  3. Development website on a live server

For learning purposes, I would choose a local development; there is no reason to learn on a live server. I’ve built many websites using XAMPP and WAMP but recently shifted to Desktop Server. It seems to make the process a bit more simple but the previous 2 are just fine.

Here is a great write up on installing XAMPP and running WordPress on a local machine.

Activating the WP Theme

So, once you have a WordPress site up and running, we simply navigate from our root folder into the wp-content  folder and in to the themes folder, which is where we were before, in that folder we should now have a folder with our theme name and 3 files in it:

  1. Style.css
  2. Functions.php
  3. Index.php

Now we are ready to activate our new theme and start getting our hands dirty. Log in to your WordPress installation at: {{ yoursitename.com/wp-admin }} and you will be redirected to the login page. Add your username and password and log in. Now navigate to the Appearance tab which will bring you into the themes page.

starter theme in admin

As you can see, my theme is present on the themes page. All I have to do is click the Activate button and our new theme will be in use.

Adding a WordPress Theme Screenshot

Though, if you realized, the pre-installed themes all have a nice screenshot, but our theme doesn’t have an image at all. This part is not mandatory, but if you plan on doing anything with this theme, it would be wise to add an image, and this is how it’s done.

Within our theme folder, we add a file called screenshot.png  with the proportions of 880×660. Now once you refresh the themes page, you will see your theme’s screenshot image. This is what mine looks like:

starter theme in admin

Adding Twitter Bootstrap to our WordPress Theme

First of all, just in case you have never heard of Bootstrap, here is a little preview. I’m not going to go in too deep into how to use it, you can read all about that in the documentation. Bootstrap just makes all the hard work of front-end development much easier. Bootstrap is made for people of basically any skill set. Even if you don’t know HTML & CSS that well, their documentation is perfect and you can just read along and get the hang of it.

Normally, when we develop for front end we have empty HTML tags such as

<div>,<a>,<p> and much more. However, they aren’t styled, meaning we have lots of work to style our entire application. Bootstrap went ahead and created lots of classes that can be used on your site within seconds, making the hard job much easier. There are lots of benefits while using Twitter Bootstrap and one of them being the grid system. Again, we won’t get into that here but you can read all about it.


Go to Bootstrap, there are 2 options of integration that are relevant to our project, downloading the actual files and integrating into our theme or using a CDN. For the purpose of this demonstration we will use the CDN option but feel free to choose the other option on your projects.

Basic Bootstrap Boilerplate

We want to take the basic template and integrate the code in our WordPress theme. The boilerplate code will be separated into 3 groups:

  • Header
  • Footer
  • Content page

In WordPress sites, the entire top area of the site, referred to as a header, is located in a file called header.php , the lower area, referred to as a footer is… you guessed it – located in a file called footer.php  and the rest will be located on the file we are using as our content page.

So, in your theme folder, add 2 new files named header.php and footer.php .

Code to add to the Theme Head

<!DOCTYPE html>
  <head <?php language_attributes(); ?>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <title>;<?php the_title(); ?>;</title>

    <!-- Bootstrap -->
    <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>;
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js">;</script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>

    <?php wp_head(); ?>

  <body <?php body_class(); ?>>


As you can see, I added the entire code up until the opening body tag, added the WordPress language attributes function, the WordPress title function to the title, the wp_head  which is a function that adds all the code needed before the head and the body_class function which gives unique classes to each page depending on a variety of variables.

Code to add to the Theme footer

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->

    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fajax.googleapis.com%2Fajax%2Flibs%2Fjquery%2F1.11.3%2Fjquery.min.js%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>">

    <!-- Include all compiled plugins (below), or include individual files as needed -->

    <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%3Cscript%20src%3D%22https%3A%2F%2Fmaxcdn.bootstrapcdn.com%2Fbootstrap%2F3.3.6%2Fjs%2Fbootstrap.min.js%22%20integrity%3D%22sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS%22%20crossorigin%3D%22anonymous%22%3E%3C%2Fscript%3E" data-mce-resize="false" data-mce-placeholder="1" class="mce-object" width="20" height="20" alt="<script>" title="<script>">

The last piece we need in order to get things going is to include these 2 files in our content file. Currently we are going to use the index.php  file. So, within index.php  add the following:

<?php get_header(); ?>

 <h1><?php the_title(); ?></h1>

<?php get_footer(); ?>


Currently we have our footer set up, out header set up and our content file. If you refresh your site now, you should see the ever known “Hello World!”
tag on the page. Now that we’ve got that working, let’s add some functionality via the functions.php  file.

Code to add to functions.php


add_theme_support( 'title-tag' );

add_theme_support( 'post-thumbnails' );

register_nav_menus( array(

           'primary' => esc_html__( 'Primary Menu', 'custom' ),

     ) );

function custom_widgets_init() {

     register_sidebar( array(

           'name'          => esc_html__( 'Sidebar', 'custom' ),

           'id'            => 'sidebar-1',

           'description'   => '',

           'before_widget' => '<aside id="%1$s" class="widget %2$s">',

           'after_widget'  => '</aside>',

           'before_title'  => '<div class="widget-title">',

           'after_title'   => '</div>',

     ) );


add_action( 'widgets_init', 'custom_widgets_init' );

function custom_scripts() {

     wp_enqueue_style( 'custom-style', get_stylesheet_uri() );

     wp_enqueue_style( 'bootstrap-style' , 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css' );

     wp_enqueue_script( 'custom-script', 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js', array( 'jquery' ), false, true );


add_action( 'wp_enqueue_scripts', 'custom_scripts' );


We’ve added a few basic functions just to make our WordPress theme work properly. Read more about functions.php tips.

  • Adding the title tag option lets me remove it from the header.php  and pull it from within WordPress.
  • Post thumbnails – just as it sounds. Enables the option to have thumbnails on every post on our site.
  • We can build as many navigation menus as we want, though we need to register them first. Here I added one to begin with.
  • The widgets is what wraps each widget you will add from within the admin.
  • wp_enqueue_style  + wp_enqueue_script  is a bit weird at first but it makes a lot of sense. Each script or css file you want to link to should be done from here. So I’ve added our Bootstrap css and Javascript files here and removed them from the HTML. The last line has a few more parameters, here is the explanation: add the script with a jQuery dependency, do not add the WordPress version to the end of the link and the last true is to add the script in the footer instead of header. If you have any further questions about wp_enqueue  you can read up about it in the WordPress codex.

Adding a Navbar to the WordPress Starter Theme

Now that we have a skeleton of our site, lets add a Bootstrap Navbar to our site header. There are many types of navbars that can be used and they are pretty flexible, I took the main navbar and removed most of its functionality and integrated the WordPress menu into it.

This is what my header.php looks like now:

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>


<link rel="profile" href="http://gmpg.org/xfn/11" />

<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />

<meta name="viewport" content="width=device-width, initial-scale=1">

<?php wp_head(); ?>


<body <?php body_class(); ?>>

  <div class="container-fluid">

    <nav class="navbar navbar-default">

      <div class="container-fluid">

        <!-- Brand and toggle get grouped for better mobile display -->

        <div class="navbar-header">

          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">

            <span class="sr-only">Toggle navigation</span>

            <span class="icon-bar"></span>

            <span class="icon-bar"></span>

            <span class="icon-bar"></span>



        <!-- Collect the nav links, forms, and other content for toggling -->

        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">

          <ul class="nav navbar-nav">


              // Get the nav menu based on $menu_name (same as 'theme_location' or 'menu' arg to wp_nav_menu)

            // This code based on wp_nav_menu's code to get Menu ID from menu slug

            wp_nav_menu( array('menu' => 'primary', 'items_wrap' => '<ul><li id="item-id"></li>%3$s</ul>' ));



        </div><!-- /.navbar-collapse -->

      </div><!-- /.container-fluid -->



I started off the page with a container-fluid so we get a full width page, if you want, you can change that into a container class to have a fixed width. Then I added the Bootstrap navbar and added the wp_nav_menu  function. You can read more about the navigation abilities here.

The WordPress Loop

Lots of the dynamic content we print out on a page comes from a unique WordPress loop. Assuming you know PHP this will be easy for you to understand, if not – tough luck building WordPress sites entails programming.

The WordPress loop is very easy to implement. Go look at your index.php  page, currently we are calling the header and footer and were able to call the page title. Now if we want to get any other content onto our page we need to add it using the loop (we will push the title into the loop as well.

Paste this code over our existing code on the index.php  file:

<?php get_header(); ?>

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

  <h1><?php the_title(); ?></h1>
  <?php the_content(); ?>

<?php endwhile;  endif;?>

<?php get_footer(); ?>


Pretty simple, right? the_content();  function will print out all the content in the main meta box area within your admin.

The WordPress Theme Homepage

WordPress lets us decide whether we want the homepage to show the last posts as a blog view or use an existing page as the homepage. However, there is a third option which is the only one I ever use. If you add a file called front-page.php ,  you can do anything you want. So, adding the exact code we just added to the index page to a new front-page.php  file will give you just that. Just to make sure everything is working correctly, within the loop I’ll add a sentence “this is the homepage” and make sure I see it on the homepage.

Adding Page Type Templates (Not Page Templates) to the Theme

There are a bunch of types of pages and layouts on sites. Some of these are:

  • 404 template
  • An archive page
  • A category page
  • A post
  • A page

WordPress has a well-built structure, without making any changes in the admin, we can control what file will be used as a template for the site content. To make things simple – index.php  is the fallback file for everything basically. As we just saw, when I didn’t define a homepage, WordPress used the fallback file. If we wouldn’t define a template for the post or page, WordPress would do the same thing.

For this theme I will build a few basic templates that I usually use, feel free to add more if you need them.

Creating a Post and Page Template

The post template is called single.php and the page is simply page.php . Since I’m creating a clean starter theme, I’m going to keep it as simple as possible, just as I did for the homepage. So, I’ll copy my code from the homepage and paste it into my 2 new files.

At this point, just to make sure everything was done correctly, add a unique sentence on each of your new templates, navigate into the dashboard, view your sample page that WordPress pre populated and view it. Do the same for the post. If your pages appear with the sentence you added (a different one for the page and post), you are golden.

Creating a Category and Archive Template

Same exact process, just add 2 files:

  • archive.php
  • category.php

The code here is identical too. Since we are in a loop, you will see all the content, no matter if you have 1 or 5 entries.

Creating a 404 Template

This process is a bit different, here we can just add a Nice message for the user. Add whatever you want in a file called 404.php  .

Adding SASS into a WordPress Theme

Integrating SASS into your theme should be a default, if you haven’t started using SASS yet – here is a short recap.

SASS = Syntactically Awesome Stylesheets.

SASS files are compiled into CSS files, so basically the browser is still reading your regular css files, however these css files were compiled from multiple SASS files. SASS is normally split up into lots of subject related files. For instance you might have a settings.scss, menu.scss, admin.scss  etc. and one CSS file that was created via a compiler.

So, how do we begin?

First of all, in order to run a compiler, you would normally develop locally and then upload the compiled file to the live server when done. The compiler I use and highly recommend is – Prepros which has a trial option, so feel free to check it out before using.

Once you have Prepros running on your local machine, press the “Add Project” button on the bottom left and choose the main folder you have WordPress set up on.


Once Prepros is set up, you will see all the WP files in the right area just like on the image above. Now click above on the “more options” button and click on “project options”. Navigate to the CSS tab and remove whatever is written in the second field, your project should now look like this:


Now save options. What we did here is tell Prepros to compile the css file in our theme’s root folder. In our case in will compile the css file into our theme’s style.css  file.

I highly recommend you read up on SASS tutorials if you haven’t used it before.

Now all I need to do is create a new folder which I will name sass in my theme root and inside it I will create 2 files. style.scss and scanwp.scss. The second name will be for some of my global settings and styles, you could name it as you like. The first is named style since this file will be importing all the SASS files and compiling a file names style.css which we need to have in WordPress any way. Remember the comment we added in our style file? Well, we need to add it to the SASS file now, so my style.scss file looks like this:

Theme Name: ScanWP_starter
Theme URI: http://scanwp.net
Author: Avi Klein
Author URI: https://x2clickseo.com
Description: A clean starter theme based on Bootstrap
Version: 1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: SASS, clean, bootstrap
Text Domain: ScanWP_starter

@import "scanwp";


This way, the first thing on the style file will be my comment and then everything else.

Just to make sure it works, add a regular css rule to both files and make sure they are compiled into your style.css file in the root.

Well… that’s it!

What do you think? Are you ready to take your developing skills to the next level?

Just in case you had a hard time keeping up, you can download the theme zip here:

Join Thousands of Others and Never Miss a Post