← Back
[W] Writing

Screenshots lie about components

For a while I was a brand ambassador for 21st.dev, where developers find and share UI components. The job was simple to describe: publish components people would actually want to use.

It's harder than it sounds, because of the way people find components. They scroll past pictures.

A picture rewards exactly the wrong thing. Here's the same card, twice, with the same code.

Design systems

A short guide to shared components.

The screenshot.
Image failed
Centralizing a design system across a mature dashboard with a very long history

undefined

Tuesday, in your project.
Both are real HTML, using one set of styles. The left one gets the likes. The right one is what you get in production.

A screenshot can't show you what happens when the title is long, the image fails, or the list is empty. It can't show keyboard focus. And it certainly can't show you what the code is like once you've copied it.

What a picture can't tell you

Component platforms fill up quickly with things that look great and fall apart in a real project. So the question I kept asking was what was missing from the picture.

What the screenshot shows
  • Default, with perfect content
What you're actually adopting
  • Focus
  • Disabled
  • Loading
  • Empty
  • Error
  • Long text
  • Touch
  • Reduced motion
  • Readable code
  • Its dependencies
When you copy a component, you're taking on everything in the second list, whether or not you can see it.

The bar I used

Every component I published had to pass the same four checks.

  1. It solves a problem that shows up in real products. If I couldn't name the product it belonged in, it was probably a demo.
  2. It reads clearly. Someone can open the code and follow it.
  3. It handles the unglamorous states. Focus, disabled, loading and empty.
  4. It doesn't drag a pile of dependencies with it.

Clean, useful, practical. If a component was only impressive, it didn't get published.

Notice that three of those four can't be seen in a screenshot. That's the problem with judging by pictures, and it doesn't just apply to the people browsing. It applies to me while I'm making the thing. It's very easy to stop the moment it looks done, because looking done feels so much like being done.

The real test is the second person

A shared component has one job, and it comes after the demo. Someone has to change it.

They'll want a different colour, a different size, and a slot for something you didn't think of. The moment they have to fight your code to do that, they rewrite it from scratch, and your component has failed, however good it looked.

  1. Looks great
  2. Gets copied
  3. Needs one change
  4. Fight it, or rewrite it
Most of a component's life happens after the screenshot, and most of that starts at the red step.

This is why I've come to think sensible defaults and readable structure are a design problem. You're designing for two people at once: the one who'll use the interface, and the developer who has to live with the code.

How to check before you copy

Before adopting a component from anywhere, including from me, I'd try this. It takes about five minutes.

  1. Tab through it without a mouse.
  2. Paste in the longest real text you have.
  3. Give it no data at all.
  4. Make it load slowly.
  5. Try to change its colour.
  6. Look at what it installs.

Most pretty components won't get past the first two. That's useful to know before it's in your product.

I took all of this with me into HextaUI, whose whole description now ends with "loading, error, empty and other hard states handled." It's what the job taught me. There's a big difference between finishing a component and getting it to the point where it looks finished.

Next