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
01config/
Two files: settings_schema.json defines every global theme setting (colors, typography, spacing scales), andsettings_data.json stores the merchant's saved values. Everything visual that should be controllable from the admin without code lives here.
02layout/
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.
03sections/
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.
04templates/
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.
05snippets/
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.
06assets/
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
01Define design tokens as theme settings
Expose brand colors, font families, and base spacing as settings. Map them to CSS custom properties in theme.liquidvia an inline <style> block. The merchant changes a color in the admin — the CSS variable updates everywhere instantly, no code deploy.
02Group 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.
03Don'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.