Awhile back I was given the challenge of architecting a UI pattern for distributing widgets across a variety of application platforms within our company’s ecosystem. The widgets I was solving for needed to be self contained and render-able anywhere.

Prior to this project, I had been researching React and some of the supporting technologies around it but hadn’t yet had a chance to use it in production. React turned out to be an excellent fit for this type of project, along with some supporting patterns I’ll be describing here.

My goal here is to describe the patterns I ultimately landed on in collaboration with both my team and the client teams I worked with.

The content here is targeted for developers already at least somewhat familiar with React and its de facto tool chain (Webpack/Babel/Flux), and, especially for those interested in using React to build widgets or any type of front end content shared across application platforms or product ecosystems.

Library as a service

Following popular widget patterns, the first principle we established was the decision to distribute the widget library as a service rather than as a traditional library.

Typically libraries are consumed in the application tier and downloaded from an external source, such as npm, and hosted by the application itself . This pattern is useful for traditional libraries like jQuery or React as it gives the ability to define a fixed version which ensures stability for the consumer. The problem with this pattern is the author has no ability to “push” updates to the library, save for the brave souls that `npm install` with latest.

On the other hand, distributing the library as a service meant hosting the library with high availability from some flavor of CDN, and using a fixed URL, so that as needed we can push updates, bug fixes, features, etc. This is the preferred pattern for our use case. This pattern ultimately takes burden off of the client — and is a similar pattern you’ll see with facebook/twitter widgets as well. The client only has to include a script from a url i.e. “https://widget/v1/widget.js” and initialize it with a config object.

The script returned from the CDN would always be the latest of a given major version. For flexibility, individual versions are made public only for debugging purposes “https://widget/1.0.1/widget.js”.

Public interface

Moving forward from the “library as a service” pattern, the provided library should also provide an interface allowing the client to configure and understand the state of the library and, in this case, render widgets into their document. When distributing a library, we don’t want to bother our consumers with implementation details — this pattern allows for those to be abstracted away.

An important principle of widget delivery is to be a good citizen in the enclosing app, which means we don’t play outside of our sandbox or let our dependencies leak through to the window object. There are many ways to accomplish this, but the de facto standard for bundling dependencies for the front end currently is Webpack (or browserify, if you like).

Webpack config

Starting from a boilerplate webpack.config.js, assuming you have your entry points and loaders defined, lets take a look at the output block. Here you’ll define your output target as well as some other options:

module.exports = {

output: {

path: path.join(__dirname, ‘./dist/’),

filename: ‘widget.js’,

library: [“MyLib”],

libraryTarget: ‘umd’,

publicPath: ‘/dist/’,

},

Notice the use of “library : “MyLib”. This will take the exported widget.js module and package it as a library under the MyLib namespace using the UMD module format. We’ll refer to this object as the facade. Now we can start populating the facade with methods that will make up our interface.