duhan
Blog

Technical Debt

Software projects get complex over time. No matter how well the code is initially written, new features are added, business requirements change, and technologies become outdated. This inevitable change naturally leads to technical debt.

Technical debt is not just about writing bad code; on the contrary, every software project accumulates debt at some point during its existence. It is impossible to prevent it completely, but it can be managed. Sometimes, technical debt is a conscious decision to keep a project moving forward. The important thing is to know when you are in debt and to keep it under control.

In today’s world, the average frontend team cannot advance a project without taking on technical debt. Software development requires working with constantly changing business requirements and limited time. There are several reasons for this:

  • Time pressure is a reality in software development. For most projects, “on time” is the top priority, which sometimes leads to a “let’s make it work for now” approach.
  • Business logic can be inherently complex. Some requirements inevitably increase code complexity. For example, consider a rule in an e-commerce platform like “Earn points when an order is placed, but subtract points if it is returned—unless it was purchased with a promo code.” Implementing such rules can be challenging.
  • As the codebase grows, readability decreases. Code growth is natural, but if not maintained properly, it becomes harder to understand. New developers, unfamiliar with the existing structure, often choose to patch rather than refactor.
  • Technology choices can create long-term challenges. A framework or library that seems like a great choice today may become a liability in the future. For example, AngularJS was once widely adopted, but when Google dropped support, teams worldwide faced massive technical debt as they had to migrate to Angular or entirely different frameworks. Developers don’t always have control over these factors. However, technology selection is a conscious decision that can turn into one of the biggest sources of technical debt. A choice that seems reasonable today can become an obstacle in the future.

Since avoiding technical debt completely is unrealistic, one of the most effective ways to minimize it is making informed technology choices. The frameworks and libraries we pick today can either reduce our future workload or create unnecessary maintenance problems.


Right Tool for the Right Job in Frontend Development

Choosing a framework with a small community or limited adoption carries significant risk. The right tool does not mean the most technically advanced or best-performing tool. It means the tool that ensures the long-term sustainability of the project.

The Impact of Rendering Choices

Selecting the wrong rendering approach for a project can lead to long-term technical debt. Consider these scenarios:

  • If you build a marketing website as an SPA, you will struggle with SEO.
  • If you build an e-commerce platform as a pure SPA, you might face performance and compatibility issues with third-party tools.
  • Even for a simple blog, using an SPA can introduce unnecessary complexity.

Rendering strategy affects performance, SEO, and user experience. Frontend developers must ensure that their applications are optimized for their intended use case.

Why React Remains the Most Practical Choice

Once the rendering technique is determined, if the project requires an SPA, React is usually the most suitable option. While other frameworks might offer certain advantages, React provides:

  • A massive ecosystem that ensures long-term viability.
  • A large developer pool, reducing the risk of hiring difficulties.
  • Extensive documentation and community support for solving edge cases.

In recent years, common concerns about React have been performance, bundle size, and unnecessary re-renders. However, in most real-world scenarios, these issues are manageable:

  • Performance bottlenecks can be addressed with React 19’s new compiler.
  • Bundle size can be reduced with proper tree-shaking and code-splitting.
  • Rerenders can be minimized with correct state management. Instead of keeping state in a parent component and passing it down as props (which causes unnecessary renders), moving state to a custom hook and using it directly in child components prevents excessive updates.

On the other hand React is not perfect. SSR and hydration introduce additional complexity, and performance optimizations often require manual intervention. However, its flexibility and stability make it the safest choice for most frontend teams.


Understanding the Trade-offs in Framework Selection

Let’s say you, as a developer, are responsible for choosing a framework and you opt for Solid.js instead of React. On paper, Solid.js outperforms React in many aspects, particularly in performance and fine-grained reactivity. However, the decision comes with long-term risks:

  • Solid.js has a smaller ecosystem, which could make hiring developers difficult.
  • Community support is limited, meaning if you run into an edge case, you might be the first person to ever encounter it. In contrast, with React, it is statistically more likely that someone has already solved your problem.

Choosing the right technology is not just about immediate performance gains—it affects the entire lifecycle of the project. Constantly jumping from technology to technology is a very good way to learn, but it has no place in a sustainable project.