Stable interface policy/Frontend

The stable interface policy for MediaWiki frontend code (CSS, JavaScript and HTML) defines what parts of the software are considered stable and safe for use by other components. Code that is considered part of this "stable interface" is subject to the deprecation process. For guidelines on PHP please see Stable interface policy. It is currently kept as a separate document given the audience is different, particularly given its unique requirement to gadget developers. The eventual goal is to move this to Stable interface policy/frontend.

While this documentation is in draft please feel free to dive into the talk page to debate any aspect of this code.

This document applied to MediaWiki developers. It is complemented and supported by a set of recommendations for developers of on-wiki code. Any changes here must be made with consideration to that document.

Terminology

 * See https://datatracker.ietf.org/doc/html/rfc2119 to understand the language used in this policy to Indicate Requirement Levels.
 * "Wiki-based code" is defined as code that executes on Wikimedia projects, who's source code lives inside a page that is editable on wiki.
 * A "MediaWiki developer" is defined as someone who contributes code to the MediaWiki code repository or one of its extensions or skins.

Guidelines around HTML markup
HTML is not a stable interface. Making changes to HTML structure, or renaming classes and IDs as part of active development is to be expected, however it is important that in some cases MediaWiki developers MUST communicate any changes to gadget developers and peers.

MediaWiki developers and wiki-based code MUST NOT share CSS classes. In cases where it might make sense for wiki-based code and MediaWiki developers to share code, this MUST be documented in the source-controlled code using a @public and@since keyword. HTML classes that do wish to be considered stable MUST add an inline comment indicating for what MediaWiki versions they were introduced using a @since annotation and must follow the deprecation policy.

Guidelines for changing HTML markup.

 * All Wikimedia deployed code that is subject to Varnish caching MUST be updated to cater for the old and new IDs/classes prior to the removal of the old ID given cached HTML may be served alongside new CSS.
 * MediaWiki engineers SHOULD assess impact of their change to HTML markup based on the popularity of the gadget e.g. Special:GadgetUsage and en:User scripts/Most imported scripts using the global search tool to decide whether communication is advisable and what a suitable timeframe for the change might be. The timeframe should be at least 1 month, but may warrant longer in some cases. This can be skipped if engineers are confident that gadgets will not be impacted.
 * Particular care MUST be taken when changing any element using a class or ID prefixed with "mw-" as traditionally this has been viewed as a stable interface or any class that is provided by the MediaWiki wikitext parser e.g. .wikitable, .external
 * In the case of renaming IDs where the class might be mistakenly considered stable per Definition of the stable interface, developers SHOULD consider a longer grace period.
 * In the case of renaming classes, it is recommended that the new class SHOULD be added along with the removed class for at least 1 MediaWiki release. An inline comment should indicate which release the old class was deprecated.

Guidelines for naming

 * All HTML classes prefixed with .mw-generated by MediaWiki core. Note, Code outside MediaWiki core, SHOULD NOT use the mw- prefix as it can confuse gadget developers by suggesting a stable API.
 * Extension/skin developers MUST prefix their CSS classes to avoid namespace clashes with wiki-based code developers. Extension/skin developers MUST use a unique prefix e.g. for Skin:Vector use vector-, for Extension:AbuseFilter use mw-abusefilter-

Guidelines for changes to HTML structure.
Frontend code relying on HTML structure, does so at its own risk. MediaWiki developers SHOULD provide and request APIs to access elements or extend existing elements (e.g. for adding items to menus the mw.util.addPortletLink method is encouraged rather than relying on jQuery)

Guidelines around modifying default styles
MediaWiki developers MAY change default CSS for content generated by wikitext provided they consider impact and where necessary follow the communication guidelines in communication / deprecation policy section.

It is generally recommended when doing re-designs, where possible that MediaWiki developers SHOULD use different classes/IDs, to avoid the situation where old HTML markup and styles can be mixed with new HTML markup and styles.

What to do when breaking changes to JavaScript interfaces

 * Code that MUST be protected by the wiki-based code stable policy and follow the deprecation policy:
 * Code inside the public mw object
 * Hooks fired using the mw.hook object
 * Code that:
 * is added to the mw object OR exported as part of the module definition in such a way that it can be accessed via require
 * that has indicated it is stable in its JavaScript documentation, preferably using the @stable tag
 * See these 2 examples:


 * When deprecating code in this form, method mw.log.deprecate MUST be used to signal the deprecation of the API. The deprecation message should state the release in which the deprecation happened.
 * When deprecating in this manner, the software MUST log hard deprecation warnings for at least one MediaWiki release. See example below.
 * MediaWiki developers MUST follow guidelines around Communicating changes to gadget developers.

What to do when removing ResourceLoader modules

 * All ResourceLoader modules inside MediaWiki core MUST be considered stable unless marked as deprecated.
 * Before removing a module, the module MUST be deprecated so that usage of them logs warnings for at least 1 MediaWiki release prior to removal.
 * When deprecating a ResourceLoader module, set the deprecated key on the associated ResourceLoader. When deprecating in this manner, the developer MUST document the deprecation in RELEASE_NOTES and mention the release number in which it was deprecated.
 * Developers MAY fix consumers of a module prior to deprecation, but it is not required as a precursor to deprecation.
 * The software MUST log hard deprecation warnings in this manner for at least one MediaWiki release. When removed, this should also be documented in RELEASE_NOTES.
 * Communicate the change to gadget developers (see Communicating changes to gadget developers)

Maintaining existing features

 * MediaWiki developers SHOULD regularly check the JavaScript console for deprecation notices and warnings and engage with them within 1 release cycle, by either fixing the issue or making clear why that is not possible.
 * MediaWiki developers MUST pay attention to Phabricator tickets with requests for code maintenance and communicate any challenges they see with resolving them.
 * Code creating complex UIs SHOULD use Vue.js and MUST follow any guidance that appear in the JavaScript console to maintain compatibility.
 * Code written in OOUI MUST follow any guidelines in the JavaScript console

When developing new features

 * All new MediaWiki code deployed to Wikimedia wikis SHOULD consider support providing on-wiki code a stable way to access its most important elements.
 * Newly written code SHOULD NOT use deprecated ResourceLoader modules e.g. jQuery.UI.
 * MediaWiki developers MUST regularly review popular gadgets to evaluate missing APIs using the global-search tool. MediaWiki developers MAY do this as part of their planning process, and MUST evaluate the use case in situations where a gadget developer raises a Phabricator ticket after an incident has occurred (for example: in a situation where a popular gadget breaks)
 * MediaWiki engineers SHOULD use feature flagging (e.g. Extension:BetaFeatures or user preferences) in roll outs where possible to allow editors to test interfaces prior to development and SHOULD advertise their availability via m:Tech/News.

Handling breaking changes in widely used but non-maintained gadgets
When making breaking changes, despite good intentions it is inevitable even with good communication that some scripts will not be updated and the change will lead to production errors and/or disruption to editor workflows.

Client side errors occurring in wiki-based code are tracked alongside errors in Wikimedia code on Grafana and can be explored further inside our logstash instance.

When making breaking changes, at times MediaWiki developers have a responsibility to fix or disable certain gadgets in the following scenarios:


 * MediaWiki developers MUST fix or disable error logging for any wiki-based code and/or user script errors with error volumes that trigger alerts via Wikimedia alerting systems. Having healthy metrics helps us have more confidence when we deploy code. Ideally the fix SHOULD be made by the maintainer of the code after discussion on the script's talk page, however in time sensitive situations MediaWiki developers MAY take action themselves if they feel comfortable doing so.
 * MediaWiki developers MAY fix or disable wiki-based code and/or user script errors that undermine user privacy. For example, if an active user is triggering an error on every page load, which reveals their page history, fixing it is encouraged.
 * MediaWiki developers MAY fix or disable wiki-based code that are broken provided the edit summary or the talk page documents how the issue can be fixed.
 * MediaWiki developers MAY run bots to fix multiple wiki-based code where resolution is straightforward. Example: A method is renamed.

Communicating changes to gadget developers

 * The scope of this policy regarding gadget code that runs on one of the Wikimedia projects. It does not apply to gadgets running on third party instances
 * For changes that impact more than 10 gadgets (MediaWiki namespace) and/or 1000+ user scripts (user namespace), MediaWiki engineers MUST notify m:Tech/News.
 * If less gadgets/scripts are impacted, then MediaWiki engineers SHOULD notify m:Tech/News
 * A period of at least one month MUST be given for wiki-based code developers to respond and raise any concerns relating to the change regardless of MediaWiki release.
 * Wikimedia engineers MUST consider any feedback from gadget developers to minimize disruption (for example create tickets around introducing APIs where missing)
 * The Tech news entry MUST mention "BREAKING CHANGE" in the title and provide steps to resolve the problem inside the description
 * MediaWiki engineers when learning about the breakage of gadgets on-wiki that is not covered by the wiki-based code policy MUST assess the inclusion of a new API to reduce future breakage.

Motivation
This policy is designed to make extensions more robust against changes in MediaWiki core, and provide more freedom for MediaWiki core code to evolve.

The motivation for this policy is two-fold:


 * Offer guarantees to gadget developers and extension developers, providing guidance on what aspects of MediaWiki core they can safely rely upon.
 * Provide guarantees to developers working on MediaWiki core, telling them what aspects of the code they can safely change without having to worry about breaking extensions.

Ecosystem
Despite gadgets and user scripts (which will be referred from now on as wiki-based code) being a key component of MediaWiki projects, up until now frontend APIs (e.g. how wiki-based code should interact with source control provided code) have been ill-defined leading to misunderstandings between engineers and wiki-based code developers when wiki-based code breaks. This also leads to code rot, where developers do not feel empowered to make changes as it's unclear how their changes will impact wiki-based code developers.

On top of this, when wiki-based code breaks it's not clear who can and will fix them.

This document aims to build agreements between Wikimedia staff, volunteer contributors (on Gerrit and Github) and wiki-based code developers to lead to a better experience for both parties and build trust and good faith between the two parties.

History

 * [August 2021] This document began life in User:Jdlrobson/Extension:Gadget/Policy. It was advertised on wikitech-l and received input from gadget developers as well as MediaWiki developers.
 * [January 2023] Document was separated into User:Jdlrobson/Stable_interface_policy/frontend and Recommendations for gadget developers
 * [March 2023] Revised format of document