Web dev and insanity

Recently I got assigned web dev work and came to a conclusion: either I am insane or everyone who uses any Javascript framework (e.g. React) or component library (e.g. MUI or Bootstrap) is.12

There are a lot of otherwise really smart people who swear by React. And using two completely different languages and frameworks to write a website and an API that the website calls. And using component libraries that to me just seem completely useless.

I suppose I ought to include a disclaimer: it is almost certainly not the case that React is always a bad idea. In fact sometimes it may be the best idea. My point here is that often (but not necessarily always) it does turn out to be a bad idea.

React

Let’s start with React. Why on earth am I writing className instead of class? Why should I write <Link> instead of <a>? So on and so forth. There are technical reasons for this. I know what they are, thank you very much. But if we are going to depart from standards and muddle up the 1-to-1 relation between “what I write” and “what is rendered”, there better be really big benefits to doing so.

Using <Link> as an example, does making your website a single-page client-side-rendered application actually help anyone?

No! You are not making the next Google Docs. Most websites with a backend are some selectively rendered text, a few images, and a bunch of HTML forms. Websites with significant client interactivity are a different story and not one I know anything about. But if your website is literally just a blog (which doesn’t behave any differently for different clients, by the way), you really should not be writing it in React. It’s just complexity for no reason most of the time. Oh and by the way, this isn’t just “React is unnecessary most of the time”, it’s “Javascript is unnecessary most of the time”. React is much more complicated than plain Javascript, and so the bar for its inclusion ought to be much higher.

Component libraries

Component libraries are also hard to justify most of the time. Let’s take one of the more popular libraries, React Bootstrap (to be clear, Bootstrap CSS itself seems fine), and look at the first component they have: the Accordion. Here is the HTML code that gets generated.

<h3 class="anchor anchorWithStickyNavbar_LWe7" id="basic-example">
    Basic Example
    <a href="#basic-example"
        class="hash-link"
        aria-label="Direct link to Basic Example"
        title="Direct link to Basic Example">
    </a>
</h3>
<div class="playgroundContainer_TGbA">
<div class="playgroundHeader_qwyd">Result</div>
<div class="playgroundPreview_bb8I">
  <div>
    <div class="bs-example">
      <div class="accordion">
        <div class="accordion-item">
          <h2 class="accordion-header">
            <button type="button" aria-expanded="true" class="accordion-button">
              Accordion Item #1
            </button>
          </h2>
          <div class="accordion-collapse collapse show" style="">
            <div class="accordion-body">
              Body text #1
            </div>
          </div>
        </div>
        <div class="accordion-item">
          <h2 class="accordion-header">
            <button type="button" aria-expanded="false" class="accordion-button collapsed">
              Accordion Item #2
            </button>
          </h2>
          <div class="accordion-collapse collapse">
            <div class="accordion-body">
              Body text #2
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Yikes. Why is the title of a collapsible item an <h2>? This is not good from an accessibility standpoint. This collapsible item is organized under the <h3> with the title of “Basic Examples” for Pete’s sake. So clearly, it and its title should semantically be a part of the <h3> header. But the HTML code indicates otherwise. And any programmatic tool which relies on the semantics of the HTML (which by the way, includes accessibility software) is not going to work well if you generate semantically incorrect HTML. And no amount of aria tags will make up for the fact that your HTML is terrible.

Also, a button? It’s not the worst thing you can do, I guess. At least aria-expanded=true is properly set. But you can do so much better for a dropdown.

Dropdown code
<details>
    <summary>
        Dropdown code
    </summary>
    <div>
        Pretend there is some code here.
    </div>
</details>

Given how simple this is, why would you ever write this code?

import Accordion from 'react-bootstrap/Accordion';

function BasicExample() {
  return (
    <Accordion defaultActiveKey="0">
      <Accordion.Item eventKey="0">
        <Accordion.Header>Accordion Item #1</Accordion.Header>
        <Accordion.Body>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat. Duis aute irure dolor in
          reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
          pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
          culpa qui officia deserunt mollit anim id est laborum.
        </Accordion.Body>
      </Accordion.Item>
      <Accordion.Item eventKey="1">
        <Accordion.Header>Accordion Item #2</Accordion.Header>
        <Accordion.Body>
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
          minim veniam, quis nostrud exercitation ullamco laboris nisi ut
          aliquip ex ea commodo consequat. Duis aute irure dolor in
          reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
          pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
          culpa qui officia deserunt mollit anim id est laborum.
        </Accordion.Body>
      </Accordion.Item>
    </Accordion>
  );
}

export default BasicExample;

The <details> tag is more accessible and easier to style to boot. There is literally no downside.3

And the worst thing is that frameworks like React Bootstrap pass automated tests like Google’s Lighthouse with flying colors. But look for a couple of seconds and you can already see issues. (I don’t know if Accordion titles are always <h2> elements, but I suspect the answer is yes. Regardless, it’s not the greatest sign if the title is a header on their official website.) And React Bootstrap is doing quite well for itself, actually. Just look at MUI’s accessibility issues on GitHub.

But this isn’t supposed to be an expose about accessibility.4 The main point here is that using a custom “Accordion” component is moronic if <details> is already available to you at no cost. Accessibility just happens to be one of the big reasons it is stupid.

A potpurri of unnecessary uses

There are a lot of reasons people have to use React, component libraries, and other similar things. Let’s run through them:

Now I am not going to go as far as to claim React is totally useless. This is very likely untrue. But it is the case that a lot of the reasons people think React is useful are total hogwash, at least for their specific use cases.

What do you do?

So how should you write a website, particularly a full-stack website? Two years ago5 I teased an answer to this question:

I hope this post was helpful! A post on full-stack websites will be coming soon :)

Two years later and I will tease it a bit more. I am planning to write a total of three entries, one of which is already done:

  1. I will start with an abstract, simplified explanation of the principles of client-server communication. We will start with username-password authentication, then dive into cookies, and finally we will discuss why encryption is necessary.
  2. We will add more detail to the abstract client-server model. The client is usually just the browser; the server can be divided into the API and the database. Furthermore, there are many other types of clients that work. For instance, you could use the terminal to interface with a CLI, which sends a request to a programmatic API that queries the database. The important point is, anything on the server can interact however it wants with anything else on the server, and with a few exceptions, the same is true for the client.
  3. We end off the series by looking at web frameworks, discussing what a “tech stack” is, and some of my recommendations for what tools to use for creating a website.6

I plan to write the first two entries fairly soon. The last entry will be written eventually, likely when I have finished Glee.


  1. Those who have followed this blog know what I think the answer is :)↩︎

  2. There are some oases of sanity out there.↩︎

  3. Technically a simple dropdown doesn’t match the function of an accordion, since accordions enforce that only one item is open at once. Putting aside how terrible of a feature this would be in most cases, it is quite easy to implement with just HTML and CSS.↩︎

  4. I am not the right person to write about this, and I’m sure people who create components are trying their very hardest to make components accessible.↩︎

  5. How time flies!↩︎

  6. You can probably guess what they are. Avoid React, make the website (one of) your APIs (though this does not preclude you from creating a REST API that, say, a CLI could interface with). Write your backend and frontend in the same language, ideally in the same project so that your backend types agree with your frontend types. (For example, you can use a Rust framework like Axum to both query the database when appropriate and generate HTML.)↩︎