---
title: Shopify Theme Development
teaser: Develop a Shopify theme from scratch.
tags: web,design,shopify
author: Ward Penney
published_on: 2015-01-27
---

Shopify has fostered a good-sized community of [themes for
sale][shopify-theme-store], and lot of them can be configured easily. However,
they may not have the right combination of features, support, content priority,
and brand feel that you are looking for. In that case, it is reasonable to find
a Shopify partner (such as [thoughtbot][thoughtbot]) to build you one from
scratch.

This article is intended to be a guide for the developer or designer tasked
with building a Shopify theme.

## Shopify theme developer stack

Developing a theme for Shopify is a little bit different than for something like
Wordpress. First of all, you do not run a local server instance or database. I'm
not sure why, but I bet it is because Shopify made a choice to reduce complexity
for the entire community by hosting and guaranteeing the quality of the data
model.  That way, you don't have to worry about ever updating your server.

Instead, you work locally and use a syncing utility to *push* your changes to the
server instantly, where you can view them. Shopify officially supports two utilities
for syncing:

* [shopify_theme gem][shopify-theme-gem] is a RubyGem for the command-line.
* The [Shopify Desktop Theme Editor][shopify-desktop-editor] is a Mac App and
  text editor.

If you are comfortable with the command-line, I highly recommend the
[shopify_theme gem][shopify-theme-gem]. The rest of this guide will assume you
made this choice.

There are other utilities out there, such as [grunt-shopify][grunt-shopify], but
I have not experimented with them.

## The Shopify asset CDN

Every asset you push up to the server (images, fonts, CSS, JavaScript) is
automatically deployed, concatenated, minified (except for JavaScript), gzipped,
and finger-printed on Shopify's CDN. The templating language provides you with
asset helpers to reference the assets.

So, you have everything you need for asset packaging and delivery. However, it
does create issues when developing because you are looking at minified CSS. The
JavaScript is not minified or uglified.

## Developing with a starter theme

Like any hosted CMS platform, there are a multitude of small details that are
specific to that platform. Choosing to use a starter theme helps you understand
the low-hanging fruit of the platform as quickly as possible without spending
too much time Googling the basics.

Shopify officially supports two starter themes:

* The [Shopify Skeleton Theme][shopify-skeleton-theme] has more minimal styling,
  although it does contain a simple grid system and basic styling.
* The [Shopify Timber Theme][shopify-timber-theme] has more styling to start,
  includes the [csswizardry-grids][csswizardry-grids] grid system, a version of
  Bootstrap, a fancy Ajax cart and a live style guide.

On my latest project, I chose Timber because both projects have some level of
styling and layout, and the styling markup is already littered throughout the
templates. If I *truly* wanted to start from scratch, I'd have to go in and
remove all the classes and start over with the Sass. I didn't have time for
that, so I decided to leverage Timber.

I had never used [csswizardry-grids][csswizardry-grids] before, but it works
just fine and has not created any blockers for me.

## Shopify theme developer workflow

Once your sync is up and running with [shopify_theme gem][shopify-theme-gem], be
careful because by default you will be **syncing directly to production**.  If
you do not specify a `theme_id` in your configuration file, the default is to
push to the currently published theme. Typically this is only comfortable for a
day or two, but the moment your client wants begin showing it to others
(investors, co-founders, friends, etc.) you should consider switching to a more
stable workflow.

We wanted to create something similar to how [thoughtbot][thoughtbot] works on
any other project. We want an environment where we have:

* Feature branches
* Green tests (we'll get to that)
* Pull requests

In the Shopify world, because they own the server and database, the traditional
concept of **production** environment is a bit different. you have to think
about the **published theme** instead. That is the theme currently published and
live on the site. It is possible to have additional unpublished themes that an
administrator can view but don't show up for regular users. We can leverage this
with the [shopify_theme gem][shopify-theme-gem].

## Shopify theme development workflow

Here is our typical workflow for a single feature branch:

1. Pull from `master` and checkout a new branch
* Log into Shopify store admin
* Duplicate the **published theme** theme
* Rename the duplicated theme to the name of your branch
* Click "Customize Theme" of your new branch theme
* Note the theme ID in the URL (example: `/admin/themes/9542224/settings`)
* Edit the `theme_id` in `config.yml` to point to your branched theme
* `theme watch` and do your work
* Preview your work by navigating to that theme in Shopify admin and clicking
  preview
* Pull Request
* Rebase onto master, push to master repo
* Delete your branch (local and server)
* Delete your branched theme in Shopify Admin

## Deployment

When it's time to deploy, force-deploy the theme in the master branch onto the
production site:

1. Make sure to kill your local theme watcher
* Remove your theme ID (to point it to the **published theme**)
* `theme upload` to push master onto the primary theme. If you have deleted
  files you can also run `theme replace`.

If you're doing it right, you should always be confident in pushing master onto
the **published theme**, provided you blacklisted the `settings_data.json`.

## Ignore the Shopify theme settings data

As a developer, you can expose theme settings to the admin user by adding to
`config/settings.html`. When an admin changes a setting, it is written to
`config/settings_data.json` on the server, however the `theme watch` is **not a
two-way street**. The local copy of `config/settings_data.json` will not reflect
settings made through the admin interface, and if you edit it locally, it will
**push up and overwrite** what is on the server. Therefore, it is best to ignore
this file altogether from your repository and let it live only on the server.

Update the `config.yml`:

```yaml
:api_key: 000000000000000000000000000000
:password: 000000000000000000000000000000
:store: mystore.myshopify.com
:theme_id:
:ignore_files:
- config/settings_data.json
```

Update the `.gitignore`:

```gitignore
config/settings_data.json
```

## Shopify's pseudo-staging environment

The workflow discussed so far set up a pseudo-staging environment. Admin users
can view the branched themes to work on development, or do acceptance, but the
underlying database **is still the production database**. However, this has not
been a problem for us because we almost never affect the data while developing,
testing or just clicking around.

The final step of *checkout* (actually clicking purchase) needs very little
testing because that portion is hosted by Shopify and has it's own test coverage
provided by Shopify (presumably). Even if we did purchase a product and thereby
decrease inventory, we can cancel it right away in the admin.

## Maintaining a true Shopify staging environment

It would be plausible to create a second development store, entirely separate
from the production store. As a Shopify Partner, you can do that easily and for
free. However, it would expose some considerations that must be handled to use
it effectively:

* The client will likely be affecting product data constantly (images, options,
  variants, etc.) and the data on a true staging environment would likely grow
  stale quickly.
* The client and other admins will be affecting theme settings frequently. Which
  means the `config/settings_data.json` file on production would also have to be
  synced frequently to staging to create a realistic production environment.

Therefore, I would be resistant to creating a completely stand-alone staging
environment until we had a compelling reason to incur those costs. We have not
had one yet.

## Using Sass with Shopify

In the Spring of 2013, Shopify [introduced Sass](https://ecommerce.shopify.com/c/ecommerce-design/t/you-can-now-use-scss-in-shopify-s-template-editor-133389)
(scss syntax only) compilation to their themes. If you are new to Sass, it is a
CSS pre-compiler that gives you a lot of very handy things (variables, control
flow, includes, etc.).

However, on Shopify, you can not use the Sass `@import` rule because of how the
Liquid templates are included. If you have multiple stylesheets, you can use the
CSS `@import`, but that will not carry your Sass variable namespace across files
because it occurs in the browser, after the Sass has been compiled and delivered
to the user.

That means you have a choice between:

* One long Sass file that contains all the things
* Not using Shopify's Sass compilation, compiling locally in development, and
  pushing up the rendered CSS.

Consider what level of ongoing support you need to provide. Unless the team
using the theme going forward has developers, it is best to let Shopify perform
the Sass compilation. That way, an admin can make small changes and not require
a full development machine setup.

## Other Reading

* Learn how to [separate your rending vs. non-rendering sass](https://thoughtbot.com/blog/separate-rendering-sass-from-non-rendering-sass)
  for better Sass file organization

[thoughtbot]: http://thoughtbot.com/
[shopify-theme-store]: https://themes.shopify.com/
[shopify-theme-gem]: https://github.com/Shopify/shopify_theme
[shopify-desktop-editor]: https://apps.shopify.com/desktop-theme-editor
[grunt-shopify]: https://github.com/wilr/grunt-shopify
[shopify-skeleton-theme]: http://shopify.github.io/skeleton-theme/
[shopify-timber-theme]: http://shopify.github.io/Timber/
[csswizardry-grids]: http://csswizardry.com/csswizardry-grids/

[shopify-theme-docs]: http://docs.shopify.com/themes
[shopify-design-forums]: https://ecommerce.shopify.com/c/ecommerce-design
