Tjeerd in 't Veen
— 7 min read
Receiving UI designs is quite common as an app developer. But that doesn’t mean we should just blindly get started. There is room to review main priorities with the designer, in order to find underlying issues and compare the design against pre-existing components amongst other things.
In this article you will find some tips and tricks to get more out of receiving designs and to strategize ways to deliver features more efficiently and effectively.
A designer will usually deliver neatly filled screens. They’ll pick a nice stock photo to fill images, all texts are nicely filled. It’s the perfect content for the perfect screen.
But, then real life comes into play. Real-life data hits different. It’s random, dirty, ugly, and all over the place. And that may not always fit the intended designs.
Once you let people upload their own pictures and add their own information, we can’t automatically guarantee that that once aesthetically pleasing screen won’t look as appealing in practice.
The avatar might be missing, or perhaps too low-res. The descriptions might be be wayyyy too long and half the fields may be empty. The unfortunate reality is that not every user takes great care in filling in their details.
If texts are missing, is that okay? In this case, we need to make sure to check with the designer that that’s a viable option. If not, there’s a strong chance that the UI might break with out-of-balance content.
As a rule of thumb: Always ask for a worst-case scenario design with poor content and see if the design still holds. Even with the worst content imaginable, the design should not break.
As a developer, thinking of a particular design isn’t necessarily your job. However, you are working on this project together and poor content is a truth we most certainly can’t avoid. So, it’s better to find any issues now preemptively versus facing potential complications down the line.
A surefire way to deliver less efficiently is to accept anything in a design as absolute, uncontested truth and implement it as if to aimlessly follow orders.
But not all ideas are weighted equally. A design is not set in stone; It’s a preliminary plan or proposal of what to make. Like all designs, it is subject to iteration. With that in mind, you’ll be the one making it come to life — albeit behind a pane of glass.
When receiving a design, don’t assume all components are equal in terms of priority and magnitude.
It may sound counterintuitive, but finding ways to not build features can ultimately lead to better comes for everyone, including the designer. Getting a designer to agree to deprioritize features, will allow you to ship more quickly. This also subsequently benefits the designer as they will be able to obtain more meaningful insights and, as a result, present their designs to customers and other stakeholders within a shorter time frame.
A benefit from shipping fewer features (within reason) is that we are able to acquire knowledge earlier on.
Taking a proactive approach to learning at the early stages of the development cycle allows us to change course more quickly as needed. It also helps us avoid the potential risk or throwing away valuable time building features that customers didn’t actually want in the first place.
The point being, when receiving designs, it’s the perfect moment to stop and think mindfully and critically about what’s really important. Revalidating priorities together with the designer mutually benefits everyone in the long run.
After receiving designs, be sure to run the components by other client engineers. In practice, this means checking what they already know exists in order to avoid reinventing the wheel.
It may seem completely obvious, but yet doesn’t always happen in reality: A single question in a Slack channel like “Does something like this already exist?” can save you days of unnecessary work.
Conversely, it might be that there already is a component that we could potentially use, but it may be just slightly different from what the designer happens to give us. This is a telltale sign that there is some plausible misalignment between the client libraries and designs. If so, this might be a good time to try to persuade the designer to use what we have.
If there is a strong reason to make an adjustment to the existing component, or a new component altogether, then so be it. However, a little pushback for the purpose of shipping more quickly can be a tremendous timesaver yielding other indirect benefits. These include, but are not limited to, avoiding having to maintain more duplicate components, which is a hidden time sink that compromises producivity.
These are a repertoire of general questions you can ask which effectively apply to most UI-based projects.
Try to think of things that the designer hasn’t thought of yet. This helps us find requirements that may have been missed.
Some examples are:
After you’ve exhausted your general UI questions, you can get even more information by trying to find edge-cases that might break the screen.
Try to come up with ways the feature might work different than intended. Like the general UI questions, asking these questions will help us find potential problems early on.
These are very specific to your feature. One example would be: “What happens if a user submits something, but before the network call finishes, the user moves the app to the background and the submit-call fails?” This scenario could perhaps be a little message or a so-called “toast”. But now that the app is moved to the background, we should then ask if that would that be a silent failure, or perhaps a notifcation or something else entirely?
In some cases it might be that you’re tempted to not want to implement specific parts of a design. For instance, the designer might have a custom navigation bar that’s quite difficult to get just right, and it may be even harder to maintain.
It can be easy to mistakenly fall into the trap of thinking in binary, black and white terms such as “worth implementing” vs “not worth implementing”.
The issue might be that you’re great at devising arguments which demonstrate why a custom navigation bar is a bad idea. Despite the fact that, on paper, the points you’ve made appear objectively correct — Making a custom navigation bar is almost always a maintenance headache — To others, you may be unwittingly labeled as a “rigid” developer.
However, don’t jump the gun and reactively say “No.” Instead, shift the conversation towards focusing on priorities and timelines. Instead of saying, “I wouldn’t do that”, you could alternatively say: “This will be x weeks more work for us to do.”
From that point on, as a team you can then decide if the custom navigation bar is worth all that extra time because maybe it is worth it to the company to have a custom styling to maintain a central theme in the application.
The point is to quantify the consequences and make decisions and alternatives more tangible. This helps people grasp the scope of the problem.
And who knows, maybe making an implementation is not as bad as you think and you can deliver it more quickly after doing some research.
I hope these tips are able to help you improve a feature next time you receive designs. With the risk of perhaps stating the obvious: The designer is your ally. I hope that by working in conjuction strategically, you will be able to make your apps even better.
It may be a bit awkward to “go against” the design(er), but it’s much better to find issues sooner than later before spending weeks implementing everything.
Want to learn more?
Coming in 2023!
Subscribe to get updates to the upcoming book:
Mobile System Design
Learn about passing system design interviews, making features faster, testing apps more thoroughly, avoiding overengineering, dependency injection without fancy frameworks, writing strong components, and more!
Suited for feature engineers of all mobile platforms.
Tjeerd in 't Veen has a background in product development inside startups, agencies, and enterprises, for companies such as Twitter, ING, and many others.