Theme Development
Build Theme Packs and understand when Theme Apps are appropriate in Jiffoo Mall
Theme Development Guide
Jiffoo currently supports two theme shapes:
Theme Pack: the default and recommended path for storefront customizationTheme App: an executable Next.js storefront package for advanced internal or white-listed use cases
If you are building a new third-party theme, start with a Theme Pack.
Choose the Right Theme Shape
| Shape | Use when | Runtime model |
|---|---|---|
Theme Pack | You need branding, layout, templates, assets, and app blocks/embeds | Rendered by the main Shop app |
Theme App | You need a standalone storefront runtime and can ship a built Next.js app | Started by the API runtime as a local child process |
Theme Pack
Theme Packs are resource packages. They do not ship executable React or Next.js runtime code.
Official first-party storefront themes can still keep an embedded renderer package for full-site rendering, but their downloadable marketplace source of truth should live in committed theme-pack/ files rather than being synthesized during artifact build.
Contract
A Theme Pack is rooted by theme.json and usually contains:
my-theme-pack/
├── theme.json
├── tokens.css
├── templates/
│ ├── home.json
│ └── product.json
├── assets/
│ └── hero-banner.webp
└── schemas/
└── settings.schema.jsonMinimal theme.json
{
"schemaVersion": 1,
"slug": "modern-travel",
"name": "Modern Travel",
"version": "1.0.0",
"target": "shop",
"description": "Travel-focused storefront theme pack",
"entry": {
"tokensCSS": "tokens.css",
"templatesDir": "templates",
"assetsDir": "assets",
"settingsSchema": "schemas/settings.schema.json"
},
"defaultConfig": {
"colors": {
"primary": "#0f766e",
"background": "#f8fafc"
}
}
}Templates and Blocks
- Page structure is defined by JSON templates under
templates/ - Blocks are rendered through the platform block registry
- Plugin storefront extensions can add
app blockandapp embedcontent on top of a Theme Pack
Theme Pack contract source:
apps/shop/lib/theme-pack/types.tsapps/shop/lib/theme-pack/template-renderer.tsxapps/shop/lib/theme-pack/app-block-renderer.tsxapps/shop/lib/theme-pack/app-embed-injector.tsx
Theme App
Theme Apps are standalone Next.js builds packaged for installation. They are not the default theme model.
Current Support Boundary
The current core runtime only supports:
- manifest file:
theme-app.json - runtime kind:
next-standalone - startup model: API process spawns the built app as a child process
- supported deployment shape: a single API replica unless you intentionally bypass the guard
The current open-source runtime does not provide Kubernetes orchestration for Theme Apps. If you need independently deployed storefront services, treat that as a platform extension beyond the current built-in runtime.
Contract
my-theme-app/
├── theme-app.json
├── server.js
├── .next/
│ └── static/
└── public/Minimal theme-app.json
{
"schemaVersion": 1,
"type": "theme-app",
"slug": "modern-travel-app",
"name": "Modern Travel App",
"version": "1.0.0",
"target": "shop",
"runtime": {
"kind": "next-standalone",
"entry": "server.js",
"healthPath": "/api/health"
},
"port": {
"preferred": 3100,
"range": { "min": 3100, "max": 3199 }
},
"healthCheck": {
"timeout": 5000,
"retries": 3,
"retryInterval": 2000
}
}Theme App contract source:
apps/api/src/core/admin/theme-app-runtime/contract.tsapps/api/src/core/admin/theme-app-runtime/manager.tsapps/api/src/core/admin/extension-installer/theme-app-installer.ts
Theme API Access
When a theme needs to call platform APIs, use @jiffoo/theme-api-sdk rather than a legacy theme SDK.
pnpm add @jiffoo/theme-api-sdkimport { createThemeApiClient } from '@jiffoo/theme-api-sdk';
const api = createThemeApiClient({
baseUrl: process.env.NEXT_PUBLIC_API_BASE_URL!,
token: async () => localStorage.getItem('token'),
});Recommendations
- Default to Theme Packs for third-party theme development.
- Use Theme Apps only when a standalone storefront runtime is genuinely required.
- Keep plugin storefront integrations in
app block/app embedform wherever possible. - Treat
theme-app.jsonas the only valid Theme App manifest filename.