Bridging the Gap Between Product Priorities and Design Consistency

Lara Aigmüller

Posted in How We Work, Portfolio

In my last article, I wrote about how I helped building a solid foundation for the ongoing UI and UX work of a human machine interface (HMI). I created design tokens and designs for basic UI components and listed them together with important guidelines in a design system. Based on this groundwork, a small team of developers is now working together for four years, constantly improving the product while still keeping the UI consistent—at least most of the time 😉.

In this follow-up post, I’d like to share our approach and processes within the team and how we find the balance between introducing new features while maintaining and improving the existing ones.

Preparing new features

Our usual workflow looks as follows: When a new feature request comes in, I talk to our PM (product manager) and we identify whether we can use existing features, patterns, and components as a template or whether we need to do some UX and design work before the actual implementation.

As soon as the requirements are clear, and in case we have the UI components and patterns in place (which means documented in our design system), I create a work item in our backlog and describe everything a developer needs to get started. After the implementation work is done, I am usually assigned a “UI polishing 💅” task to have a final look and do the design fine-tuning. This sometimes includes adjustment of content hierarchy and spacing, fixing some accessibility issues, removing unnecessary markup, etc.

For some new features, I prepare pages or sections in advance, including custom components and special layout behavior that are not yet part of the design system. Where necessary, I add comments like “when the user clicks this button, the section below should update with the following data”… Before the implementation work is started, we schedule a short walkthrough to discuss the prepared code and what’s the desired behavior.

Design police on the case

When I am working on the codebase, I sometimes find issues that have nothing to do with my current task. Here are some examples:

  • content blocks where the layout and spacing look off
  • wrong usage of components (too many primary buttons, card nested in another card,…)
  • unclear wording and typos
  • insufficient color contrast
  • missing style overrides for UI library components we’ve never used before

When I do user interface maintenance work, I often need to do global searches and replacements which brings me to the darkest corners of the codebase 🕵️‍♀️. I touch code snippets that follow the same patterns but are unrelated feature-wise. During these expeditions, I occasionally stumble across code smells like:

  • unused variables and properties
  • custom code snippets and styles that could be replaced by meanwhile existing components or patterns
  • inconsistent usage of the same patterns
  • inline styles that could be replaced by an existing component
  • inconsistent wording for the same things

I create new work items for such issues as soon as they come up, explaining the problem and how to best fix it with the tools we already have. When it’s just a small inconsistency that can’t be found elsewhere in the codebase, I usually deal with it right away. In more complex situations that might require additional discussions with the team, I place the work item in the next sprint.

These cleanup tasks are unrelated to individual features, but they are the key to maintaining the product’s user interface. Whenever I add new items to our backlog, I tag them with design system workshop. Every few months, we schedule one- to two-hour sessions with all developers who write frontend code to review new additions to the design system and go over my “design police” notes 😅. These calls serve an educational purpose, allowing me to remind the team of what’s already available in our system and explain the “why” behind the design, ensuring we’re all learning as we build.

Collaboration with product management and the backend team

When feature additions or adjustments of existing ones get more complex, we discuss UI/UX design decisions together before they get implemented. In a collaborative meeting between product management, frontend and backend development we:

  • walk through the desired user journey
  • align the user experience between similar parts of the product (if possible)
  • discuss how we can use existing data structures and UI patterns to create a new feature
  • break the work down into independent work items, from an MVP (minimum viable product) to the final version

The great part here is the synergy between PMs, backend developers, and me as the solo frontend developer. When these different mindsets are combined, each one can give valuable insights, and together we find the best path forward.

Challenges as a one-person team

While there are some developers working on the frontend code, I’m the only dedicated frontend developer with a background in design and user experience. The great thing is: the team is uncomplicated, and I can usually make decisions without discussions about design details and personal preferences. The hard part is: Usually I can simply make decisions myself 🙈.

Without a frontend team or at least one fellow UX designer, it can be a real challenge to decide what’s “the best decision” for the product. Especially when designing and building for a niche market, it’s not easy to find similar applications I can use as inspiration. Therefore, I rely heavily on user feedback and combine this with general best practices from the UI/UX world.

On-site workshops

Because of the remote nature of my collaboration, I run the HMI locally on my computer without having all the complex machinery in the room. However, during my first visit at my client’s factory, I realized that even looking at the exact same user interface, it makes a huge difference seeing and operating this in the real world.

The weirdest bugs, the greatest question marks, and especially the best ideas always come up when we’re all standing in front of the machine and navigating through some real-life user journeys together with actual users.

The biggest wins for a user’s workflow are often tiny refinements to what’s already in place—nothing fancy, just a small tweak here and there. This reminds me that it’s not the most important thing to build one new feature after the other but also take the time to step back and polish the code we’ve already written.

Final thoughts and learnings

If there’s one takeaway from our process, it’s this: don’t underestimate the power of maintenance. Not only to avoid technical debt, but also to revise earlier decisions every now and then. Sometimes, cleaning up and doing small adjustments provides more value than adding another shiny new feature.

I often need to remind myself not to lose focus when finding a lot of tasks for the “design police maintenance to-do list” while working on a specific feature 🙈.

Communication of design system adjustments within the development team is important, but just presenting UI components and patterns without any context isn’t really effective. Therefore, I try to always show good and bad examples from the code recently written to combine theory and practice.

In many projects, finding time for maintenance is a common hurdle. Since the value isn’t always visible immediately, it’s often hard to put these work items on top of the backlog. The ideas and approaches outlined in this article might not work for everyone. It takes the right mindset and a sense of shared product ownership to make building and maintaining software a successful journey 💪.

Any thoughts or comments?

Say hello on Mastodon or contact us via email or contact form!