Guide · Shopify themes

Building a Shopify theme
from scratch

Starting from a blank theme — not Dawn, not a starter kit — gives you a codebase you fully understand. Here's what the structure looks like and how to think about each layer before writing a single line of Liquid.

Why start from scratch

You own every line

Forking Dawn means inheriting its CSS architecture, its JavaScript modules, its section assumptions. On a large custom project, that inherited weight becomes friction — you spend time working around the base theme rather than building the store.

Performance is structural

Dawn ships with Web Components and a custom JS module system that adds ~80KB of JavaScript to every page. A blank theme starts at zero — you add only what the store actually needs.

Cleaner handoffs

A custom-built theme has a coherent architecture. Another developer picking it up doesn't need to untangle what's base theme, what's override, and what's app injection.

Folder structure

01

config/

Two files: settings_schema.json defines every global theme setting (colors, typography, spacing scales), and settings_data.json stores the merchant's saved values. Everything visual that should be controllable from the admin without code lives here.

02

layout/

theme.liquid is the root document — <html>, <head>, global scripts, and the {{ content_for_layout }} tag that renders each page. Keep this file small. It runs on every request.

03

sections/

One file per section. Each file contains the Liquid markup, a {% schema %} block that defines its settings and blocks, and optionally scoped CSS. Sections are the main unit of customization — design them to be self-contained.

04

templates/

JSON templates (product.json, collection.json, index.json) that compose sections into pages. The merchant drags, reorders, and configures in the Theme Editor — templates define what sections are available and in what order.

05

snippets/

Reusable Liquid partials included via {% render 'snippet-name' %}. Product cards, icon sprites, price formatting — anything used in more than one section belongs here. Keep snippets stateless: pass data in via parameters, don't rely on global scope.

06

assets/

CSS, JavaScript, fonts, icons. Shopify serves everything from this folder via its CDN. Reference files with {{ 'file.css' | asset_url }} — the CDN fingerprints them automatically for cache busting.

The settings_schema.json pattern

01

Define design tokens as theme settings

Expose brand colors, font families, and base spacing as settings. Map them to CSS custom properties in theme.liquid via an inline <style> block. The merchant changes a color in the admin — the CSS variable updates everywhere instantly, no code deploy.

02

Group settings logically

settings_schema.json is an array of groups. Use headers to separate Colors, Typography, Layout, and Social. A cluttered, flat list of 40 settings is hard to use; a structured schema with clear headings isn't.

03

Don't expose what shouldn't change

Not every design decision needs a toggle. Structural choices — grid columns, section max-width, transition duration — are better hardcoded than exposed to accidental changes. Fewer settings means fewer ways to break things.

Related