Implementing a redesign in large, often semi-well aged Rails or Phoenix apps is a daunting task as one is often faced with a lot of legacy and poor organization of the view layer, JavaScript and CSS. Still, tackled with the right strategy and tooling, it can be a super rewarding experience for both, the client and the team.
At bitcrowd we recently did a couple of those redesign projects for our clients. Let's explore how we demystify them, what strategies work for us and where the challenges are.
🌊 Problems​
Things on the internet age quickly. Some age well, some don't. A web application may very likely look dated and just not state of the art after some years out in the wild. This process is heavily influenced by the fast turning tech standards and the iterative nature of development projects, which can lead to a loss of an overall UX & design vision for the product.
The need for a visual overhaul of an application can also become apparent when the design stands in the way of new features. For example, an horizontal topbar for an app menu can be the right choice when the navigation is concise, but this choice does not scale as new primary features requiring an entry in the main navigation menu are added.
Finally, disorganized styles, templates, and generally a lack of componentization, can cause an increase of complexity for adding or updating views. Let's look at a classic example: buttons being styled by how they look, instead of what they are.
<!-- Looks -->
<button class="button button--blue"></button>
<!-- Roles -->
<button class="button button--secondary"></button>
When a developer is asked to change the looks of a button variant in the app, having a componentized button means there is only one file to change, as opposed to an endless amount of template files to update.
Redesign: how hard can it be?​
🤿 It's not just the looks​
In most cases, the term "redesign" goes way beyond changing a few colors, fonts or images. It is most likely a complete change of the look and feel of the app, including a new navigation, restructuring of content, etc. A redesign has to be carried on the entire view layer, not just the styles.
🎰 It's not just legacy​
Plus, the new design may also include new features. Some might be hiding in plain sight: a new redirection logic that is invisible in the new design files, or a text change that requires to wire the data from the controller differently. These can easily be missed when estimating the effort. There can also be real new features, which can be hard to estimate as they assume that the application is in a futuristic state.
🚧 It's blocking everything else​
Last but not least: it is practically impossible to release a redesign in small cycles. That would lead to Frankenstein-y UIs and user flows. In other words, the majority of the visual work has to be finalized before the launch: it has to be a big-bang production release. This can be problematic as redesign projects typically take months to reach a first release.
Strategy and timeline​
When clients approach us to implement a redesign for them, they usually have large parts of the new design already laid out by their (or external) designer(s). Starting from there, we mostly go through the same series of steps with them:
Design access and feedback​
Over the years, Figma ended up being our go-to tool for anything design related, being it design systems, prototyping, wireframing or UX design. There are alternative tools which do the same. We for instance used Zeplin for a while, too. Regardless of the tool, the important part is to have one source of truth for all involved parties.
In the ramp-up phase of the redesign, we review the designs with the client, check for consistency, verify what's doable within the app and check for completeness of the new design. The most important task here is to identify when the design includes new features which aren't present in the current state of the app.
Ideally, the designs should be "final" by the time the actual implementation starts.
Estimate the effort​
Estimating the effort of a redesign can be quite hard. When putting together the work packages and labelling them with their effort, separating pure redesign work from new features and backend-only work turned out to be useful for us. The key point is again to identify when the new design accidentally or deliberately adds or changes functionality and which additional effort this brings.
Another thing to take into account for estimating the effort is the potential overhead of switching over to a different UI abstraction or library. Let's say we're moving a Rails app from using partials to ViewComponents, an old Phoenix app from partials to PhoenixComponents or even from controllers and dead views to Phoenix LiveView. Doing this with consistency is essentially a rewrite of the whole view layer.
At best, one has thorough knowledge of the app and the codebase, its patterns, its degree of legacy and where complexity lies. It can be interesting to factor these in the effort estimation: how comfortable is the team with the codebase, what is the test coverage, are the views already componentized, etc.
UI Abstraction & Integration strategy​
Once the page designs are set up properly in Figma, they can be used as a basis for extracting design tokens like colors or spacing and shared components. It may seem tempting to be sloppy on this step, since it does not change anything within the app itself yet. But being concise about having the whole new design set up properly in Figma turned out to be absolutely worth the effort in 100% cases for us.
On our redesign projects we identify core components and build a design system and a component library. Those core elements, like typography, buttons, cards, etc, are built in isolation using the given frameworks capabilities to test and showcase them with Storybook (React), Lookbook (Rails) or PhoenixStorybook (Phoenix). Being able to develop our core components in isolation, showing all of their different states without interfering with the existing application is a huge boost for productivity as it allows building the components (styles & logic) independent from using them.
For the CSS, we often start completely from scratch. Either moving the old rules to a "legacy" folder of having the new ones in a separate redesign folder. One of them should be empty and gone at the end. It's always super satisfying to delete old code...
Implementation​
Any changes necessary from the backend are ideally done before the frontend ticket is worked on. So that when it comes to implementing the new design, all the data is already present. It can for instance also make sense to already render out plain data that is needed for a new design, but keep it hidden in the DOM. This way, the person taking on the design ticket has an easier time: with unit & feature tests already in place to make sure they did not break anything, and the changes in the PR being only on the view layer.
Without a tool like Storybook, depending on the size and complexity of the application, developers need to spend time to get the application into the particular state where a component behaves like xyz. Same when reviewing the work on the components. That can be an absolute time sink. Here again, componentized views and the associated tooling help the team!
Once a good portion of the redesign is done, it can make sense to re-estimate the effort. Maybe it turns out, that a technical decision had to be done that either simplifies a lot of the rest of the work, or - unfortunately easier the case - there was hidden complexity in some area of the application which slowed down the progress a lot. Re-estimating can also be a chance to cut down on feature changes and re-align the scope of the redesign.
Conclusion​
We're rolling quite well with our approach to redesigns! The right tooling is key: for us, Figma, some kind of Storybook and a framework to build UI components just make sense. Another core part is to have as much discussion about the designs and their consistency done before any actual development takes place. Tackled the right way, a redesign can be loads of fun for all parties involved. From a developer's perspective it just feels great to be able to iron out bad decisions from the past, refactor and update things left and right and just leave every part of the codebase nicer as it was before. For the clients, it's absolutely satisfying to see their ideas about the new design come to life bit by bit like blossoms in spring. Everything is - at best - fresh, more thought through and generally better than before!
