# What Is Technical Debt and How It Kills Side Projects

URL: https://whatshouldibuildnext.com/journal/what-is-technical-debt-side-projects
Type: blog
Locale: en
Published: 2026-09-12
Updated: 2026-09-13

---

> Solo builders accumulate technical debt faster than teams. Here is what it is, why it happens, and how to manage it before it blocks your next feature.

Understanding what is technical debt starts with this: it is the accumulated cost of every shortcut you take to ship faster. The term was coined by Ward Cunningham in 1992 as a metaphor for financial debt - borrow now, pay interest later. What makes it different from ordinary bad code is intent: a trade-off, conscious or not, between short-term speed and long-term maintainability.

If you have ever left a TODO comment in a file, hardcoded a value because you needed to ship by Friday, or copy-pasted a function instead of extracting a shared module, you have taken on technical debt. Most side projects are built on it, and most solo devs carry more than they realize.

## Why solo builders accumulate debt faster than teams

Teams have friction built in. Code review, architecture discussions, standards documents - these slow things down but they also slow debt accumulation. As a solo dev, you have no such friction. You make every trade-off yourself, in real time, at 11pm when you just want to see the thing work.

The result is a codebase that reflects every compromise you made under time pressure. That is not a character flaw. It is the structural reality of building alone. The problem is that debt compounds. A hardcoded API key is a one-hour fix. When you have twenty of them across six files because the pattern propagated, it is a full day of archaeology before you can even start fixing.

There is also a subtler form of accumulation: architectural debt from decisions made when the project was small that do not hold once the project actually gets traction. A flat JSON file as a database is fine at zero users. It is a problem at five hundred. The Taipei-based devs I know who run side projects in parallel with day jobs face this constantly: optimize for shipping speed, absorb the debt, renegotiate it later - if there is a later.

## The four types of technical debt that actually matter

Not all debt is equal. Here is a practical breakdown for side projects specifically.

**Code debt** is the most common. It covers shortcuts in the code itself: duplicated logic, functions that do too many things, variables named `temp2` that are still there six months later. This is the debt you feel every time you add a feature and spend thirty minutes just understanding what the existing code is doing before you can change anything.

**Documentation debt** is underestimated by solo builders because there is nobody else to confuse. Then you take three weeks off from the project, come back, and spend four hours figuring out why you built the API that particular way. You are now confused by your own choices from two months ago. The assumption that you will remember the context is almost always wrong.

**Security debt** accumulates when you skip input validation, leave admin routes unprotected during development and forget to lock them, or keep running a library that had a critical vulnerability patched six versions back. On a side project this usually feels low-risk right until you get real users - and then it is not theoretical anymore.

**Tooling debt** is the one builders least discuss. No deployment pipeline. Manual steps to release. A `.env` file that only exists on your laptop with no documented format. When something breaks in production, this is the debt that turns a thirty-minute fix into a three-hour recovery where you are also rebuilding the context for how anything gets deployed.

![Four categories of technical debt illustrated with colored sticky notes on a developer workspace](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/whatshouldibuildnext/2026-09/3191ee-inline1.webp)

## When taking on debt is the right call

Here is what the enterprise software literature gets wrong: it treats debt as uniformly bad. For a solo builder or indie hacker, some debt is the correct decision.

You have a side project you want to validate in two weeks. Writing a full test suite before you know whether the thing has any users is not engineering discipline - it is procrastination wearing a respectable name. Skipping tests at zero users and adding them once you have ten paying customers is a deliberate, reasonable trade-off. Ward Cunningham himself called this "prudent and deliberate" debt: you know you are taking it on, you understand the consequences, and you plan to pay it back.

The problem is when builders take on debt without realizing it, or take it on deliberately and never plan the payback. Debt without a plan is just entropy.

The rule that works in practice: debt is fine when it is bounded. One hardcoded config value is manageable. The same pattern applied across thirty different files is a codebase that nobody can work in, including you. Voila ce qui coince en pratique: most solo builders do not track their debt. It exists as a vague discomfort in the back of their head. That is the real problem - not the debt itself, but the lack of visibility into what it actually is and what it will cost to fix.

## How to see your debt before it starts costing you

The cheapest form of debt management is making debt visible. That does not require a complex process. A simple `DEBT.md` file in the root of your repo where you note the trade-offs as you make them takes thirty seconds per entry and saves hours of rediscovery later.

A typical entry might look like this:

`## [2026-08-03] Hardcoded DB connection string in api/users.ts
Why: Needed to ship the demo for Friday.
Cost: Environment-specific, breaks if anyone else tries to run this locally.
Fix: Move to env var with dotenv. Estimated 20 min.
Priority: High, before any collaborator joins.`That is all. The format does not matter. The act of writing it matters because it forces you to articulate the trade-off explicitly rather than letting it evaporate into the code where it will silently accumulate interest.

Static analysis tools do a different version of this automatically. Tools like SonarQube or CodeClimate scan your codebase and flag code smells, duplications, security hotspots, and complexity scores. They are more useful for catching debt you did not know you were creating - the inadvertent kind that comes from a pattern you did not notice yourself applying twelve times in a row.

CodeScene goes a step further by analyzing commit history to identify which files change together and which hotspots are getting touched repeatedly under time pressure. For a solo project, this kind of signal is actually more actionable than a static snapshot: it shows you where you have been repeatedly making compromises, not just where the code looks bad right now.

## Three ways to pay it down without stopping work

The mistake is treating debt repayment as a dedicated sprint that you schedule for next month and never get to. The correct approach is paying it down continuously in small amounts, embedded in your normal flow.

**The Boy Scout Rule applied to code**: leave the file you edit slightly better than you found it. Rename the confusing variable while you are already in there. Extract the duplicated logic into a function while you are touching it anyway. This costs five to fifteen minutes per session and compounds significantly over months of consistent work.

**Debt budgeting during active development**: if you are building a new feature, allocate 20% of the time to fixing debt in the adjacent code. Not debt you discover in a distant part of the codebase - that can wait. Debt that directly touches what you are building right now. This prevents the common pattern where new features make old debt worse because they are built on top of it.

**Priority triage by blast radius**: not all debt deserves equal attention. Debt in code you touch every week matters more than debt in a module you have not opened in four months. When deciding what to address, ask: if this breaks or needs to change, how many other things does it affect? High blast radius, high priority. Low blast radius debt that lives in a corner you rarely visit can stay there.

A three-to-one rule works for active development: for every three sessions spent building new features, spend one session paying down debt. This keeps the ratio from getting out of control without halting progress.

![Developer reviewing and refactoring code in a calm Bangkok home office setting](https://fdzlnqpwsaniezitwiuw.supabase.co/storage/v1/object/public/cms-media/whatshouldibuildnext/2026-09/b8ca4d-inline2.webp)

## What your current debt load is telling you

A six months into a project, the debt distribution in your codebase is a fairly accurate map of the decisions made under pressure. High debt in the authentication module means you were rushed when you built it. Massive duplication in your API layer means you were validating features quickly and did not stop to consolidate. Dense complexity in one particular file usually means that file became a dumping ground when the architecture was unclear.

This is genuinely useful information. It shows you which parts of your codebase were built with confidence and which were built with uncertainty. The parts built with uncertainty are also often the parts that turned out not to matter - features you validated quickly and then deprioritized. The debt you accumulated there may never need to be paid because those paths are going nowhere.

The parts that did turn out to matter - core user flows, data model, API contracts, authentication - those are where debt repayment actually pays off. You are not trying to write perfect code everywhere. You are trying to identify the load-bearing walls and keep them clean.

If your codebase has reached the point where adding any feature takes more time debugging existing behavior than writing new code, that is the signal. Not a signal to stop and rewrite everything - that is almost never the right call, and it is estimated to take twice as long as you think. It is a signal to dedicate the next three to four weeks to targeted debt reduction in the specific modules causing the slowdown.

## Should you rewrite it or refactor the messy parts?

This is the question solo builders face when debt starts feeling unmanageable. The answer is almost always to refactor, not to rewrite.

Rewrites are estimated to take half the time they actually take. They also lose the accumulated knowledge embedded in the existing code - the edge cases handled, the bugs fixed, the workarounds for third-party API quirks you discovered the hard way. You pay the original debt twice: once when you carried it, and again when you have to rediscover everything while rebuilding.

Refactoring works when it is targeted. Pick the module causing the most concrete pain - slowest to change, most bugs originating there, hardest to understand. Get a complete picture of what it does before changing anything. Add tests around the boundaries so you can refactor safely without breaking adjacent behavior. Make the changes incrementally over several sessions, not in one long heroic sprint that leaves things half-done if you run out of energy.

Three reasons to refactor, one reason not to: refactor when the debt is in a high-traffic area of the codebase, when you are about to build on top of it, or when it is causing actual bugs. Skip the refactor when the module is stable, rarely changes, and the debt is self-contained. Ce n'est pas une idee parfaite. C'est une idee faisable: the sustainable version of technical debt management is not zero debt. It is debt you understand, can articulate, and are actively deciding to carry or pay down. That clarity is the actual goal.

## FAQ

### What is technical debt in simple terms?

Technical debt is the future work created by taking shortcuts in code today. When you hardcode a value instead of making it configurable, copy-paste logic instead of extracting a shared function, or skip writing tests to ship faster, you are borrowing time now and will pay it back later, usually with interest in the form of slower feature development and more bugs.

### Is technical debt always bad?

No. Deliberate, bounded technical debt is a legitimate tool. Skipping tests while validating whether anyone wants your product is a reasonable trade-off. The problem is untracked debt, debt taken on without a plan to address it, or debt that has accumulated in your core user flows where it creates real slowdowns and bugs.

### What are the main types of technical debt?

The four types that matter most for side projects are code debt (duplications, complexity, poor naming), documentation debt (missing context that costs you hours of rediscovery), security debt (unpatched libraries, missing input validation, exposed routes), and tooling debt (manual deployment steps, missing CI, missing environment documentation).

### How do you measure technical debt in a codebase?

Static analysis tools like SonarQube and CodeClimate give you automated measurements of code complexity, duplication ratios, and security hotspots. For a more practical signal, pay attention to how long it takes to add a small feature: if a one-hour change requires two hours of understanding existing code first, your debt is already affecting velocity.

### How do solo devs manage technical debt without stopping feature work?

Three approaches that work in parallel with normal development: the Boy Scout Rule (leave each file slightly better than you found it), debt budgeting (allocate 20% of each feature session to adjacent debt), and triage by blast radius (prioritize debt in high-traffic modules over isolated corners of the codebase that rarely change).

### When should you rewrite instead of refactor?

Almost never. Rewrites take twice as long as estimated and lose the accumulated knowledge in existing code. The exception is a module that is actively causing production bugs, is impossible to test incrementally, and is small enough that a rewrite can be completed in under a week. In all other cases, targeted refactoring with tests around the boundaries is the better path.

### What tools help track technical debt in side projects?

SonarQube flags code smells, duplications, and security vulnerabilities. CodeClimate tracks maintainability scores over time. CodeScene analyzes commit patterns to identify hotspots under repeated pressure. For something simpler, a DEBT.md file in your repo root where you note trade-offs as you make them costs nothing and is surprisingly effective.