Junk (junk code) — is code en afhankelijkheden die geen nut hebben voor het project, maar de omvang, bouwtijd en cognitieve belasting van het team vergroten. In tegenstelling tot dode code die nooit wordt uitgevoerd, kan junk wel werken, maar doet dit inefficiënt of overbodig: dubbele bibliotheken, ongebruikte imports, uitgecommentarieerde blokken, verouderde polyfills en decoratieve abstracties. Volgens het rapport CodeScene Code Health Report (2025) wordt gemiddeld 15 procent van de afhankelijkheden in mobiele projecten niet direct gebruikt, maar trekken ze alleen transitieve pakketten mee. Junk-code is het „extra gewicht” van het project: het maakt de codebase dikker, maar niet sterker. Regelmatige audit van afhankelijkheden en het verwijderen van overbodige abstracties verbeteren direct de bouwsnelheid en codekwaliteit.
Belangrijkste punten
Junk (junk code) — een verzamelterm voor code, configuraties en afhankelijkheden die in het project aanwezig zijn maar geen functionele waarde hebben. Junk is niet per definitie kapot of ongebruikt — het probleem is dat de aanwezigheid ervan de projectmetrieken verslechtert zonder adequate rechtvaardiging.
Junk wordt in vier categorieën verdeeld. De eerste — overbodige afhankelijkheden: bibliotheken toegevoegd voor één functie die met standaardmiddelen kan worden geïmplementeerd. De tweede — dode last: uitgecommentarieerde blokken, TODO's zonder tickets, lege methoden en stub-klassen. De derde — dubbele oplossingen: twee bibliotheken die hetzelfde doen (bijvoorbeeld Gson en Kotlin Serialization in één project). De vierde — over-engineering: architectuurlagen die niet worden gebruikt maar „voor de toekomst” worden onderhouden.
Volgens onderzoek van Stripe Engineering Productivity (2025) verkort het verwijderen van 10 procent junk uit een typisch project de volledige bouwtijd met gemiddeld 22 procent. Reden: elke overbodige afhankelijkheid vergroot de bouwgraaf, elke lege abstractie kost tijd om te begrijpen, elk uitgecommentarieerd blok leidt af.
De grootste moeilijkheid in de strijd tegen junk is het ontbreken van onmiddellijke gevolgen. Een project met junk-code compileert en werkt. Problemen stapelen zich geleidelijk op: de bouw vertraagt, het aantal transitieve afhankelijkheden groeit en na een jaar duurt het toevoegen van een nieuwe functie twee keer zo lang als het zou moeten.
Junk-afhankelijkheden — zijn bibliotheken en pakketten die aan het project zijn gekoppeld maar niet direct in de code worden gebruikt, of slechts in één functie die eenvoudiger met standaard API's kan worden geïmplementeerd.
Typische voorbeelden: een bibliotheek voor JSON-werk wanneer het project al Kotlin Serialization gebruikt (twee parsers — dat is junk); de bibliotheek Apache Commons Lang voor één methode StringUtils.isEmpty, die wordt vervangen door de Kotlin-extensie isNullOrBlank; een DI-bibliotheek die in één van de tien modules wordt gebruikt, terwijl de rest afhankelijkheden handmatig via de constructor krijgt.
Elke overbodige afhankelijkheid is niet alleen extra code in de binary. Het is ook een vergroting van het aanvalsoppervlak voor kwetsbaarheden: volgens GitHub Advisory Database (2025) is 40 procent van de kritieke CVE's in mobiele projecten afkomstig van transitieve afhankelijkheden die ontwikkelaars niet controleren. Hoe minder afhankelijkheden — hoe kleiner het aanvalsoppervlak.
// Bekijk Gradle-afhankelijkheidsboom
./gradlew app:dependencies --configuration releaseRuntimeClasspath
// Vind ongebruikte afhankelijkheden (Gradle-plugin)
plugins {
id "com.autonomousapps.dependency-analysis" version "2.0.0"
}
// Genereer rapport ongebruikte bibliotheken
./gradlew buildHealth
Gebruik voor iOS het commando swift package show-dependencies, dat de volledige afhankelijkheidsboom toont. De tool Xcode Build Timeline laat zien hoeveel tijd elke bibliotheek aan de bouw toevoegt. Als een bibliotheek 30 procent van de compilatietijd inneemt maar slechts op één scherm wordt gebruikt — is het een kandidaat voor verwijdering of vervanging.
Gebruik voor Node.js (React Native) depcheck — een tool die ongebruikte afhankelijkheden in package.json vindt, en npm-check, die ook verouderde versies toont. Voer de regel in: elke nieuwe afhankelijkheid moet door code review met de rechtvaardiging „waarom niet met standaardmiddelen”.
Dode imports — de meest voorkomende vorm van junk. Ze beïnvloeden de runtime niet, maar verhogen de compilatietijd: de compiler verwerkt elke import, zelfs als deze niet wordt gebruikt. In grote projecten verkort het verwijderen van ongebruikte imports de bouwtijd met 5–10 procent.
Moderne IDE's markeren ongebruikte imports automatisch in het grijs. Stel automatisch opschonen in bij het opslaan van bestanden: in IntelliJ IDEA — Optimize Imports on the fly, in Xcode — Editor > Remove Unused Imports. Voeg in CI een controle toe: de linter moet commits met ongebruikte imports blokkeren.
Uitgecommentarieerde code — een andere vorm van junk. Ontwikkelaars commentariëren blokken om functionaliteit niet te verliezen tijdens refactoring. Maar git bewaart de volledige wijzigingsgeschiedenis: elke verwijderde code kan worden hersteld met één commando git revert of git log -S
Regel: in de repository is geen uitgecommentarieerde code. Als code niet nodig is — verwijder deze dan definitief. Als code nodig is maar tijdelijk is uitgeschakeld — gebruik dan een feature toggle met ticket en deadline. Opmerkingen zoals // TODO: remove after migration — laat ze niet zonder deadline. Zet een datum en stel een herinnering in de agenda in.
Over-engineering — het creëren van architectuurlagen die huidige problemen niet oplossen maar wel onderhoud vereisen. Dit is een van de lastigste vormen van junk omdat de code formeel „correct” is: hij voldoet aan SOLID, is getest en past in de architectuur. Het probleem is dat hij niet nodig is.
Het klassieke voorbeeld — een abstracte UseCase-klasse met één invoke-methode die alleen de repository aanroept. Als UseCase geen logica toevoegt (caching, retry, transformatie), maar alleen de aanroep doorgeeft — is het een overbodige entiteit. Het vergroot de navigatie door het project: de ontwikkelaar opent UseCase, ziet invoke → repository — en sluit het. Tijd verspild, voordeel nul.
Een ander voorbeeld — overmatige parametrisatie. Een generieke interface met zes typeparameters, gebruikt op één plaats. Elke typeparameter is cognitieve belasting: bij het lezen van de code moet je zes typen onthouden, terwijl er maar twee daadwerkelijk worden gebruikt. Als de abstractie niet wordt hergebruikt — is hij overbodig.
Het afsnijcriterium: als een abstractie niet in drie verschillende contexten wordt hergebruikt — verwijder hem dan. Een abstractie is gerechtvaardigd wanneer hij daadwerkelijk een duplicatieprobleem oplost, niet wanneer hij hypothetische toekomstscenario's voorspelt. YAGNI (You Ain't Gonna Need It) — het beste principe om over-engineering te voorkomen.
Audit van junk vereist een combinatie van statische analyse, afhankelijkheidsanalyse en handmatige controle. Het volledig automatiseren van het zoeken naar overbodige abstracties is niet mogelijk, maar technische junk (dode imports, ongebruikte bibliotheken, uitgecommentarieerde code) wordt met tools gevonden.
| Categorie | Tool | Wat het controleert |
|---|---|---|
| Ongebruikte afhankelijkheden | dependency-analysis (Gradle) | Bibliotheken die niet in de code worden gebruikt |
| Ongebruikte afhankelijkheden | depcheck (Node.js) | Pakketten uit package.json zonder imports |
| Ongebruikte afhankelijkheden | swift package --show-dependencies | SwiftPM-afhankelijkheidsboom |
| Dode imports | IDE (Optimize Imports) | Ongebruikte import-expressies |
| Uitgecommentarieerde code | grep -r "//" / rg "^\s*//" | Commentaarblokken met code |
| Lege methoden/klassen | SonarQube / CodeClimate | Methoden zonder body of met lege body |
| Dubbele bibliotheken | Gradle lint (duplicate classes) | Klassenconflicten uit verschillende bibliotheken |
Voor een volledige audit voert u buildHealth (Android) of depcheck (Node.js) één keer per sprint uit. Maak een dashboard in CI dat de dynamiek van het aantal afhankelijkheden per sprint toont. Als het aantal stijgt maar de functionaliteit niet evenredig groeit — hoopt het team junk op.
Let op duplicate classes — een fout wanneer twee bibliotheken dezelfde klasse bevatten. Dit is niet alleen junk, maar ook een directe bron van bouwconflicten. In Gradle worden zulke conflicten opgelost via force of exclude, maar elke dergelijke oplossing is een signaal dat een van de bibliotheken overbodig is.
Junk opruimen is geen eenmalige actie, maar een regelmatig proces. Zonder regels keert junk binnen twee tot drie sprints terug. De beste praktijk — reserveer 10–15 procent van de capaciteit van elke sprint voor technisch opschonen, inclusief junk-audit.
Het proces bestaat uit vier stappen. De eerste — diagnose: tools uitvoeren, rapport verkrijgen, prioriteren. Hoge prioriteit — afhankelijkheden met bekende CVE's en dubbele bibliotheken. Medium — dode imports en uitgecommentarieerde code. Laag — overbodige abstracties (vereisen handmatige analyse).
De tweede — opschonen: dode afhankelijkheden verwijderen, dubbele bibliotheken vervangen door één, uitgecommentarieerde code verwijderen. Elke wijziging wordt in een aparte commit gedaan met een duidelijke message: „remove unused dependency: gson (replaced by kotlinx.serialization)”, „delete commented code in LoginViewModel”.
De derde — verificatie: project bouwen, tests draaien, UI controleren. Als tests na het verwijderen van een afhankelijkheid slagen — was de afhankelijkheid echt niet nodig. Als tests falen — betekent dat er ergens een verborgen referentie is achtergebleven die de statische analysator niet heeft gedetecteerd.
De vierde — preventie: de code review-checklist bijwerken, de regel „geen nieuwe afhankelijkheid zonder rechtvaardiging” toevoegen aan de Definition of Done, automatische controle in CI instellen. Preventie is de enige manier om hernieuwde opeenhoping van junk te voorkomen.
Veelgestelde vragen
Technische schuld is een bewuste compromisbeslissing (snel, maar van lage kwaliteit) die gepland staat om te worden opgelost. Junk is geen bewuste beslissing, maar opgehoopt afval: overbodige afhankelijkheden, uitgecommentarieerde code, lege abstracties die niemand heeft gepland en niemand wil onderhouden.
Het optimale ritme — elke sprint 10 procent van de tijd besteden aan technisch opschonen. Dit houdt junk onder controle zonder kritische massa op te hopen. Als er veel junk in het project is — begin dan met één grote opschoon-sprint en ga daarna over op een regelmatig ritme.
Meet en toon de cijfers: meet de bouwtijd voor en na het verwijderen van 3–5 overbodige afhankelijkheden. Een besparing van 15–30 seconden per bouw keer het aantal bouwen per dag geeft uren bespaarde teamtijd. Cijfers overtuigen beter dan abstracte oproepen tot netheid.
Ja, vooral als de afhankelijkheid een CVE heeft. Zelfs als het project stabiel is, is een kwetsbaarheid in een transitieve afhankelijkheid een beveiligingsrisico. Bovendien kan bij een SDK- of taalupdate de oude afhankelijkheid incompatibel worden en het verwijderen ervan vóór de upgrade bespaart uren migratietijd.
Elke TODO zonder ticket is junk. Stel de regel in: TODO wordt alleen geschreven in het formaat // TODO(PROJECT-1234): fix met koppeling aan een taak in de tracker. Controleer regelmatig TODO's en sluit degenen die hun actualiteit hebben verloren. Verwijder verlopen TODO's — als het probleem niet binnen een half jaar is opgedoken, is het niet kritiek.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook