Graceful Degradation in Web Libraries

Web UI libraries should do everything in their power to render something relevant given absolutely any input. This, even if the consumer fails to include the necessary input for the component in question to function correctly.

When graceful degradation is discussed in programming it is generally in regard to what a web app should do when various web features are not supported: if JS is disabled, do X. If the api fails, do Y.

What I don’t see enough of is discussion of graceful degradation at the library level. I believe that libraries should match the level of graceful degradation that the core environment provides. For an environment like Java this is fairly obvious, provide meaningful error messages and stack traces. Allow the strongly typed nature of the language to intercept errors during compilation whenever possible. For web development this is not so simple.

In modern web browsers, the levels of supported bad input are, quite frankly, nuts. For instance this invalid html still prints the word “test” without incident:


There are many more core failure states and fallbacks built into browsers and their underlying technologies.

Historically there is a very good reason for this: Microsoft won the browser war with Internet Explorer 6 by supporting all of the most broken sites available. At the time, being able to access as many sites as possible was value. Users didn’t care if the sites were programmed properly, they cared if the sites worked, and the browser was blamed if the sites didn’t. In the end any competitor had to follow suit or die.

One of the side effects of this is that web development became one of the most developer friendly environments ever! You barely need to know how to code to make an early 2000’s site, and you certaily don’t need to follow the rules.

This is, for better or worse, the environment web developers expect to operate in. So when I add a web component to my page and get nothing because I left off a required property, my first assumption is that the component is broken. I either abandon the library completely, or, if I’m required to use it, I read the documentation, fix the issue, and write an angry blog post.

For public facing libraries the importance of meeting the expectations of consumers is obvious. The library is competing with other libraries for market share and support. For private, company owned, libraries the importance is still there but less obvious. The company is competing to hire and retain the best developers. Keeping those developers requires a good development environment. Good developers will also move faster and build better code in an environment that is intuitive to use and matches their expectation.

Call to action:

First, test for common partial input scenarios and allow for partial behavior as much as possible. Second, when a consumer raises a concern about a component not working, and it is traced to bad input, treat the developer with care. Do not be dismissive. Handle the issue as a usability problem. Correct documentation in response, but also consider opening a story to make this failure case more intuitive.

A quick note:

Some time ago I had a discussion about this with a colleague who supports a component library I work with. This is not intended to be a subtweet for that colleague. If you come across this you know who you are. I appreciate everything you have built for our organization and the support you provide. I have actually encountered this issue many times in my career. After that discussion I decided to get my ideas down in writing for reference the next time this comes up. As it surely will.