{'fraction_non_alphanumeric': 0.024963289280469897, 'fraction_numerical': 0.0015322735108216816, 'mean_word_length': 4.9946421737466515, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
UX Debt: Developers Borrow While Users Pay

Technical debt has become a well-known metaphor among software professionals, visualizing how shortcuts taken during development can accumulate and become a burden for software projects. In the traditional notion of technical debt, software developers borrow from the maintainability and extensibility of a software system, thus they are the ones paying the interest. User experience (UX) debt, on the other hand, focuses on shortcuts taken to speed up development at the expense of subpar usability, thus mainly borrowing from users' efficiency. With this article, we want to build awareness for this often-overlooked form of technical debt by outlining classes of UX debts that we observed in practice and by pointing to the lack of research and tool support targeting UX debt in general.


Introduction
Going into debt means trading additional costs in form of interest for immediacy, that is being able to spend money now that a borrower otherwise would not have. However, the borrower needs to be able to pay back debt and interest in addition to the other investments they intend to make. Otherwise, the accumulation of debt and interest leads to bankruptcy.
The term technical debt, coined by Ward Cunningham in 1992 [1], transfers this financial concept to software engineering, describing how shortcuts that are taken during the development of a software system accumulate and steer more and more development resources towards maintainability, that is paying back debt and interest. While taking shortcuts allows teams to ship features earlier and refactor later with experience from the feature's usage (i.e. making an investment that would otherwise not be possible), the team is going to pay interest in terms of reduced maintainability and extensibility until the refactoring has been done. While Cunningham's metaphor focuses on the developers implementing and maintaining a software system, user experience debt (or UX debt) focuses on its users. The term was introduced by Andrew J Wright in a blog post published in 2013 [3], where he defines UX debt as "the quality gap between the experience your digital product delivers now and the improved experience it could offer given the necessary time and resources". Wright further distinguishes between intentional UX debt, resulting from "project constraints and deliberate corner-cutting" and unintentional UX debt, resulting from "misconceptions about users' needs or users' comfort with technology".
Examples for intentional UX debt include trading new features for improvements to cumbersome user workflows because they already "work". Such prioritizations are a common part of software development. However, if choices jeopardize the user experience, they result in UX debt. This is also true for shortcuts where developers implement a feature in a way that saves them time but is not optimal in terms of usability. What those situations have in common is the intent to deliberately decide against a solution resulting in better UX. In other cases, UX debt is introduced unintentionally. This happens when developers lack understanding of users' needs and abilities, thus implementing features in a way not aligned with users' workflows. To counter this kind of UX debt, teams may utilize different evaluation methods to catalog existing usability issues. Those methods include observational studies, heuristic evaluations, or survey instruments such as SUS (system usability scale) and NPS (net promoter score). SUS is, for example, being used as a key performance indicator (KPI) at GitLab [6]. The integration of such UX research methods into agile process models is sometimes labeled as Lean UX [7].
While implementation-level technical debt has been researched in depth over the past decade, broader notions of the concept appear rare [2]. However, a major difference between technical debt and UX debt is that, while technical debt borrows from the maintainability and extensibility of a software system, thus mainly affecting developers, UX debt borrows from user efficiency and user frustration [8]. However, the two concepts are not isolated. An implementation shortcut affecting the software's performance, for example, can also add UX debt to the system.
In this article, we distill our experience in an industry project into three classes of UX debts and align them on a two-dimensional UX debt spectrum, capturing who pays the interest and how the debt can be detected (see Figure 1). With this article, we want to build awareness in the software engineering research community about the fact that not all forms of technical debt are implementation-level and thus tied to particular parts of the source code.
From Code-Level to User-Level Debt As motivated above, the two concepts technical debt and UX debt are related but different. To gain a better understanding of their relationship, we reflected on our experiences working on a team developing a real-world (closed source) web application in the domain of data analysis for voice processing systems. The project has, as of April 2021, almost two years of development time and around 70k lines of code. Despite the project being relatively young, we already observed quite a few instances of UX debt, as we outline in the following.

Implementation-level UX Debt
The first class of UX debt, which is the closest to the traditional notion of technical debt, contains implementation-level technical debts that affect usability, usually introduced intentionally. For example, we identified several instances of code duplication that led to inconsistencies in the user-facing behavior of our application. Over time, duplicated CSS classes caused the same UI components to look differently within the application as the copied code fragments diverged (e.g., at some point we had three copied-and-pasted table components that looked slightly different from each other). This inconsistency in the appearance of functionally equal components triggered questions by confused users.
Even worse are code duplicates in the application code that lead not only to diverging layouts between functionally similar components but to diverging functionality. For example, sorting and filtering are possible in one instance of the same table, but not in another. This behavior not only confuses users but also slows down their workflows because they have to double-check in all instances whether the required functionality is available. It is, however, the developers who pay the largest interest in this class of UX debt, because at some point the diverging layouts need to be consolidated in a time-intensive refactoring session (which is exactly what we did in our project).
Fortunately, tool support exists for detecting and avoiding UX debt instances from this class, because such UX issues are closely tied to related implementation issues. Exemplary static analysis tools, which can for example detect code clones in CSS classes, include Sonar, PMD, and the code inspections in modern IDEs such as IntelliJ.

Software-Architecture-related UX Debt
The second class of UX debts is still closely tied to the implementation level, i.e., the source code, but it is no longer easily measurable with existing tools. It highlights the tradeoff between "clean" software architecture and good usability, which surfaced several times in our project.
Modularization and reusable components are essential aspects of maintainable software architecture. One example where software architecture and usability competed with each other in our project was the design of certain UI container components. We designed containers to be as self-contained as possible with a clean event-based interface for inter-component communication. Those components were, from an architectural perspective, perfectly reusable and well-designed. However, the chosen architecture made it difficult for us to move basic UI components between the containers because they operated on encapsulated data. Thus, our clean architecture did not represent a meaningful grouping from the users' point of view. For example, a developer might place a button in one component because it fits there best from a technical perspective. However, for a more intuitive user experience, the button should be placed somewhere else, i.e., in another container. UX debt in this class can no longer be found by code analysis tools alone because they usually do not represent implementation-level technical debts. Hence, more elaborate measures such as user surveys or observational studies are required (see evaluation methods mentioned in the introduction). This kind of UX debt can be introduced intentionally or unintentionally, depending on whether the developer intentionally breaches common UI patterns or is not aware of users' actual needs. In any way, it is the users who pay the largest part of the interest in this situation.

Workflow-related UX Debt
While for the previous two classes, the UX debts were still closely tied to particular parts of the implementation (but not necessarily detectable using static analysis tools), the third class captures more abstract UX issues representing a (mis-)alignment of how users want to work and how the software guides them through their workflows. If the development team does not consider an in-depth knowledge of their users' desired workflows important, maybe even thinking they knew better how to design the workflows, this is likely to result in conflicts. Users are frustrated due to the lack of workflow alignment and developers are inclined to repeatedly point to available documentation in case users do not utilize the software as intended. While we did not observe such ignorant behavior in our team, from time to time a certain degree of misalignment and know-it-all mentality was indeed present.
Again, like for the previous class, a software system can be implemented without any implementation-level technical debt, and yet completely miss the point when it comes to supporting users' workflows. No tool support can fix such issues, the only mitigation is user research and frequent interactions with stakeholders. Depending on whether developers deliberately decide to ignore user feedback or are simply victims of their cognitive biases, this class represents international or unintentional UX debts. The interest is almost exclusively paid by the users and not the developers.
In our project, we, for instance, encountered the lack of user-facing communication of technical limitations as a problem: when uploading data, we expected a certain order of values, but the users were not aware of this. However, when the upload failed, the system showed technical error messages pointing to the format mismatch, resulting in frequent user feedback asking for clarifications regarding the failed import. Our takeaway from this situation was to revise our applications to map technical to domain-level error messages and at the same time document the intended behavior in-situ, i.e. in the user interface where the users trigger the import. By revising our error handling in this way, we were able to not only improve the user experience in the event of an error but also save ourselves a lot of follow-up questions.
Another mismatch between the users' workflows and our UI layout was the placement and grouping of tabs in our navigation header. For our users, it was not intuitive as it did not correspond to their usual work process. It did, however, correspond to our understanding of the user workflows. For users, the layout resulted in cumbersome navigation paths, or even worse, in some cases, they could not find the desired functionality and thought that it was not available, triggering feature requests for features that were already available.
To mitigate such issues, we utilized telemetry and log data, which is a relatively inexpensive way of understanding which features of the software are being used and which not (at least compared to conducting user studies). For example, if certain features are neglected, this can be an indication of UX debt, e.g., because the user does not find the corresponding functionalities within the UI or does not know how to use them. One can then specifically ask about those use cases when talking to users.
Speaking of if and how features are being used, we also want to mention user documentation and manuals. While these documents are supposed to help the user to get more acquainted with the UI, we could find two situations where this is not the case: documentation in the wrong place and documentation with the wrong scope. From our experience, very few users read a manual in advance; instead, they ask for help when a problem arises. In case documentation exists but is not linked in the potentially problematic parts of the UI, it does not help users much.
Even worse is outdated or bloated documentation. If a manual is referenced, but it only confuses the user even more due to the lack or overabundance of information, the frustration is immense. In summary, documentation can sometimes be a cause and not a mitigation of UX debt.

Conclusion
Based on our project experience, we derived three classes of UX debts: implementation-level UX debt, software-architecture-related UX debt, and workflow-related UX debt. We aligned those classes on two dimensions, namely whether it is primarily developers or users who pay the interest and whether the debt can rather be detected with tools or with user research.
Looking back at the past decade, a lot of effort went into communicating and providing tool support to raise developers' awareness of technical debt. While authors such as George Fairbanks [4] discussed broad and narrow definitions of technical debt, introducing the term ur-technical debt as the process where developers' "ideas diverge from [...] code", most publications still seem to target implementation-level technical debt from the developers' perspective. We argue for a broader perspective, taking users into account as well, especially because they are often the ones paying the interest of intentionally or unintentionally introduced UX debt. In the traditional notion of technical debt, however, it is primarily the developers who introduce and pay for technical debt.
As mentioned in the introduction, there is currently hardly any research on UX debt, and even the few articles we found refer to grey literature in the form of blog posts (e.g., [5]). There are, however, approaches that aim at broadening the scope of technical debt, for example, the concept of domain-level technical debt introduced by Störrle and Ciolkowski [2], which describes the misrepresentation of an application domain by a software system. With our notation of UX debt, we argue for a stronger user focus and want to build awareness for the fact that a software system can be implemented in a technically clean and sound manner and still slow users down because of workflow misalignment and other forms of UX debt, as outlined in this article.
Similar to implementation-level technical debt, the more UX debt is built up, the harder it is to consolidate the system (i.e., make it usable again). Additionally, with UX debt, resources are wasted because users are frustrated and work inefficiently. This might even lead to them losing trust in the software, and, as a last consequence, to a high churn rate if users switch to competitors. Thus, we want to encourage the software engineering research community to both empirically study UX debt in detail as well as work on potential tool support for detecting and quantifying it.