Frontend Design, React, and a Bridge over the Great Divide

Frontend designers create the HTML, CSS, and presentational JavaScript code that powers web products’ user interfaces. I see frontend design as helpful mortar that bridges the gap between design and development.

a venn diagram showing design on one end, development on the other, and

Of course “frontend designer” may or may not be the right title for it. Some others titles that companies use are:

  • UI developer
  • Client-side developer
  • UI engineer
  • Design engineer
  • Frontend architect
  • Designer/developer
  • Prototyper
  • Creative technologist
  • Devigner (ugh)

Whatever the label is, these people specialize in crafting the code that powers the UIs of websites. Here are just some of the things frontend designers spend their day doing:

  • Crafting semantic HTML markup with a strong focus on accessibility, in order to make experiences that are friendly to browsers, assistive technologies, search engines, and other environments that can consume HTML.
  • Creating CSS code that control the look and feel of the web experience, tackling colors, typography, responsive layout, animation, and any other visual aspect of the UI. Frontend designers architect resilient CSS code with a focus on modularity, flexibility, compatibility, and extensibility.
  • Authoring JavaScript that primarily manipulates objects in the DOM, such as making an accordion panel open or close when you click the accordion title, or closing a navigation panel.
  • Testing across browsers and devices to ensure the UI is functional and good-looking on a never-ending stream of desktops, mobile phones, tablets, and all manner of other web-enabled devices (and even anticipating ones that haven’t been invented yet!)
  • Optimizing the performance of frontend code in order to create lightweight, fast-loading, snappy, jank-free experiences.
  • Working with designers to ensure the brand, design vision, and UX best practices are properly translated into the browser, which, to remind you, is the actual place actual people will go to use the actual product.
  • Working with backend & application developers to ensure the frontend code is compatible with backend code, services, APIs, and other technology architecture.

You may have read the above and thought, “Well no shit, Brad.” But I’m spelling out these responsibilities to make a point: this is hard, nuanced work that requires a lot of thought, care, and attention. Frontend design is a full-time job and should be treated as such.

You may have also read the above and thought, “Isn’t that what a frontend developer does?” And the answer to that is…maybe. As the absolutely fantastic article The Great Divide covers (seriously if you haven’t read the article, do yourself a favor and go read it now), the term “frontend development” is incredibly loaded now that “JavaScript dun got big.”

Image from The Great Divide on CSS Tricks representing the split between the “front of the frontend” and the “back of the frontend”

“Frontend development” is now so loaded that I quipped that as a frontend designer I live on the “front of the frontend”, while there are plenty of other developers living on the “back of the frontend”. I’d like to lean into that distinction because this great divide is played out in a very real way in JavaScript frameworks like React.

A frontend designer lost in React-land

React homepage that reads

React’s website greets you with this message: “A JavaScript library for building user interfaces”.

Hey, I build user interfaces! That’s actually sorta my thing, and I’ve been building user interfaces professionally for well over a decade now. This seems right up my alley.

Except it isn’t. Or at least it isn’t a thing that is obviously beneficial for my work as a frontend designer.

In his post, The Elements of UI Engineering, Dan Abramov articulates a lot of the challenges he faces when building the UIs of large scale applications. This post to me perfectly highlights the split between “back of the frontend” and the “front of the frontend”. Everything he covers in the post sounds incredibly important, but admittedly much of it also reads like a foreign language to me. Keeping data in sync, cache invalidation, managing state, handling routing nuances, and some of his other considerations have thankfully never been part of my job. And I’d prefer to keep it that way.

The rise of JS frameworks like React was no fluke. These frameworks provide solutions for real needs developers have when building big applications. I’m glad these frameworks exist to help those application developers with that stuff.

But a by-product of creating those solutions involved, uh, eating HTML and CSS. Just sucked up the HTML and CSS part of frontend web development into one big ol’ ball o’ JavaScript. And that throws a pretty serious curveball in the direction of frontend designers.

I shared my struggle to learn React, and caught a lot of heat from a whole bunch of people. But I also got — and continue to get — a whole lot of (often private) correspondence from a slew of people who feel equally overwhelmed. And in case you don’t believe me, this recent post by the great Jonathan Snook (a longtime hero of mine who has been doing this stuff for longer than me) shared his own struggles learning React:

It was difficult to come in thinking I was a senior developer and instead feeling like a junior. I often spent more time than I should have on my own just trying to understand things, frustrating myself in the process. I’d go a day or two or three of making no progress before reaching out to someone to explain something I didn’t understand but feeling like I should, feeling like I wasn’t good enough.

It seems like frontend designers are getting stuck on React, so I definitely feel there’s something here worth poking at.

Component stew

In React, everything is a component. The button a person actually sees on the screen is a component. The business logic that handles what happens when that button is clicked is a component. The route the application takes you to when you click on it is a component. It’s components all the way down.

None of this is wrong, but I can’t exactly fault people for feeling overwhelmed when they’re presented with an app that contains this big stew of components that do wildly different things and they have to unpack it all. Again, here’s Jonathan:

Throw in everything else at the same time, though, and things get confusing because it’s hard at first to recognize what belongs to what. “Oh, this is Redux. That is React. That other thing is lodash. Got it.”

We’re not just dealing with React, but rather React and Friends.

I’ve now worked in multiple React codebases that (to my eyes) are a tangle of business logic, presentational code, data-manipulating code, and other terrifying-looking forms of code wrapped up in an opaque file structure. Squint your eyes and you might find some HTML sprinkled in there somewhere. This is no doubt due to the implementation, but it’s overwhelming nonetheless.

I’ll admit I was feeling pretty defeated until I saw a glimmer of hope in Dan Abramov’s article Presentational and Container Components. Dan talks about the distinction between presentational (dumb) components and container (smart) components. It gave me the first sense that there may be a place for me in this whole crazy JS world after all.

I’ve now been working on React-based client projects for about a year and a half now, and I’m happy to share that this frontend designer has carved out a path in this brave new JS world.

A place for frontend designers in this brave new javascript world

As the pattern library craze was ramping up, Dave Rupert struck a nerve when he said we need to deliver “tiny Bootstraps, for every client”.

Responsive deliverables should look a lot like fully-functioning Twitter Bootstrap-style systems custom tailored for your clients’ needs.

He hit the nail on the head, especially the “custom-tailored for your clients’ needs” part. That’s what we’ve seen come to fruition with the explosion of design systems: all these pattern libraries containing solutions to each organization’s thorny UI problems.

Coming back to Bootstrap, the problem in the olden days was that developers could wire up Bootstrap’s CSS and JS files, but had to manually translate Bootstrap’s HTML into their own environments.

In this brave new world, things work differently. We now have directly consumable components, meaning that a component’s structure, style, and behavior can all travel together as a neat, tidy bundle. This changes things in tremendously exciting ways.

In the React world, there are frameworks like Material UI and React Bootstrap that translate these popular frontend UI libraries into directly consumable React components. These prefab solutions have their place, but many organizations like are crafting their own custom UI component libraries to serve their needs. Check out Salesforce’s Lightning Design System for React, The React flavor of IBM’s Carbon Design System, Shopify’s Polaris, and many more examples.

So with directly consumable UI components in mind, here’s my updated take on Dave’s words of wisdom:

Frontend design deliverables should look a lot like fully-functioning React Bootstrap-style systems custom tailored for your clients’ needs.

It’s a subtle but important difference. Instead of merely creating components’ reference HTML, CSS, and presentational JS, frontend designers can create directly consumable HTML, CSS, and presentational JS that back-of-the-frontend developers can then breathe life into. But note that “custom tailored for your clients’ needs” is still intact. I’m not saying “Just use React Bootstrap,” but rather create a library of UI components that serves your specific needs.

As I see it, directly consumable UI components serve as a bridge between The Great Divide. It creates a healthy handshake between the front of the frontend and the back of the frontend.

Venn diagram showing

So in order to make this happen, I had to add the following responsibilities to the list I laid out at the beginning of this post:

  • Create a library of presentational UI components that are packaged up to be consumed by other developers.
  • Author and document a robust, intuitive component API for each presentational component so developers consuming the component can easily plug whatever they need into to it
  • Determine how flexible or rigid the component library should be, working with developers to understand how open/composable or rigid/locked down each component should be.
  • Maintain the presentational components as a product, meaning I have to handle versioning, deploying, governance, release notes and all the operational stuff goes into maintaining a software product.

And most importantly, I had to roll my sleeves up and learn JS frameworks like React. Not all of React and Friends, mind you, but the parts of React that are needed to do good frontend design work.

What do consumable UI components look like?

So what does this look like? Consider an alert component:

A UI alert component showing a green checkbox, an alert title, and a description of the alert

The basic gist of the markup for the component (written in JSX) would look something like this:

<div
  className={`c-alert ${variant}`}
  role='alert'
  {...other}
>
    <Icon
      name={iconName}
      className='c-alert__icon'
    />
  <div className='c-alert__body'>
    <h2 className='c-alert__title'>{title}</h2>
    <div className='c-alert__description'>
      {children}
    </div>
  </div>
</div>

We’re carving out slots for the dynamic bits (such as title) that will be populated by the application developer.

Once the component is built, others need to be able to use it. One way is to have a “ui-components” folder within the application, but better yet is to publish it as its own product (Look ma! I’m publishing my own UI framework!). If you go that route, back-of-the-frontend developers can suck in your component library like so:

npm install our-react-design-system

Once the component library is installed, devs can plug in that alert component:

import Alert from "our-react-design-system/components/Alert";
<Alert 
  variant="success"
  iconName="checkbox"
  title="Profile updated!"
>
  You have successfully updated your profile.
</Alert>

Where’s that copy coming from? What’s triggering the alert? That’s the realm of back-of-the-frontend developers. They take these presentational UI components and wrap them in a layer of smarts that handles business logic, data manipulation, and whatever else they need to successfully implement the alert component in the real application.

Circle that says

I love React consumable UI components

In the last year and a half of working in React, easily my favorite thing about working with React isn’t specific to React. It’s the idea of a directly consumable components. Ultimately, this is why I’m so excited about diving into web components, because they are native to the web and interoperable with different JS frameworks.

Here’s what’s so awesome about the concept of directly consumable UI components:

  • It centralizes the frontend codebase – allowing frontend specialists to manage a single source of truth for markup, styles, and presentational JS. This helps reign in spaghetti frontend code sprawl and allows frontend designers to be more deliberate with how they architect the frontend code. They can iterate over and improve the UI component code, and propagate those changes out to anywhere that component is used. Powerful stuff!
  • Frontend designers control the frontend code. I’ve been on plenty of projects where non-frontend devs copied and pasted the markup they needed and omitted attributes they didn’t understand. Sure enough, ARIA attributes seemed to mysteriously disappear, divs were shoved directly under ul tags, and the document structure was an absolute mess. Historically, frontend designers could do little more than weep into their pillows at night. But with directly consumable UI components, frontend designers retain control of the UI code, and provides other devs an API to interact with rather than exposing the source markup, styles, and presentational JS.
  • Can bake in frontend best practices into components – This is huge and exciting. Because UI components are centrally managed, you can bake in frontend best practices into the components, and other developers get those best practices for free. I’ve written about how you can automatically generating IDs in order to create more accessible form controls. Application developers no longer have to worry about rote frontend chores and instead can focus on other more worthwhile tasks.

My workflow

I recently gave a talk about how I’ve been working in this way, but the gist of my workflow is this:

  • Work in Storybook as a frontend workshop environment that allows me to build out UI components through the lens of building representative product pages. Most Storybooks I see online contain only lower-level components, but we use our Storybook to demonstrate all our product pages. These pages are living, breathing comps that the team reviews and back-of-the-frontend developers use as a reference as they wire up the page to backend services and the rest of the application.
  • As I build out product screens, I create the API for each component. Should it be <Button text="Click Me" />,<Button label="Click Me" />, or <Button>Click Me</Button>? Turns out authoring an intuitive, consistent component API is something I really enjoy.
  • We review our pages and components with our stakeholders, and when everyone’s happy, we cut a new release of the component library containing any new components, variations, and fixes.
  • Application developers then pull down the latest and greatest changes into their applications to receive the new features and updates.

There’s a lot of detail to this workflow that I can’t cover here; that’s a post for another day.

Stuff I’m still working through with React

As a frontend designer, I’m really happy to have finally found a way to operate in these new JS waters. Many people have gotten in touch asking for an update on my journey in React-land, and this is it. While there’s a lot to like about React (especially the consumable components that I highlighted above), there are some things I still take issue with or am still working through:

  • I still don’t really love writing JSX. While I’m definitely a lot more fluent in it now, I dunno, it just still feels a bit weird to me. I could share some specifics but that would only invite a bunch of angry nitpicking comments. All I’ll say is that when I go over to projects where I’m writing HTML or HTML-like stuff (Vue, for instance), it feels like a breath of fresh air.
  • React and Friends – I found this talk by Evan You helpful at explaining how the React library itself intentionally has a pretty light footprint, which means that other libraries are needed to make an application tick. That light footprint has resulted in a huge ecosystem built around React, and no doubt has contributed to its massive success. But as I mentioned above, this leads to having to find the seams of each library, and requires you to keep up to speed with this incredibly fast-moving React and Friends landscape. I’m no fortune teller, but I have a hunch a lot of teams are going to spend the next few years untangling a constellation of former “new hotnesses”.
  • Strong opinions in the community – I was talking with a React advocate about how our team had to refactor our Accordion component so the client could use Redux to manage the panels’ open/closed state. Before I finished the sentence, he responded with a dismissive “pssshhh nobody uses Redux anymore!” Uh, yes they do. I’m literally telling a story about how my client uses Redux. I see a lot of grenades and Strong Opinions lobbed out by some in the React community that to me contributes to this general feeling of FOMO chaos. Every team I work with tells me how hard they’re trying to keep up with the Joneses.
  • Not super into the quasi-religious vibe of it all – Anytime I might comment on or criticize something even tangentially related to React, I feel like people come out of the woodwork to shout me down. It seems like some people are quite annoyed I haven’t yet accepted React as my lord and savior, and that any questioning, criticism, or commentary is blasphemy. It’s an interesting phenomenon. Of course there’s plenty to like about React, but at the end of the day it’s a tool. And yes, there are people behind the tools and technologies we use, so we need to be careful to decouple the concepts, and technologies from the people who create and use them.
  • Tooling and build step stuff are tough to get my head around – Tooling, environment setup, and build steps seem to be things that some people really enjoy and other people do not. I do not enjoy that stuff, and I’m happy to let other developers own. I’m super happy with where I landed with my presentational React setup (Storybook and a literally empty Create React App), but whenever I have to venture into application codebases a sense of doom washes over me.
  • Trying to figure out what’s a real trend vs a flavor of the month – I saw a tweet promoting “The modern front end design system stack” that lists out several GitHub projects. Not “A” stack, “The” stack. That’s freaking fashion. I read that as “Shop the Fall 2019 lookbook”. But amidst all that noise are genuine trends that will impact how I do my job. I spend a lot of time asking myself “Do I need to care about this in order to do my job?” Hooks? Yep. Routing? A little bit. State management. A little bit. Data storage? Probably not. Of course somebody needs to care about those things, and I hope to closely partner with them.

What I would like to see

  • I’d love to see more frontend designers step up to the plate and learn the front-of-the-frontend parts of React (and/or other JS frameworks and/or web components). Again, you don’t have to learn all of React And Friends, but learn the parts that allow you to deliver great markup, styles, and presentational JS to these environments. Doing this allows you to directly contribute to the final products in very real and important ways.
  • I’d love to see back-of-the-frontend developers recognize the importance of frontend design and make room for front-of-the-frontend people in your codebases. Sure, things all happen under one big JavaScript roof now, but the concern around gatekeeping is real, so do your best to make it welcoming for other skillsets to contribute.
  • For the love of all that is holy, recognize that there is value in specialists who focus on application code or UI code. Organizations, stop pretending you only hire “full-stack developers” and hire some specialists. There’s just SO MUCH WORK TO DO. Everything involved in the front-of-the-frontend is a full-time job, and no doubt the same is true of the back-of-the-frontend. Hire specialists that can kick ass in their respective spaces rather than only hiring generalists who can do just an okay job across the board.
  • I’d love to see more nuance happening at an organization/industry level. When you say “we’re hiring a React developer”, what exactly do you mean by that? “React developer” is almost as vague as “frontend developer”, so clarify. Are you looking for a person to specialize in markup and styles? A person to author middleware and business logic? A person to manage data and databases? A person to own build processes? If the answer is “all of the above”, see the above point about specialists.
  • Because it’s now all “just JavaScript” and “everything is a component”, it takes a lot of care and thought to create a thoughtful separation of concerns in these environments. Again, this is about nuance. I really like the idea of managing the UI component library as a separate product because it makes the split between the front-of-the-frontend and the back-of-the-frontend obvious. But even if you don’t go that route, be sure to organize projects in a way that is clear where UI-centric code goes vs application-centric code goes. And crucially, make room for people with different skillsets in your codebase.
  • Stop saying crap like “if you don’t like React just don’t use it.” That’s not how this works. I don’t make these decisions; I work with teams of people who choose the technologies we’re working with. Rather than boxing people out, foster an environment that encourages people from different skillsets to participate.
  • It’s OK to learn these libraries and have no intention of becoming a fullstack 10x developer ninja warrior. No doubt there are many front-of-the-frontend people who can and do back-of-the-backend stuff. And vice versa. And no doubt there are many people who aspire to do it all. That’s great! But I’m here to say there’s nothing wrong with being a specialist. Again, there’s SO MUCH WORK TO DO and there’s plenty of room in the pool for everyone.

It’s been an interesting ride, and I’m looking forward to continuing to learn and evolve. Thanks for reading.