skin.json manifest, a PHP class that extends one of the skin base classes, and ResourceLoader module declarations for your CSS and JavaScript.
skin.json structure
Every skin must have askin.json file in its root directory. This file is read by ExtensionRegistry when wfLoadSkin() is called.
skins/MyTheme/skin.json
The internal skin name (the key in
ValidSkinNames, "mytheme" above) must be lowercase. It is used for CSS class names, message keys (skinname-mytheme), and per-skin customisation pages (MediaWiki:Mytheme.css).Key skin.json fields
| Field | Description |
|---|---|
name | Display name of the skin |
namemsg | i18n message key for the skin name (used in Special:Preferences) |
descriptionmsg | i18n message key for the skin description |
ValidSkinNames | Maps skin key to class and constructor args |
ResourceModules | ResourceLoader module definitions |
MessagesDirs | i18n directory paths |
AutoloadNamespaces | PSR-4 namespace to directory mapping |
SkinTemplate vs. Skin base class
MediaWiki provides two main base classes for skin development:Skin
The abstract base. Provides
getTemplateData(), buildSidebar(), buildNavUrls(), initPage(), and navigation building. All skins ultimately extend this class. You must implement outputPage().SkinTemplate
Extends
Skin. Adds QuickTemplate and portlet data assembly via prepareQuickTemplate(). Most legacy skins subclass this directly. Defines generateHTML() and outputPage().SkinMustache, which extends SkinTemplate and adds Mustache template rendering:
Implementing skin methods
initPage()
initPage( OutputPage $out ) is called before the HTML body is generated. Use it to set meta tags, add modules, or configure page-level output. The parent implementation handles responsive viewport tags and Open Graph meta tags.
includes/MySkin/SkinMyTheme.php
initPage() sets the viewport meta tag based on the responsive option:
includes/Skin/Skin.php
generateHTML()
SkinTemplate::generateHTML() executes the template and returns the HTML body. When using SkinMustache, this is overridden to call TemplateParser::processTemplate():
includes/Skin/SkinMustache.php
template option in skin.json specifies which Mustache file is used (defaults to skin). getTemplateData() assembles the full data array passed to the template.
getTemplateData()
OverridegetTemplateData() to add skin-specific variables to the template. Always call the parent and merge the results:
getDefaultModules()
OverridegetDefaultModules() to modify which ResourceLoader modules are loaded. The return value is an array grouped by type:
styles sub-key controls render-blocking CSS. Modules listed under skin are the skin’s own scripts.
ResourceLoader modules
ResourceLoader modules are declared inskin.json under ResourceModules. Skins typically use SkinModule for their main stylesheet, which provides opt-in feature styles from MediaWiki core.
SkinModule features
MediaWiki\ResourceLoader\SkinModule provides a set of reusable feature styles. Declare which features your skin uses:
SkinModule feature keys include:
| Feature | Description |
|---|---|
normalize | Cross-browser rendering normalisation |
elements | Base-level single-element styles |
content-media | Thumbnail and floated-element styles |
content-links | Red links, stub links, external link styles |
content-body | Styles for .mw-parser-output |
content-tables | .wikitable styles |
interface | Common interface styles (MonoBook/Vector level) |
interface-category | Category bar styles |
logo | CSS for .mw-wiki-logo using $wgLogos |
accessibility | Universal accessibility rules |
Script modules
Making skins responsive
To enable responsive behaviour, set"responsive": true in the skin’s constructor args inside skin.json:
responsive is true, the isResponsive() method checks both the skin option and the user’s skin-responsive preference:
includes/Skin/Skin.php
isResponsive() returns true, OutputPage adds the skin--responsive class to <body> and initPage() sets a full viewport meta tag instead of the fixed width=1120 desktop fallback.
In your CSS, use this class to apply responsive rules:
Skin options reference
The following options can be passed in the constructor args array inskin.json:
| Option | Default | Description |
|---|---|---|
name | required | Internal skin name (lowercase) |
styles | [] | ResourceLoader style modules to load on all pages |
scripts | [] | ResourceLoader script modules to load on all pages |
responsive | false | Enable responsive viewport meta tag |
toc | true | Whether ToC is in main content area |
bodyClasses | [] | Extra CSS classes on <body> |
clientPrefEnabled | false | Enable mw.user.clientPrefs support (since 1.41) |
wrapSiteNotice | false | Wrap banners in div#siteNotice (since 1.42) |
messages | [] | i18n messages to include in template data as msg-* |
menus | ['namespaces','views','actions','variants'] | Navigation menus the skin supports |
templateDirectory | — | Path to Mustache template files (required for SkinMustache) |
template | 'skin' | Name of the root Mustache template file |
Skin variants and color schemes
Skins can support user-selectable variants (e.g., light/dark themes) using theclientPrefEnabled option together with mw.user.clientPrefs. Enable it in skin.json:
<html> and persisted in localStorage for anonymous users (or user preferences for logged-in users). Your CSS uses these classes as hooks:
Enable clientPrefEnabled
Set
"clientPrefEnabled": true in your skin’s constructor args in skin.json.Define CSS classes
Write CSS rules scoped to
.skin-<name>-clientpref-<value> class names on the <html> element.