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 browser-based code from other components.

For guidelines on PHP, see stable interface policy. The frontend stable interface policy is maintained separately from the PHP stable interface policy due to the difference in audience and scope (e.g. this policy includes gadget developers). The eventual goal is to move this to Stable interface policy/Frontend.

This document applies to all developers of browser-based code that relies on MediaWiki. This document 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.

The scope of this policy regards wiki-hosted code that runs on one of the Wikimedia projects. The policy does not apply to gadgets running on third party instances.

Using code

 * The mw object is the primary stable API for interacting with MediaWiki in the browser.
 * HTML should not be considered stable. Direct access and manipulation of the DOM is not safe. The only safe way to access parts of the DOM is through utilities provided through the object to obtain of modify existing elements on the page rather than DOM queries. If there is no utility function that satisfies your use case, please let us know.

Communication

 * Review https://doc.wikimedia.org/ (particularly the core documentation) for documentation of the available stable interfaces.
 * Request APIs via Phabricator where APIs are missing, rather than relying on unstable functions, structures or identifiers.
 * Read and respond to deprecation warnings in the JavaScript developer console within the current release.
 * Subscribe to m:Tech/News to learn about deprecations.
 * If you are writing "Wiki-hosted code" (see terminology section below) please review recommendations for developers of on-wiki code.

Writing code

 * HTML is not a stable interface, but providers must consider communicating changes that touch HTML markup with IDs or HTML class attributes containing  given they may historically have been used by wiki-based code developers.
 * When renaming or removing ResourceLoader modules, follow the deprecation process
 * Limit code exposed on the  object, since it must be maintained as @stable API unless it has been marked as @private.
 * Keep public methods exposed on the  object and    signatures compatible for callers. Follow the deprecation process for breaking changes.

Communication

 * Work with gadget developers to disable or patch unmaintained gadgets which interfere with our ability to track JavaScript errors
 * Work with gadget developers and other extension developers to identify and add missing stable APIs.

Terminology

 * See RFC 2119 to understand the language used in this policy to indicate requirement levels ("MAY", "MUST", "SHOULD").
 * "Wikimedia wikis" refers to all deployed Wikimedia's projects.
 * "Wiki-hosted code" is defined as code that executes on Wikimedia projects, whose source code lives inside a page that is editable on wiki.
 * A "MediaWiki developer" is defined as someone who contributes code to the MediaWiki core code repository or one of its extensions or skins that is deployed in any Wikimedia wikis.
 * "Frontend code" is defined as any code that is executed by the browser such as client-side JavaScript, CSS and HTML. This includes wiki-hosted code as well as some code deployed on Wikimedia servers (extensions, skins and MediaWiki core).
 * The "codesearch tool" refers to codesearch.wmcloud.org.
 * The "global search tool" refers to global-search.toolforge.org.
 * "Providers" refer to MediaWiki developers who are defining stable interfaces.
 * "Consumers" refers to code that makes use of stable interfaces, and the maintainers of such code. This includes "MediaWiki developers" as well as developers of "wiki-hosted code".
 * "Caching implications" is used to describe the situation on Wikimedia production sites where old HTML markup is served to users alongside new styles. We cache HTML for a longer period than JavaScript and CSS assets. Caching implications apply to any page that is cached on the edge layer (typically any page that can be rendered by anonymous users excluding the special namespace). Explaining caching in detail is out of scope for the document; for more information, see Readers/Web/Building features with cached HTML in mind.
 * "Popularity of a gadget" is used to describe how widely used or important a gadget is in the Wikimedia ecosystem. Popularity can be evaluated using Special:GadgetUsage and en:User scripts/Most imported scripts) using the global search tool . As a general rule, popularity can be judged by 50+ scripts in MediaWiki namespace or more than 1000 scripts across the user and MediaWiki namespace impacted by any given change.
 * Use your best judgement on determining usage and popularity. For example, the Twinkle gadget is widely used, so an issue that impacts the Twinkle gadget may be more significant than a change that impacts 100 user scripts.
 * Participants in Wikimedia development should be forgiving when mistakes occur and propose revisions to our definition of gadget popularity based on real world experience via discussion on the talk page.

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

The motivation for the frontend stable interface policy is twofold:

Gadgets and user scripts (which will be referred to as wiki-hosted code) are key components of MediaWiki projects. Before the introduction of this policy, there was no clearly defined API that such code could rely upon. This has caused misunderstandings and unexpected problems particularly for wiki-hosted code.
 * Offer guarantees to the maintainers of frontend code, providing guidance on what interfaces that 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 or wiki-hosted code.

This situation has also made it difficult to improve MediaWiki code, since it was unclear how changes would impact wiki-hosted code and developers often did not feel empowered to make changes in an acceptable fashion.

In addition, it has not been clear who is responsible for fixing issues in wiki-hosted code.

This document aims to build agreements between Wikimedia staff, third party extension developers, and developers of wiki-hosted code developers to create a better experience for all groups and to build trust between them.

History

 * [July-August 2023] Incorporated changes based on talk page feedback
 * [June 2023] Folding feedback from outside wiki into document
 * [May 2023] Targeted MediaWiki.org developers https://www.mediawiki.org/w/index.php?title=MediaWiki:Editpage-code-message
 * [March 2023] Revised format of document
 * [January 2023] Document was separated into User:Jdlrobson/Stable_interface_policy/frontend and Recommendations for gadget developers
 * [May 2022] Emailed engineering-all@wikimedia.org to request feedback
 * [Feb 2022] Emailed wikitech-l@lists.wikimedia.org https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/message/HLQSR7NCYJFKDBITBYSF2RRQJUEOP6PC/
 * [August 2021] This document began life in User:Jdlrobson/Extension:Gadget/Policy.

ResourceLoader modules
All ResourceLoader modules inside MediaWiki core MUST be considered stable to load, unless marked as deprecated and must follow the deprecation process. For modules outside MediaWiki core, there is no need to follow the deprecation policy, unless you have explicitly designed the module for consumption by other extensions/skins.

JavaScript code
JavaScript code that is considered stable MUST follow the related deprecation process. This includes:
 * Code that declares itself as stable in its JavaScript documentation either on docs.wikimedia.org OR ResourceLoader/Core_modules, preferably by using the  tag. If a property or module is marked as stable that indicates all of its public methods are also stable.
 * Code that is defined on the public  object, that has not been documented as , regardless of how the code is added (extension, skin or wiki-based code), even if the code has not been marked as
 * The function signature of the callback function for hooks fired using the  object in MediaWiki core code should be considered stable. Consumers can expect that the hook will be fired in the circumstances as described in its documentation. See example 3.

See these examples:

Additional information for providers

 * Providers SHOULD document all stable methods on https://doc.wikimedia.org using current coding conventions.
 * Providers looking to avoid adding code on the public  object SHOULD instead share code between modules using ResourceLoader/Package files (using   and  ). See OptionalParamWidget.js as an example of a class that is not defined on the mw object and can only be used by mediawiki.special.apisandbox.
 * Providers using ResourceLoader/Package files should limit what functions are exported in the main module file to those that need to be shared between multiple ResourceLoader modules.

Additional information for consumers

 * Consumers should note that the require method is only accessible to ResourceLoader modules and currently should not be considered a stable interface outside ResourceLoader modules where it is undefined.

What is not stable?
HTML markup and CSS cannot be considered stable. All frontend code (including wiki-hosted code, extensions and skins) relying on HTML structure does so at its own risk.However, consumers often do rely on the DOM structure and unstable identifiers for historic reasons.

To avoid unnecessary breakage, providers should bear the following in mind:.

HTML markup and CSS
HTML markup is NOT a stable interface (unless explicitly stated). However, due to missing frontend APIs, historically, gadget developers had no other choice than to rely on HTML markup.

Advice for providers
MediaWiki developers are not required, but have a responsibility to respect gadget developers' existing work by proactively communicating any changes to HTML markup where alternative APIs are not currently available, particularly in projects which have high visibility or operate in the article namespace. This requirement will be dropped 2 years after the roll out of the frontend stable policy (September 2025).

In cases where there might be mutually beneficial for wiki-hosted code developers and MediaWiki developers to share stylesheets, for example for performance reasons, while not advised, the relationship MUST be documented in the source-controlled code using the  and   tags and linking to the on-wiki discussion. Classes defined in HTML class attributes that do wish to be considered stable MUST add an inline comment indicating in which MediaWiki version they were introduced using the  annotation and must follow the deprecation process in the relevant section below. For example:

Advice for consumers
Wiki-hosted code SHOULD NOT make use of stylesheets defined by MediaWiki core for styling custom HTML markup, as doing so can lead to misuse, misunderstandings and breakage (T213239, T287997) unless the consuming code makes this relationship clear via @public and @since tags (please refer to advice for providers section). Instead it should define its own class and styling rules.

For example: Gadgets SHOULD NOT replicate the HTML markup of a dropdown and a menu in Vector, using Vector's stylesheets. The stylesheet is not stable and may change without notice. Instead wiki-hosted code should use the mw.util.addPortletLink function to add additional menu items, because as part of the mw object it would be considered stable, and if imitating the HTML markup they should also imitate the CSS that goes with it, so it can rely on the styles not changing.

Advice for consumers needing to change HTML markup and CSS classes safely

 * MediaWiki developers MUST understand and consider caching implications, namely that HTML from a previous deploy may be served to users alongside newer CSS. For pages subject to cache, MediaWiki developers MUST consider how HTML that is greater than a week old (such as HTML generated during the last train cycle) will be styled.
 * MediaWiki developers SHOULD first assess the impact of their change to HTML markup on wiki-hosted code, based on the communication guidelines and whether communication is advised.
 * Particular care MUST be taken when
 * changing any element using a class or ID prefixed with  as traditionally the prefix has been associated by some as a stable interface.
 * Removing an HTML element class attribute from output HTML that is provided by the MediaWiki wikitext parser (for example,  and  ).
 * In the case of renaming IDs which might be mistakenly considered stable (such as due to historic association with the  prefix, or an ID that hasn't changed in over 5 years), developers SHOULD consider a longer grace period since there is no way to do backwards compatibility.
 * In the case of renaming classes, it is recommended that the new class SHOULD be added along with the removed class for at least one MediaWiki release cycle in case 3rd parties may be relying on them e.g. for HTML processing. An inline comment should indicate in which release the old class was deprecated.
 * Where APIs do not exist, providers SHOULD document missing APIs on Phabricator.


 * MediaWiki developers MUST follow the conventions in Manual:Coding_conventions/CSS. The benefits of using naming conventions are twofold:
 * 1) Developers can use the codesearch tool to easily locate locate where HTML is generated.
 * 2) Gadget developers due to historic usage will often rely on the   prefixed selectors, and assume they are stable and not prone to change.

Guidelines for consumers to avoid reliance on HTML structure

 * For adding items to menus, the  method is encouraged rather than relying on jQuery.
 * For adding subtitles, use  rather than appending to   or   elements.
 * If you find yourself relying on CSS in core you should request a function for generating markup that is compatible for that CSS.
 * Where APIs do not exist, consumers SHOULD request APIs to access elements or extend existing elements via Phabricator.

Guidelines for providers around modifying default styles
MediaWiki developers MAY change default CSS for content generated by wikitext (such as changing the default link colors or changing typography). While rare, developers SHOULD consult the global search tool to inform themselves about potential local overrides made by editors in MediaWiki:Common.css and should follow the communication guidelines in communicating changes to gadget developers when the change may be controversial or potentially cause visual changes.

Deprecation process
For frontend code we do not make a distinction between soft and hard deprecation since we do not log deprecation warnings and their primary purpose is for communicating to developers.

What providers should do when making breaking changes to stable JavaScript interfaces

 * When deprecating JavaScript code,  MUST be added to the JavaScript documentation and should note the MediaWiki release number.
 * When deprecating code, the method  MUST be used to signal the deprecation of the API. The deprecation message should state the release in which the deprecation happened.
 * Deprecated methods MUST NOT be removed until they have been logging deprecation warnings in at least one stable release and at least one month in Wikimedia production environment.
 * MediaWiki developers MUST follow guidelines around communicating changes to gadget developers.


 * When changing the function signature or removing a hook consumers MUST call the  function in a callback defined by itself.

What providers should do when removing ResourceLoader modules

 * Code that was never part of a public MediaWiki release, and never consumed according to codesearch and global search MAY be changed or removed without deprecation, since the code has never become part of the stable interface or used.
 * Before removing a module, the module MUST be deprecated so that using the module logs hard-deprecation warnings for at least one MediaWiki release prior to removal using the deprecated key in its ResourceLoader definition. This is to support third party developers who need to be notified and respond to any upstream changes.
 * When deprecating a ResourceLoader module, set the deprecated key on the associated ResourceLoader. The developer MUST document the deprecation in RELEASE_NOTES and mention the release number in which the deprecation occurred.
 * Developers MAY fix consumers of a module prior to deprecation, but doing so is not required as a precursor to deprecation.
 * When completing a deprecation, the removal MUST be documented in RELEASE_NOTES.
 * Communicate the change to gadget developers per communication guidelines.

Providers

 * MediaWiki developers MUST pay attention to Phabricator tickets with requests for code maintenance and communicate any challenges they see with resolving them.
 * All new MediaWiki code deployed to Wikimedia wikis SHOULD consider providing a stable way for on-wiki code to support extensibility if this property is desired.
 * MediaWiki developers MUST review popular gadgets, using the global-search tool, annually to evaluate code that makes assumptions about the HTML structure and to flag opportunities and plan construction of new APIs. MediaWiki developers MAY evaluate 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 developers MAY use feature flagging (such as Extension:BetaFeatures or user preferences) in deployments to allow editors to test interfaces prior to development and SHOULD advertise their availability via m:Tech/News.

Consumers

 * MediaWiki developers SHOULD regularly check the JavaScript console for deprecation notices and warnings and engage with them within one release cycle, by either fixing the issue or making clear why that is not possible.
 * Newly written code SHOULD NOT use deprecated ResourceLoader modules (such as jQuery.UI).

How providers can make breaking changes that impact widely used but non-maintained gadgets
When making breaking changes, despite good intentions it is inevitable even with good communication that some on-wiki scripts will not be updated by their maintainers and the change will lead to production errors and/or disruption to editor workflows.

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

When making breaking changes, 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-hosted 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-hosted 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 the error is encouraged.
 * MediaWiki developers MAY fix or disable wiki-hosted code that is broken, provided the edit summary or the talk page documents how the issue can be fixed.
 * MediaWiki developers MAY run bots to automate fixing wiki-hosted code where resolution is straightforward. Example: a method is renamed.

Communication of changes to developers of wiki-hosted code

 * If any gadgets/scripts are impacted, then MediaWiki developers SHOULD notify m:Tech/News. For changes that impact popular gadgets in such a way that they break functionality or where stable interfaces have changed (regardless of whether they are used), MediaWiki developers MUST do so.
 * If MediaWiki developers are confident that gadgets will not be severely impacted (for example if the gadget is still functional after the change but stylistically different) communication can be skipped.
 * When communication is required (MUST):
 * A period of at least one month MUST be given for wiki-hosted code developers to respond and raise any concerns relating to the change regardless of MediaWiki release.
 * MediaWiki developers MUST consider any feedback from gadget developers to minimize disruption (for example create tickets around introducing APIs where missing).
 * For all communications (MUST and SHOULD):
 * The Tech News entry MUST mention "BREAKING CHANGE" in the title and provide steps to resolve the problem inside the description.
 * Timeline is left to the providers best judgement for changes that impact non-stable interfaces.
 * When learning about the breakage of gadgets on Wikimedia wikis that are not covered by the wiki-hosted code policy, e.g. using unstable interfaces due to unavailability, MediaWiki developers MUST assess the inclusion of a new stable interface to reduce future breakage.

Communication of changes to other MediaWiki developers

 * If code running on Wikimedia sites is impacted by breaking changes, developers MUST open Phabricator ticket(s) tracking the issue for impacted skins and/or extensions. The Phabricator ticket(s) should tag the impacted project and detail the timeline for the removal and provide details on the required change.
 * Developers MAY provide patches, and are encouraged to do so especially in the case where the fix is simple.