Junk in Development — What It Is, Why Junk Code Is Harmful, and How to Remove It

Author: IT Sectr Published: 2026-07-27 Reading time: 10 min

Junk code refers to code and dependencies that bring no benefit to a project but increase its size, build time, and cognitive load on the team. Unlike dead code that never executes, junk may work but does so inefficiently or redundantly: duplicate libraries, unused imports, commented-out blocks, outdated polyfills, and decorative abstractions. According to the CodeScene Code Health Report (2025), on average 15 percent of dependencies in mobile projects are not used directly and only pull transitive packages. Junk code is the “extra weight” of a project: it makes the codebase thicker but not stronger. Regular dependency audits and removal of redundant abstractions directly improve build speed and code quality.

Key Takeaways

  • Junk is useless or redundant code and dependencies that increase project size without benefit.
  • Types of junk: dead dependencies, duplicate libraries, commented-out code, empty abstractions.
  • Junk dependencies increase the attack surface area and slow down the CI pipeline.
  • Audit tools: Gradle dependencies (Android), SwiftPM audit (iOS), depcheck (Node.js).
  • Regular junk cleanup is as much a part of project maintenance as writing new code.

What Is Junk Code?

Junk (junk code) is a collective term for code, configurations, and dependencies that exist in a project but provide no functional value. Junk is not necessarily broken or unused — the problem is that its presence worsens project metrics without adequate justification.

Junk falls into four categories. First — redundant dependencies: libraries added for a single feature that could be implemented with standard tools. Second — dead weight: commented-out blocks, TODO without tickets, empty methods, and stub classes. Third — duplicate solutions: two libraries doing the same thing (for example, Gson and Kotlin Serialization in one project). Fourth — over-engineering: architectural layers that are not used but maintained “just in case.”

According to Stripe Engineering Productivity (2025) research, removing 10 percent of junk from a typical project reduces full build time by an average of 22 percent. The reason: every extra dependency increases the build graph, every empty abstraction takes time to understand, every commented-out block distracts attention.

The main difficulty in fighting junk is the lack of immediate consequences. A project with junk code compiles and runs. Problems accumulate gradually: builds slow down, the number of transitive dependencies grows, and after a year adding a new feature takes twice as long as it should.

Junk Dependencies and How to Identify Them

Junk dependencies are libraries and packages added to a project that are not used directly in the code, or are used only for a single feature that would be simpler to implement with standard APIs.

Typical examples: a library for JSON processing when the project already uses Kotlin Serialization (two parsers is junk); the Apache Commons Lang library for a single StringUtils.isEmpty call that could be replaced with a Kotlin extension isNullOrBlank; a DI library used in one module out of ten, while the others receive dependencies via constructor manually.

Every extra dependency is not just extra code in the binary. It increases the surface area for vulnerabilities: according to the GitHub Advisory Database (2025), 40 percent of critical CVEs in mobile projects come from transitive dependencies that developers do not control. The fewer dependencies, the smaller the attack surface.

Android Project Dependency Analysis

groovy
// View Gradle dependency tree
./gradlew app:dependencies --configuration releaseRuntimeClasspath

// Find unused dependencies (Gradle plugin)
plugins {
    id "com.autonomousapps.dependency-analysis" version "2.0.0"
}

// Generate unused library report
./gradlew buildHealth

For iOS, use the swift package show-dependencies command, which outputs the full dependency tree. The Xcode Build Timeline tool shows how much build time each library adds. If a library takes 30 percent of compilation time but is used on a single screen, it is a candidate for removal or replacement.

For Node.js (React Native), use depcheck — a utility that finds unused dependencies in package.json, and npm-check, which additionally shows outdated versions. Introduce a rule: every new dependency must pass code review with a justification of “why standard tools cannot be used.”

Dead Imports and Commented-Out Code

Dead imports are the most common type of junk. They do not affect runtime but increase compilation time: the compiler processes every import, even unused ones. In large projects, removing unused imports reduces build time by 5–10 percent.

Modern IDEs automatically highlight unused imports in gray. Set up auto-cleanup on file save: in IntelliJ IDEA — Optimize Imports on the fly, in Xcode — Editor > Remove Unused Imports. Add a CI check: the linter should block commits with unused imports.

Commented-out code is another type of junk. Developers comment out blocks to “not lose” functionality during refactoring. However, git stores the full history of changes: any removed code can be restored with a single git revert or git log -S command. Commented-out code in master is disrespectful to the team: every developer spends mental energy on the question “why is this commented out and when should it be uncommented?”

The rule: there is no commented-out code in the repository. If code is not needed, delete it permanently. If code is needed but temporarily disabled, use a feature toggle with a ticket and an expiration date. Comments like // TODO: remove after migration — do not leave without a deadline. Set a date and remind yourself with a calendar.

Redundant Abstractions and Over-Engineering

Over-engineering is creating architectural layers that do not solve current problems but require maintenance. This is one of the most insidious types of junk because formally the code is “correct”: it follows SOLID, is covered by tests, and conforms to the architecture. The problem is that it is unnecessary.

A classic example is an abstract UseCase class with a single invoke method that simply calls a repository. If the UseCase adds no logic (caching, retry, transformation) and only passes the call through, it is an extra entity. It increases navigation in the project: a developer opens the UseCase, sees invoke → repository, and closes it. Time wasted, zero benefit.

Another example is excessive parameterization. A generic interface with six type parameters used in only one place. Each type parameter adds cognitive load: when reading the code, you have to keep six types in mind while only two are actually used. If an abstraction is not reused, it is redundant.

The cutoff criterion: if an abstraction is not reused in three different contexts, remove it. An abstraction is justified when it actually solves a duplication problem, not when it predicts hypothetical future scenarios. YAGNI (You Ain’t Gonna Need It) is the best principle for preventing over-engineering.

Junk Audit Tools

Junk auditing requires a combination of static analysis, dependency analysis, and manual review. It is impossible to fully automate the detection of redundant abstractions, but technical junk (dead imports, unused libraries, commented-out code) can be found with tools.

CategoryToolWhat It Checks
Unused dependenciesdependency-analysis (Gradle)Libraries not used in code
Unused dependenciesdepcheck (Node.js)Packages from package.json without imports
Unused dependenciesswift package --show-dependenciesSwiftPM dependency tree
Dead importsIDE (Optimize Imports)Unused import statements
Commented-out codegrep -r “//” / rg “^\s*//”Comment blocks with code
Empty methods/classesSonarQube / CodeClimateMethods with empty or no body
Duplicate librariesGradle lint (duplicate classes)Class conflicts from different libraries

For a full audit, run buildHealth (Android) or depcheck (Node.js) once per sprint. Create a CI dashboard showing the dependency count trend across sprints. If the count grows but functionality does not grow proportionally, the team is accumulating junk.

Pay attention to duplicate classes — an error that occurs when two libraries contain the same class. This is not only junk but also a direct source of build conflicts. In Gradle, such conflicts are resolved via force or exclude, but each such resolution is a signal that one of the libraries is unnecessary.

Regular Project Cleanup Process

Junk cleanup is not a one-time action but a regular process. Without a procedure, junk returns within two to three sprints. The best practice is to allocate 10–15 percent of each sprint’s capacity to technical cleanup, including junk auditing.

The process consists of four steps. First — diagnostics: run tools, get a report, prioritize. High priority: dependencies with known CVEs and duplicate libraries. Medium priority: dead imports and commented-out code. Low priority: redundant abstractions (require manual analysis).

Second — cleanup: remove dead dependencies, replace duplicate libraries with one, delete commented-out code. Each change should be a separate commit with a clear message: “remove unused dependency: gson (replaced by kotlinx.serialization)”, “delete commented code in LoginViewModel.”

Third — verification: build the project, run tests, check the UI. If tests pass after removing a dependency, the dependency was indeed unnecessary. If tests fail, there is a hidden reference somewhere that the static analyzer did not detect.

Fourth — prevention: update the code review checklist, add a rule “no new dependency without justification” to the Definition of Done, set up automatic checks in CI. Prevention is the only way to prevent junk from accumulating again.

Frequently Asked Questions

How is junk different from technical debt?

Technical debt is a conscious compromise (fast but low quality) that is planned to be fixed. Junk is not a conscious decision but accumulated garbage: extra dependencies, commented-out code, empty abstractions that no one planned or wants to maintain.

How often should junk be cleaned?

The optimal rhythm is to allocate 10 percent of each sprint to technical cleanup. This keeps junk under control without accumulating critical mass. If a project has a lot of junk, start with one big cleanup sprint and then switch to a regular rhythm.

How to convince the team to remove junk?

Measure and show the numbers: measure build time before and after removing 3–5 extra dependencies. A reduction of 15–30 seconds per build multiplied by the number of builds per day gives hours of saved team time. Numbers convince better than abstract calls for cleanliness.

Should junk be removed from dependencies if the project is stable?

Yes, especially if the dependency has a CVE. Even if the project is stable, a vulnerability in a transitive dependency is a security risk. Moreover, when updating an SDK or language, an old dependency may become incompatible, and removing it before the upgrade will save hours of migration time.

What to do with TODO in code?

Every TODO without a ticket is junk. Set a rule: TODO is written only in the format // TODO(PROJECT-1234): fix linked to a task in the tracker. Regularly check TODOs and close those that have lost relevance. Remove expired TODOs — if the problem did not surface in six months, it is not critical.

Summary

  • Junk is useless code, unused dependencies, and redundant abstractions that increase the project without benefit.
  • Four categories: redundant dependencies, dead weight, duplicate libraries, and over-engineering.
  • Every extra dependency increases build time, attack surface, and cognitive load.
  • Audit tools: dependency-analysis (Gradle), depcheck (Node.js), SonarQube, grep for commented-out code.
  • Regular cleanup: 10–15 percent of sprint on technical work, dependency audit once per sprint.
  • Prevention: code review with dependency checks, YAGNI in design, auto-cleanup of imports.
  • Rule: no new dependency without justification, no TODO without a ticket, no line of commented-out code in master.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also