Motivation
Platform Evolution is one of the five pillars of the Wikimedia Foundation's Medium Term Plan. The need to evolve our platform is very evident when it comes to how we design, develop, and deliver experiences to users in the browser.
WMF projects still rely on the same approach to front-end development that they did a decade ago: most user interface elements are built in PHP (often without relying on templating languages), and enhanced in the browser using jQuery and our own in-house frameworks (OOJS and MobileFrontend) and UI component library (OOUI). There are many pain points associated with this way of working in 2019.
Thoughtfully adopting a modern JS framework will provide many immediate improvements to the front-end development process at the Foundation, and will help to pave the way for further architectural improvements in the future. Some advantages of using a modern JS framework include:
- The ability to build UIs in a declarative way (describing what to build), as opposed to the present imperative approach (describing how to build it), leading to more concise code that is easier to reason about
- Better support for breaking up UI code into small, manageable components with clear separation of concerns
- Components built with a modern framework would be reactive (automatically responding to user input) out of the box, with no need for manual DOM reconciliation. This can potentially eliminate an entire class of bugs
- State management systems (Redux/Vuex/etc) would be available to help make complex data flows consistent and predictable
- Unit-testing of UI elements would be greatly simplified, leading to better test coverage and fewer bugs in our UIs
- The ability to do server-side or isomorphic rendering of UI elements opens up many new architectural possibilities that could be explored in the future
- Aligning front-end development within the Foundation to current best-practices in the larger web will simplify onboarding of new developers (a process that is currently quite painful and time-consuming, since many things need to be re-learned here) and lower the barriers to contribution generally
- Relying on tools that have large, active communities outside the Foundation will let us benefit from the larger community’s work (fixing bugs, writing documentation, maintaining the framework); this will also make it easier for innovations developed within the Foundation to be adopted across the wider web.
Requirements
The FAWG has collectively gathered an extensive list of requirements for whatever new technology we end up adopting. These can be summarized as follows:
- The framework allows UI elements to be defined in a declarative way
- UI elements created within the framework are reactive (update automatically in response to changes in data or user input) by default
- The framework is open-source, widely used, and has a thriving community (and we anticipate this will continue to be the case for years to come)
- Flexibility: the framework supports the widest-possible range of use-cases (client-side as well as server-side rendering, progressive enhancement as well as full "SPA" usage, build step as well as no build-step etc.)
- The framework is heavily optimized for performance.
Proposal
As part of the Wikimedia Foundation’s platform evolution program, the Technology and Product departments have assembled a cross-departmental Frontend Architecture Working Group (FAWG). This group (which met extensively between September and December 2019) was tasked with carrying out the WMF’s platform evolution recommendations – in particular, with exploring how to modernize the tools used for front-end development at the Foundation.
As part of its work, the FAWG recommends that the Foundation should adopt a modern, widely-used JavaScript framework for the purpose of developing user interfaces within its projects. After much research and discussion, the working group believes that the open-source Vue.js framework is the best match for the Foundation’s requirements right now as well as for the foreseeable future.
The new framework would initially be introduced in one or two small features which would serve as case studies. Wider adoption could proceed if initial experiments succeed.
The working group anticipates that some deeper changes to architecture and infrastructure will be needed in order to take full advantage of what a modern JS framework like Vue.js can offer. In the longer term, adding support for a frontend build step in deployment and for server-side rendering (SSR) of UI components are two tasks that would be particularly useful here. In the short term, there may be a need for making small additive changes to tools like ResourceLoader to better support using Vue.
Until such features are in place, use of Vue.js would be limited to cases where server-rendered elements can be progressively enhanced within the user’s browser. Considerations of accessibility, internationalization, and performance will remain paramount. This RFC is about adopting a specific tool for use in building UI components within our present architecture. The FAWG has also produced a set of recommendations that touch on larger architectural changes in the Foundation’s projects, but they are beyond the scope of this RFC.
Even with these limitations, the FAWG believes that adopting a modern, widely-used library like Vue.js will provide many benefits by improving developer productivity, aligning our work with the best-practices for UI development used by the wider web, and lowering barriers to contribution.
Libraries Considered
The FAWG evaluated a number of different libraries in the front-end framework landscape. We believe that the only libraries which currently satisfy all of the requirements above are React and Vue.js.
Angular and Ember have active communities and powerful features, but lack the flexibility that will be required for our particular use-cases (especially early on in any "transitional" period of adoption when tools like jQuery, OOJS, and OOUI remain in use).
Svelte, Inferno, and Preact are aggressively optimized for performance but have much smaller communities of users (Preact suffers from this issue to a lesser extent, but only as long as it maintains a very high level of compatibility with mainstream React, which may not be the case forever). Stimulus.js embraces the philosophy of progressive enhancement but doesn't support other use-cases like server-side rendering.
React and Vue.js share many features and philosophies. Both enable developers to build UIs in a declarative, reactive, and component-based way; both core libraries are fairly light-weight and performant; both possess large and active communities. We believe that the Foundation would be well-served by adopting either tool. However, we believe that Vue.js has a few key advantages that are relevant for the Foundation's use-cases.
Why Vue.js
It is true that React has a larger community by at least an order of magnitude; if the requirement of widespread adoption outweighs the others listed above, then React is the clear winner.
However, we believe that Vue.js has sufficiently wide adoption in the form of a thriving and fast-growing community to be a safe bet. In addition, we feel that Vue.js has some advantages in terms of flexibility that distinguish it from React for our anticipated use-cases within WMF projects:
- Better support for usage without Webpack/Babel/front-end build tools: Both React and Vue.js rely on a build step for their ideal use cases. React uses JSX files, while Vue.js uses single-file components. But Vue.js can also use templates provided as HTML strings (which can be provided in a variety of ways). This allows us still define UI elements in a declarative way, one of our key requirements. React can also be used without a build tool, but it falls back on its imperative CreateElement API which is not ideal for general use. We should still explore introducing a full build step in the future (including full support for module bundling, ES6+ transpilation via Babel, etc), but this is a non-trivial change to the architecture of MediaWiki. In the meantime, Vue.js’s string templates could probably be handled by ResourceLoader with some small modifications. Finally, the ability to define components in a declarative way without requiring a build step may be especially useful in the development of gadgets and other user-generated scripts, one feature that makes Wikipedia and related projects very different from many other major websites
- Vue.js may enable us to rely on fewer libraries as dependencies. If we are only allowed to use a small number of whitelisted tools (due to security audits, for example), Vue.js allows us to do more with fewer dependencies in some cases. For example, the core Vue.js library includes powerful transition and animation tools; React has similar tools but they exist within community-maintained libraries separate from the main codebase. Similarly, both React and Vue.js can support scoping CSS styles to a single component, but React users must use a 3rd-party library like Styled Components, while Vue.js includes this feature in the core library. Finally, key add-ons in the Vue.js ecosystem (router, state management, testing tools, etc.) tend to be maintained as officially-supported products by the core development team, while the equivalent tools in the React ecosystem tend to be community-driven, and support levels will vary.
- The official Vue libraries are evolving in a stable and predictable fashion. In the last 4-5 years, Vue.js has moved from 0.x to 1.x to 2.x (the current version), and is about to enter version 3. There have been very few breaking changes that required rewrites of existing code; new versions tend to introduce new optional features while preserving the core workflows. In contrast, React and its related tools have gone through a large amount of change over the same period of time. The recommended best-practices have changed considerably over the years. Keeping up with these changes would be quite difficult given the pace that WMF projects move at.
- Vue.js development is not led by a single corporation whose goals may diverge from those of the WMF. React was originally licensed in a way that made many open-source projects hesitant to use it; fortunately those days are gone. However, React is still developed primarily by Facebook and will likely continue to change in ways that serve Facebook's needs first and foremost. The WMF had to spend time and energy migrating away from another open-source FB project (HHVM) when Facebook decided that new versions would no longer remain fully compatible with PHP. Sudden changes in direction may be less likely in a project like Vue.js which does not rely on a single dominant corporate backer.
It should be noted that these points are not “reasons why Vue.js is better than React” – they are arguments that Vue.js is the best choice for the WMF, where “best” must balance between current realities, migration paths, and ideal future outcomes.
Next Steps
Fully adopting a tool like Vue.js would represent a significant change in the way the Foundation approaches front-end development. This is a decision that has many implications and potential pitfalls.
To minimize the risks inherent in such a change, the FAWG recommends that the initial adoption of Vue.js be limited to one or two case-study projects that fall within the upcoming Desktop Improvements project. These should be small-scale, discrete features which would rely on client-side interactivity regardless of how they were implemented. Core reading and editing functionality should be left alone for now. A good test-case feature would be one that provides an enhancement to functionality that has a more basic, no-JS fallback.
Developing a new component library in any framework will need to be done in a way that aligns with Wikimedia’s existing design system. Integrating any new tools we adopt into this system is a precondition to production usage and should commence as soon as possible.
Teams working on such projects should carefully evaluate the impacts of the new tools on performance, accessibility, developer productivity, etc., and this data should inform the wider framework adoption process.
Additionally, Vue.js has been used successfully in production by Wikidata for several years; WMDE is currently experimenting with the use of server-side rendering for a new feature. As part of our evaluation process, WMF should consult with WMDE to learn from these experiences.
Conclusion
The Frontend Architecture Working Group was tasked with providing recommendations to the wider Foundation to guide future work; this RFC is one of those recommendations.
Adopting a framework is not the same thing as designing a new architecture; there will be follow-up RFCs to address other questions that came up in the FAWG’s work. We believe that gradually adopting a modern JS framework in a thoughtful way will allow us to improve the experience for both developers and users within our projects now, while some bigger architectural questions continue to be evaluated.