themes
Theme package format
The files, theme.json v2 manifest, limits and versioning rules for a SaaS theme package.
A theme is a ZIP archive. Paths are case-sensitive and use lower-kebab-case names.
Files
| Path | Purpose |
|---|---|
theme.json | Manifest (required) |
templates/<type>.<name>.json | Templates such as home.default.json or product.luxury.json |
sections/<type>/schema.json | Section schemas |
blocks/<type>/schema.json | Block schemas |
snippets/<name>.json | Shared JSON fragments |
config/settings.schema.json, config/settings.defaults.json | Theme settings and defaults |
locales/ar.json, locales/en.json | Storefront strings |
migrations/<from>-<to>.json | Declarative setting migrations between versions |
assets/** | .css, .png, .jpg, .jpeg, .webp, .avif, .gif, .svg, .woff, .woff2 |
README, CHANGELOG, LICENSE | Optional text files |
Any other file type or location is rejected, including scripts, HTML, symlinks and hidden files.
theme.json
{
"schemaVersion": 2,
"id": "luxe-perfume",
"name": { "ar": "لوكس للعطور", "en": "Luxe Perfume" },
"version": "1.1.0",
"publisher": "my-studio",
"description": { "ar": "…", "en": "…" },
"minimumPlatformVersion": "1.0.0",
"sdkVersion": "2.0.0",
"supportedLocales": ["ar", "en"],
"rtl": true,
"templates": [{ "id": "home.default", "type": "home", "file": "templates/home.default.json" }],
"sections": [{ "type": "hero", "file": "sections/hero/schema.json" }],
"blocks": [{ "type": "heading", "file": "blocks/heading/schema.json" }],
"settingsSchema": "config/settings.schema.json",
"locales": ["locales/ar.json", "locales/en.json"],
"assets": ["assets/theme.css"]
}Only the documented top-level keys are accepted. A theme must include Arabic, support right-to-left layout and provide a home template. The full example is examples/themes/luxe-perfume in the platform repository.
Limits
| Limit | Value |
|---|---|
| Archive size | 50 MB |
| Entries | 2,000 |
| Single file | 10 MB |
| Total uncompressed size | 100 MB |
| Compression ratio | 100:1 |
| One JSON file | 2 MB |
| Compiled theme CSS | 256 KB |
Encrypted, multi-disk or corrupt archives are rejected before anything is stored.
Versions
version is MAJOR.MINOR.PATCH and must increase with each version you register. A version is immutable once submitted: to change anything, push a new version. The platform records the SHA-256 of your source package and of the built artifact, and verifies the artifact hash every time it is loaded.
Migrations
When a version renames or removes settings, ship a migration so merchants keep their customisations:
{
"from": "1.0.0",
"to": "1.1.0",
"operations": [
{ "op": "rename_setting", "scope": "theme", "from": "layout_width", "to": "page_width" },
{ "op": "set_value", "scope": "section", "type": "hero", "id": "overlay", "value": 30, "onlyIfMissing": true }
]
}Other operations are remove_setting, move_setting_to_block, rename_section_type, rename_block_type and rename_template. Before a merchant applies an update, they see a report of what is kept, migrated and dropped; nothing is dropped silently.