When to Reach for a Framework (and When Not To)

First off, when I say “framework” in this post’s title I just mean any big chunk of stuff that you load up and it does stuff for you. So, could be React, jQuery, Bootstrap, etc.

Let’s say that a “framework” is made up of 10 bits of functionality. If we use all 10 of them then we’re getting great value from it. Conversely, if we’re only using one or two we’re probably loading up a lot of stuff that is never used – bloat.


If you’re only using one or two bits then you’d probably be better off writing these parts yourself, if you can, or finding smaller libraries which do just the parts you need.

If you go too far with trying to roll your own system you end up with a kind of framework but one that’s made up of lots of disparate parts which may have other dependencies. It’s a Frankenstein’s Monster of a framework. Hard to maintain and extend.

Tipping Point?

So, the real question is at what point do you move from assembling your own parts to adopting a full framework which organises these parts in a coherent and systemic way? Where’s the tipping point?

Going back to our example of a framework that offers 10 bits of functionality, how many would you want to be using to make adopting the framework worthwhile? I think it’s important not to look at the now but at the future. Where is your project headed? Will it keep growing? What other functionality might you use further down the line? Does the framework given you other things for free that you can do now?

Framework Benefits

The other major benefit that a framework brings is the knowledge and familiarity. You can recruit someone who has worked with a framework before and they will be up to speed quite quickly compared with someone coming in and having to pick their way through a large custom system.

If a framework offers 10 bits of functionality I’d be inclined to adopt it as soon as you’re using 3 of them. I feel the benefits of a framework outweigh the saving.

You also have to consider the quality. Is a framework that has been worked on by top engineers and tested by thousands of developers going to be better than something you roll yourself? And will it integrate better with other third party tools?

Modules FTW

The real answer is for frameworks to become modular with a very small core and lots of optional modules. Not NPM which is going back to the “Franken-framework” but a properly connected set of features which can be included or dropped as needed. A bit of an old-school example now but jQuery UI does this very well – you can build a custom version of the library to suit your needs.

Hiding UI Elements

At the start of March 2019 I ran a poll on Twitter to see how devs hide UI elements. Here’s the tweet and results.

50% CSS "display:none",
5% HTML "hidden" attribute,
27% JS framework state,
18% Something else

Admittedly, not a very scientific sample size but it was enough to confirm my suspicion that very few people use the “hidden” attribute. I should probably call it a property rather than an attribute as it’s a Boolean and acts in a similar way to “disabled” or “required” which we often use on form elements. And, by contrast, the most common method seems to be to use the CSS “display:none”. Probably no great surprise to anyone.

I think it’s interesting to think about what we’re really doing when we hide an element. Is the visibility of the element just for screen users or for all users? Do we still want the element available for non visual media? Or is the content going to be used by another part of the page in some way? Does it need to be in the DOM at all or are we just keeping it there because it’s easier?

If we use JavaScript, either native or a framework, we can insert and remove elements as needed based on logic. If it’s playing no part in our document why not just leave it out altogether? This keeps the DOM light and performant and easier to work with. If you’re working with something like automated testing you can check for an element’s existence rather than trying to figure out if it’s visible or not.

If we use CSS to hide an element and respect the separation of concerns principle then are we saying that hiding this element is a presentational choice rather than a semantic one? Maybe we are hiding it, maybe temporarily, rather than denying its existence?

In the case where we want an element to be hidden in one medium and shown in another, CSS feels like the right choice. Whilst “display:none” and “visibility:hidden” are valid, other techniques like “height:0”, “opacity:0” or “left:9999px” feel very unclear in their intentions and too focused on the visual user.

The HTML “hidden” property is a more semantic choice. It is stating that this element is not to be considered when reading the document, whether that be on screen or via assistive technologies. It is about more than visibility and is probably badly named. Maybe “ignore” would have been more fitting? It is more about the state of the element and closer in meaning to the input[type=hidden] that we used to see in the days before Ajax.

If you take away the JavaScript and CSS – maybe some network issues, maybe the HTML gets copied elsewhere – the element stays hidden. The point is that it’s meant to be hidden, it’s not styling.

The “hidden” property is also easy to work with and change in JavaScript. In fact, it’s easier than using a CSS class as you don’t have to write any CSS and you know it will work regardless.

<p class="disclaimer" hidden>This is a disclaimer</p>

  const disclaimer = document.querySelector('.disclaimer');
  function showDisclaimer() {
    // with a CSS class
    // with the hidden property
    disclaimer.hidden = false;

Think about why your content is hidden and how it may be reused and choose the most appropriate method of hiding it (or removing it).

What I Learned in 2018

I write a post like this every year and it feels like it gets harder each time. There was a time when I could rattle through a list of new tech, tools or libraries that I’d been using. It feels like I’m much more focused on soft skills these days or firming up what I already know.

Running Workshops

This year I’ve started running workshops to share knowledge with other developers. I’ve run short half hour workshops on Semantic HTML, Sass, Web Workers, Service Workers and Flexbox. I’m not a natural teacher or presenter but it’s been great to give other developers dedicated time to learn something new and by putting together a workshop it’s made me firm up my knowledge of each subject. I’d definitely recommend it as a worthwhile activity to anyone.

Design System

After a period of research and seeing what other companies are doing, I’ve started a design system, documenting UI patterns and styling advice. It feels good to have things documented in one place rather than in my head or having to go back and find the most recent or best usage. I’ve built a base system which loads HTML pages and then created a HTML page for each design element. This gives the flexibility to be able to move the content into another environment in the future without having to start from scratch. It makes heavy use of CodePen embeds to demo the result and share the HTML and CSS.

Design Audit

I’ve learned about design audits and ways of going about bringing designs of separate sites or software together. This is the method we’re planning to adopt:

  1. Select a design element, e.g. buttons.
  2. Go through every page of your site or app and screenshot every different variation which you find.
  3. Put all of the screenshots into an audit document.
  4. Present these differences so that others are aware of the scale of the inconsistency.
  5. Agree on one correct design with which to move forwards.
  6. Change each variation to the new correct design. As you do so, remove that variation from your audit document.
  7. Over time the audit document gets smaller and smaller until it is no longer needed.

Web Workers

Learning about Web Workers and how you can send some operations off to be carried out in the background was very interesting. I’m yet to find a real life use case for them but it certainly opens up a lot of possibilities having multiple threads running instead of just one.

Service Workers

This is another area which seems to have a huge potential, not only for performance by loading resources from the cache but also being able to provide offline content and create a Progressive Web App, a web based app which can run offline just like a native app. I’m hoping to create my own app some time in 2019.

Custom Elements

Towards the end of the year a colleague introduced me to Custom Elements. I was vaguely aware of them before but without the browser support hadn’t taken too much notice. Now they’re usable. Being able to make your own elements that work independently of any framework is very powerful. It means that we’re not longer limited to using a single framework or framework version in an app or across teams.


The final thing that I’ve been working on is trying to improve my use of ES6, gradually trying to break old habits and write in the newer, easier style. The biggest breakthrough I’ve found is the backtick syntax, being able to write HTML and use ${variable} within it for binding. It’s a lot easier than lots of document.createElement() and then setting innerHTML or textContent.


Basically I’m aiming to put all of this new learning from 2018 into practice and get some real working examples.

The DOM Diet and Year Pickers

I think we all know that having a smaller DOM is good for performance but I was never sure what’s considered big or small, or at what points performance is affected. Knowing a little more can change how you approach things.

I was recently doing a performance analysis on some pages and the tool I chose to use was the Chrome Performance Audit. If you open Dev Tools (F12) and go to the Audits tab you’ll see a range of available audits which includes Performance. This uses a tool called Lighthouse and gives estimates for various performance metrics as well as Opportunities and Diagnostics.

One of the diagnostics which came up for me was “Uses an excessive DOM size” and the detail gives us this:

Browser engineers recommend pages contain fewer than ~1,500 DOM nodes. The sweet spot is a tree depth < 32 elements and fewer than 60 children/parent element. A large DOM can increase memory usage, cause longer style calculations, and produce costly layout reflows.

The item that triggered this diagnostic for me was a year picker, a select element with 150 options. Whilst I don’t think it’s really causing any major performance issues it did strike me that 1 parent element and 150 children does seem excessive for just picking out one number from a consecutive range so I started looking at alternative ways we could do this. I wanted to put my year picker on a  “DOM Diet”. I created this pen:

See the Pen Year Pickers by Chris Smith (@chris22smith) on CodePen.dark

Here’s a quick comparison of 4 possible ways of selecting a year from a consecutive range. It’s important to not only look at possible DOM performance but also the user experience side – ease of understanding and ease of use. No point making it faster if it’s confusing or hard work.


This is the standard method. It can have a default value or a blank value as the first option. It’s very familiar, ease to understand and use. It’s probably better to start with a blank value so that we know a user has actually made a selection rather than just left the default. It supports arrow keys and mousewheel. It’s easy to validate using just the required property as the available options are set. It can look untidy in some browsers when long option lists run off the bottom of the screen and it does use a lot of DOM nodes.

Range Input

The input[type=range] doesn’t show a value by default so you have to do a bit of work to show an output value, and a bit more work to do this elegantly. Through testing I found the output value had to go above the slider rather than below so it was not obscured by a finger using the control. I think this is fairly easy to understand but users may not be aware that they can use their arrow keys to get greater precision – either up/down or left/right. It can be hard to control and get the exact figure you want dragging the handle especially using a finger. It can also be wired up to support the wheel event and respond to scrolling up or down on the mousewheel. There’s no way to have a blank value so it has to have a default set. There’s no real validation to be done as it has to use a value in the range. It’s very kind to the DOM too with only 3 nodes.

Number Input

This method is very simple. You just let the user type in the date they want. It can be left blank or have a default value. It can be controlled using arrow keys or the mousewheel though I’m not sure how many users know this. By setting the min, max and step attributes it can limit the range entered when not typing. If the value is typed (or pasted) it will require validation. This uses a single DOM node.

Multiple Number Inputs

This final method is just a bit of a “left field” design. The advantage of it is that it’s very easy to update using the tab key and arrow keys. By having the digits separated the range for each is only ever 10 so in theory it should mean less to change. If left blank it could be set to automatically shift the focus to the next input when a value is added. This makes it as fast to type the 4 digits as a single number input. The min, max and step attributes can limit the range for each digit. It’s light on the DOM too with only 5 nodes. The disadvantage with this method is the validation – it’s going to be a bit more involved, parsing the 4 digits as a single value to be checked and then highlighting the invalid digit(s) could be difficult. On a mobile device with a number pad it also means the pad flashing in and out quickly, which is not a great experience so it’s only really suitable for desktop use.

I’m not sure I’d necessarily go running from the standard dropdown but some of the other methods are certainly possibilities and help keep the DOM smaller.

Why Are We Making Web Development So Hard?

I don’t think I’m the first person to think this by any stretch. There are lots of infographics around showing the difference between web tooling now and 10 years ago and it’s clearly ballooned at an extraordinary rate.

In the last year or so I’ve started working with Angular (as opposed to Angular.js a.k.a. Angular 1) and have also dabbled in Vue and React. All of these frameworks seem to share the same basic ideas – build everything as a component and push and pull them from the DOM as needed. Each component is made up of a HTML template, embedded CSS styles and a JavaScript controller.

This feels like an efficient way of working, very DRY. But is it? You create a component, let’s say a time picker. One it’s developed you can put it into multiple views or uses relatively quickly. However, if you later modify it to work slightly differently, using adding complexity, you have to test it in each use case and make sure it still works with no detrimental effects.

All UIs are basically built up of HTML, CSS and JavaScript. Traditionally HTML is for content, CSS for styling and JavaScript for reacting to user behaviour. With components we’re adding a whole load of JavaScript just to make the basic elements appear before we even get into any behavioural usage. This adds to page weight (size of files being transferred to the browser) and render times. There’s the library itself, often split into many smaller modules, plus a controller for the UI to assemble it and then the components. It could just be one HTML file, one CSS file and one JavaScript file.

Increasingly, what the developer writes in their editor is becoming further and further from what actually appears in the DOM. The frameworks insert a whole host of IDs and classes to elements, bloating the HTML and making it harder to read. Styles are inserted as inline <style> blocks rather than being cached in an external stylesheet. Opening the browser’s Dev Tools to track down and fix a problem is becoming harder, not easier.

Also, the more tools you use, the more you’ve got to maintain, keep up to date, upgrade and replace. It’s creating work just to keep up and inviting technical debt.

I think that what we’re gaining in terms of being able to develop new UI more quickly is all rooted in developer efficiency and production cost saving. It’s not thinking about the user. We’re making things slower for users. The mobile experience on most sites is still awful and the overhead of these frameworks is partly to blame.

The latest frameworks also rely on good browsers with all the JavaScript features. They do not use progressive enhancement but just grind to a halt on an older browser. This goes against the universal nature of the web – it should be easy to read and easy to write. The bells and whistles on the top is just that and should be optional, not prevent the basics from working.

I think we need to get back to making things simple. Write HTML, CSS and as little JavaScript as we can get away with. Go static wherever possible. Make it fast and simple for users. User experience should trump developer experience.