Any look. One contract.
The engine decides what a page says and does. The theme decides how it looks. Between them is the storefront contract: every page, every field and every rule, written down and checked.
Same data. Switch the theme.
The product, the price and the form stay the same. Only the theme changes. That is the whole idea of the contract.
Illustrations of three looks. The engine ships no storefront CSS.
Who owns which part.
The theme decides how it looks: Go html/template pages, the CSS, the pictures and a contract.yaml that names the contract version.
The engine gives each page its data and its words, and the parts it depends on: the cart and checkout forms, the order summary and the policy links. A theme places them with template functions.
From the storefront contract (CONTRACT.md) on main, 21 October 2026.
Checked before it serves.
The engine loads the theme once at start. It refuses to serve a theme that breaks the contract, and names every problem. Run the same check yourself before you ship.
engine storefront check \ --config store.yaml \ --templates theme \ --preview previews/
--preview writes the pages with example data, so that you can look at each one.
A contract that only grows.
Version 5 is closed
Its list of additions is final.
Version 6 is open
It can still get additions. From version 6 a theme can also give HTML mail, with its own tokens and components.
A typed contract
A data struct for each page and a generated CONTRACT.md. A test fails when the document and the code differ.
Three places to start.
A small styled theme
Uses every template function and a shared layout partial.
The bare skeleton
One unstyled template for each page.
A full theme
Covers every page and every mail, phone first.
Source: shared-contracts/storefront on main, 21 October 2026.