Jiffoo Docs
Developer

Theme Development

Single source guide for developing Theme Packs and Theme Apps on the current runtime

Theme Development (Single Source)

This is the only developer guide for theme development in this repository.

It covers both theme types supported by current runtime code:

  • Theme Pack (default path)
  • Theme App (advanced executable path)

If you are building a third-party theme, start with Theme Pack unless you explicitly need an executable storefront runtime.

1. Scope and Relationship to Plugins

Theme development and business plugin development are separate tracks.

  • Themes control storefront/admin presentation and rendering behavior.
  • Business plugins provide backend capability through plugin runtime (external-http / internal-fastify).
  • A business plugin can expose app block / app embed via themeExtensions, but it is still a plugin, not a theme.

Use this doc for theme-* and theme-app-* development only.

2. Theme Shapes and When to Use Them

ShapeBest forRuntime model
Theme PackBranding, layout, templates, assets, block compositionRendered by built-in theme runtime
Theme AppFully executable storefront with custom runtime behaviorSpawned as child process by API runtime

3. Installer Kinds and Manifest Files

Theme installation uses POST /api/v1/admin/extensions/:kind/install.

Kinds:

  • theme-shop -> Theme Pack (theme.json, target shop)
  • theme-admin -> Theme Pack (theme.json, target admin)
  • theme-app-shop -> Theme App (theme-app.json, target shop)
  • theme-app-admin -> Theme App (theme-app.json, target admin)

4. Theme Pack Contract

Theme Pack is a static resource package. Do not ship executable runtime code.

my-theme-pack/
├── theme.json
├── tokens.css
├── templates/
│   ├── home.json
│   └── product.json
├── assets/
│   └── hero-banner.webp
└── schemas/
    └── settings.schema.json

Minimal 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"
    }
  }
}

Pack development rules

  • Use JSON templates under templates/ to define page structure.
  • Use CSS tokens and static assets for visual system.
  • Keep customization inside block/slot contract.
  • Do not put executable JS/TS runtime code in the package.

5. Theme App Contract

Theme App is an executable package with built output.

Supported runtime boundary (current code)

  • manifest filename must be theme-app.json
  • runtime.kind must be next-standalone
  • API runtime starts app via node <runtime.entry>
  • health checks must pass before activation completes
  • runtime state is process-local (single replica is the safe shape)
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": {
    "path": "/api/health",
    "timeout": 5000,
    "retries": 3,
    "retryInterval": 2000
  }
}

Theme App activation behavior

Activation is fail-safe:

  1. API reads active theme state.
  2. API starts Theme App runtime.
  3. API performs health checks.
  4. Active theme switches only after healthy startup.

If startup or health check fails, active theme stays unchanged.

6. Theme Runtime and Routing Behavior

  • Theme Pack uses built-in renderer in Shop/Admin apps.
  • Theme App traffic is proxied through /theme-app/{target}/{slug}/*.
  • Theme API routes (/api/*) remain owned by platform API.
  • Plugin gateway routes (/api/v1/shop/plugins/{slug}/api/*) remain independent from theme runtime.

7. Theme + Plugin Integration Model

Theme and plugin integration should follow this pattern:

  • Theme defines layout and rendering slots.
  • Plugin provides dynamic business capabilities and data endpoints.
  • Plugin themeExtensions contributes app block / app embed into theme rendering.

Do not move plugin business logic into theme packages.

8. Local Development and Packaging

Theme Pack

  • edit theme.json, templates, tokens, and assets
  • create zip with package root containing theme.json
  • upload via Theme install in Admin

Theme App

  • build standalone output first
  • ensure theme-app.json points to built runtime.entry
  • include required static artifacts (.next/static, public as needed)
  • zip built package root and upload in Admin

9. Minimal Submission Directory Templates

Use these as copy-paste starting points before zipping.

Theme Pack (shop/admin)

my-theme-pack/
├── theme.json
├── tokens.css
├── templates/
│   ├── home.json
│   └── product.json
├── assets/
│   └── hero-banner.webp
└── schemas/
    └── settings.schema.json

Minimal theme.json for submission:

{
  "schemaVersion": 1,
  "slug": "my-theme-pack",
  "name": "My Theme Pack",
  "version": "1.0.0",
  "target": "shop",
  "entry": {
    "tokensCSS": "tokens.css",
    "templatesDir": "templates",
    "assetsDir": "assets",
    "settingsSchema": "schemas/settings.schema.json"
  }
}

Theme App (shop/admin)

my-theme-app/
├── theme-app.json
├── server.js
├── .next/
│   └── static/
└── public/

Minimal theme-app.json for submission:

{
  "schemaVersion": 1,
  "type": "theme-app",
  "slug": "my-theme-app",
  "name": "My Theme App",
  "version": "1.0.0",
  "target": "shop",
  "runtime": {
    "kind": "next-standalone",
    "entry": "server.js",
    "healthPath": "/api/health"
  }
}

ZIP notes:

  • ZIP root must contain theme.json or theme-app.json directly, or contain a single wrapper folder with that manifest.
  • Upload with the correct kind for target and shape (theme-shop, theme-admin, theme-app-shop, theme-app-admin).

10. Acceptance Checklist

Before upload:

  • manifest file exists and validates (theme.json or theme-app.json)
  • slug/version/target are correct
  • package structure matches selected kind
  • no disallowed artifacts for selected theme shape

After install:

  • theme appears in installed list for target (shop or admin)
  • activation succeeds
  • storefront/admin renders correctly
  • rollback to previous theme works

Theme App extra checks:

  • runtime process starts successfully
  • health check passes within configured retries
  • proxied traffic works through /theme-app/{target}/{slug}/*

11. Authoritative Code References

Use these files as runtime truth when updating this document:

  • apps/api/src/core/admin/extension-installer/types.ts
  • apps/api/src/core/admin/extension-installer/theme-installer.ts
  • apps/api/src/core/admin/extension-installer/theme-app-installer.ts
  • apps/api/src/core/admin/theme-app-runtime/contract.ts
  • apps/api/src/core/admin/theme-app-runtime/manager.ts
  • apps/api/src/core/admin/theme-app-runtime/gateway.ts
  • apps/api/src/core/admin/theme-management/service.ts
  • apps/shop/lib/theme-pack/types.ts
  • apps/admin/lib/theme-pack/types.ts

When this document conflicts with runtime behavior, update this document to match code.

On this page