You only Need this 1 Rule to have Clean UI Code
Start doing this today, and your frontend code will be much cleaner pretty soon
I recently stumbled upon this simple rule that makes your frontend code much cleaner, easier to maintain and more fun to work with.
“Clean”, “easy to maintain”, “fun to work with” — the classic hallmarks of Clean Code. And in case you haven’t read Robert C. Martin’s classic and recognize the term — clean code is source code that’s written for humans.
More specifically: Clean Code is code that your teammates will be able to work with and not hate you for it. And as a side bonus, code that’s easy to work with tends to be better maintainable, more reusable and overall more hygienic as in less bug infested (aka “cleaner”).
So between React, Vue.js, legacy Handlebars projects or just plain old Vanilla JS, how can we ensure clean frontend code? Read on to find out…
Component Driven Development (CDD)
To understand The Rule, we first have to take a look at the philosophy of Component Driven Development. The idea behind CDD is simple — you have different granularities of frontend components that together make up your app.
It’s a little bit like the testing pyramid — a hierarchical system to think about structuring code in a way that different levels have different responsibilities:
Components are the atoms of this hierarchy, the smallest unit. Components are small things like Buttons, Tooltips, Inputs, Avatars.
Fragments are a combination of components into composite structures like Forms, Headers & Toolbars.
Pages are combinations of fragments into the pages that are served under the different routes of your app like the Home page, Timeline page, Settings page, login / logout page.
Integration is the only place where you add business logic — everything before this point is made up of purely visual components with props or attributes & event handlers. The integration part is where you add logic, network requests, API calls etc. This is where your visual page components turn into the fully fledged web app, marketing landing site, documentation page that you deliver to your users.
In Component Driven Development, even pages are treated as purely visual components that don’t have any business logic, network requests, or API calls in it. All the logic is added on top of the page-components.
💡 IDEA: What if we treat our pages as purely visual components, too?
What’s so special about CDD is that pages are treated as purely visual components. And that’s a good thing — think about it:
Pages are typically the most messy parts of your complete app. Often you will find logic + visuals tested together making for bloated tests that mock gravity and space-time itself.
By treating pages as purely visual components & adding the business logic and network requests on top you gain the following benefits:
- No mocks in (page) tests — just props & event handlers ✅
- It’s way easier to make pages responsive ✅
- Amazing separation of concerns ✅
Downside: Yes you have to invest more work into building good abstractions (welcome to modern software development — first time?).
The second thing we need, in order to understand The Rule is Storybook. If you are one of the 60.000+ people who starred Storybook on Github, just skip this section to get straight to The Rule 👇🏻
For anyone who doesn’t know Storybook — here’s a quick intro: Storybook is a gallery for your visual components:
Storybook relies on only two things: Props (the “Controls” tab) and event handlers (the “Actions” tab).
For each of your visual components, you can define stories which are sets of props that storybook will set for your component (the Histogram story in this case displays the Default, Empty, and Normalize states).
As you can see from the gif above, the states are merely predefined prop values. Storybook makes it super easy to change the props interactively to see for yourself how this affects the component. This makes it super straight-forward to test edge behavior and get the details just right.
Oh and Storybook is super easy to setup!
Add storybook to an existing CreateReactApp, Vue CLI or Ember CLI project:
$ npx sb init
With Storybook explained and CDD refreshed in your mind — here’s the rule.
Are you ready?
Everything that the user sees must be in your Storybook.
Sounds simple enough — so why does that work to produce clean UI code?
If we assume that everything that we see in Storybook are purely visual components (yes you can get around that — exceptions prove the rule here) which only rely on props & event handlers, then that means that everything we see in Storybook is automatically made up of side-effect free, pure functions (class style components acting like essentially pure functions if they only receive through props & call back through events).
So if all of your app’s visual elements are side-effect free, pure functions — what do we get? A code base that’s a lot easier to test, maintain & refactor.
Want to switch from REST API calls to GraphQL? Just swap out the part of the integration that fetches data. Want to swap out your state manager or switch away from one entirely? Just change the integration part that manages state. Want to change away from Material UI to a new brand identity? Gradually migrate out the components until it’s all shiny & new (without having changed a bit in its functionality).
That’s the promise of clean code — you spend a little more time & effort in the beginning, but become so much faster for it down the road.
And it gets better!
Good for you + your team
If you’re not yet convinced, here’s how this rule is good for your team overall:
Benefit #1: Easy to commit to
This rule is truly something the whole team can commit to. Storybook can be built & hosted statically, so you can easily make it accessible to your designers, POs and curious DevOps team mates :)
Everyone can double check whether the visual elements they see on the app / in a ticket also appear in the Storybook — like that it’s easy to hold each other accountable.
Benefit #2: One (visual) language for the whole team
Raise your hand if had to fence off weird feature requests from your PO or esoteric ideas from your designers because they didn’t work with the components you already have?
Storybook changes that. Got a request that re-invents the wheel? Gently nudge your team mate to the storybook and ask them to reuse what you already have as much as possible.
Benefit #3: You’re freed up to focus on details (again)
Because storybook makes it easy to develop the visual aspects in isolation, you can afford to take care of details again. Building a new feature and had to make a few tradeoffs between what your designer wanted and what you could build? Just show them — even before any business logic is implemented.
Shorter feedback cycles between frontend & design are always a plus for the overall user experience.
Benefit #4: Bring your own style
No more discussions about class-style vs. functional-style components in React! Everybody (in theory) can bring their own style because at the end of the day, if it only relies on props & event handlers, how bad can it be?
That’s exactly the point of good abstraction — it shouldn’t matter what happens behind the interface.
Benefit #5: Easier Onboarding
Last on the list, definitely not the least important one in here. Whether you’re onboarding new developers to the team, or getting a junior dev started — in both cases it’s a breeze.
New team members can really quickly figure out how everything works (due to the clean separation between business logic & visuals), juniors have a very limited blast radius in what they can break and don’t have to implement everything all at once.
They can focus on just the visuals and then focus on just the business logic — or vice versa. That’s a win for anyone you’re onboarding, regardless of their skill level.
I can’t say whether this is the rule to end all rules when it comes to clean UI code. Your team might have individual needs for rules that help you do your best work. What I was blown away by is just how simple this rule is and how realistic it is to commit to this as a team.
Start doing this today, and your frontend code will be much cleaner pretty soon.
And no, you don’t have to refactor your complete codebase over a new tool in your belt. Just apply the Scout’s rule: Leave the campsite better than you found it — or rather leave the Storybook fuller than you found it.
— — — — — — —
Thanks for reading!
I’m Jonas and I work at Axel Springer — Europe’s largest publisher — where I’m uniting our 3000+ developers worldwide into one global Tech Community.
If you liked this blogpost, feel free to clap 👏🏻 or share it on socials!
If you want to get in touch or would like me to give this talk at your company or team, feel free to reach out:
TL;DR (too lazy ;) didn’t read):
You can also watch me give the talk this blogpost was based on 👇🏻