theme.json
The manifest is how your theme tells the platform what it is: which pages it provides, which fields a merchant may edit, and the palette the editor offers.
Shape
{
"id": "mecsto/aurora",
"name": "Aurora",
"version": "1.0.0",
"pages": {
"home": "/",
"listing_index": "/listing",
"listing_detail": "/listing/[slug]"
},
"editable": {
"hero.title": { "type": "text", "label": "Hero heading" },
"hero.image": { "type": "image", "label": "Hero image" },
"hero.body": { "type": "richtext", "label": "Hero copy" }
},
"palette": { "accent": "#1f6feb" }
}editable
Every key here becomes a field in the merchant’s visual editor. A field you do not declare cannot be edited — which is the point: you decide what a merchant can change without being able to break your design.
Bind them in your components with EditableField, EditableImage, EditableRichText or EditableList from the SDK. Declared-but-unbound fields, and bound-but-undeclared paths, both fail pnpm theme:check.
Pick editable fields conservatively. Every editable field is a way for a real merchant to make your theme look worse. Expose the ones that carry their identity — headline, imagery, colour — and keep structural choices to yourself.
palette
A single accent colour. Merchants customise the accent and nothing else: not fonts, not spacing, not layout. That constraint is deliberate — it keeps every store on your theme recognisably your theme.