Installing a Theme
jekcms themes control the public-facing look of your site: templates, CSS, layout variants, and customizer options. Every install ships with a built-in starter theme so a fresh site renders something sensible out of the box.
This page covers the two installation paths, how activation works in a multi-site setup, and how to cleanly remove a theme you no longer need.
Where themes live
Themes are plain folders under /themes/{slug}/. Each theme folder needs at minimum:
themes/
my-theme/
theme.json
templates/
header.php
footer.php
index.php
single.php
assets/
css/style.css
The folder name (my-theme) is the slug jekcms uses to reference the theme everywhere — in the database, in per-site overrides, and in the admin UI. It must be lowercase, hyphen-separated, no spaces.
Installation path 1 — drop into /themes/
If you have shell/FTP access (self-hosted installs), extract the theme directly into /themes/ and that's it. jekcms auto-discovers any folder containing a valid theme.json on the next admin page load.
cd /var/www/jekcms/themes
unzip ~/downloads/ocean-theme.zip
# -> creates themes/ocean/
Installation path 2 — upload ZIP via admin
Appearance → Themes → Upload Theme accepts a ZIP. jekcms unpacks it into /themes/, validates the theme.json, and rejects the upload if required fields are missing or the slug collides with an existing theme.
Managed/hosted installs typically disable path 1 and force path 2 for safety.
A minimal theme.json
Every theme must have a theme.json at its root:
{
"name": "Ocean",
"slug": "ocean",
"version": "1.0.0",
"author": "Your Name",
"description": "A clean coastal theme.",
"license": "free"
}
The slug field must match the folder name. Set "license": "premium" to mark a paid theme (see below). See the [theme.json schema reference](/docs/themes/theme-json-schema) for the full field list.
Activating a theme
Appearance → Themes lists every discovered theme with a preview thumbnail. Click Activate on the one you want live. Activation is instant — no cache bust required. The active theme's slug is saved to the active_theme site option.
Per-site vs native theme hierarchy
On multi-site installs the hierarchy is:
- Per-site override — each site can pin its own
active_theme. This beats everything else. - Network default — set in Network Admin → Settings → Default Theme. Used for any site that hasn't picked its own.
- Built-in fallback —
starter. Used if neither of the above resolves to a valid installed theme (e.g., the chosen theme's folder was deleted).
jekcms walks this list top-to-bottom and renders the first theme that exists on disk. A broken per-site pick falls back to the network default, not to a blank page.
The starter theme
themes/starter/ ships with every install and cannot be deleted through the admin UI. It exists as a guaranteed render target — if something goes sideways with your active theme, jekcms can always fall back to starter.
Treat starter as a reference implementation, not a foundation for customization. If you want to tweak it, duplicate the folder under a new slug and activate the copy instead.
License-gated premium themes
Themes marked "license": "premium" in their theme.json only activate when the install has a STD license or higher. On FREE-tier installs:
- Premium themes are visible in Appearance → Themes but the Activate button is disabled
- A tooltip explains the tier requirement and links to the upgrade page
- Attempting activation via the REST API returns
403 Forbiddenwithlicense_required
License status is checked at activation time and on every page render — downgrading from STD to FREE auto-reverts your site to the network default theme on the next request.
Removing a theme safely
Before deleting anything:
- Make sure the theme isn't the active theme on any site (check Network Admin → Sites → Active Theme column)
- Make sure it isn't the network default
Then remove it either via Appearance → Themes → Delete or by deleting the /themes/{slug}/ folder. jekcms re-scans on the next admin page load and drops it from the list.
Deleting a theme does not delete the customizer values associated with it. If you reinstall the same slug later, your previous customization comes back.