<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp" -->

---
title: Dead Code Shouldn't Exist | daily.dev
description: Dominik, a Sentry design engineering team member, explains how his team removed 28,000 lines of dead code using the static analysis tool knip. Knip scans a...
canonical: https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Dead Code Shouldn't Exist | daily.dev
og:description: Dominik, a Sentry design engineering team member, explains how his team removed 28,000 lines of dead code using the static analysis tool knip. Knip scans a...
og:url: https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp
og:image: https://api.daily.dev/og/posts/siLRz0CFP.png
og:image:alt: Dead Code Shouldn't Exist
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Dead Code Shouldn't Exist

**[TkDodo](https://daily.dev/sources/tkdodo)** · 16 min read · 0 upvotes · 1 comments

## Summary

Dominik, a Sentry design engineering team member, explains how his team removed 28,000 lines of dead code using the static analysis tool knip. Knip scans a codebase for unused files, exports, and dependencies, running in about 15 seconds on Sentry's large codebase and using over 150 plugins to auto-detect frameworks. Its 'production mode' found over two-thirds of the dead code by excluding test-only usages. Dominik made over 50 PRs over a few weeks, removing almost 3% of the whole codebase, and knip now runs in CI to block new dead code from being merged.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://tkdodo.eu/blog/dead-code-shouldnt-exist>

## Questions this post answers

### What does knip's production mode do and why is it useful?

Production mode focuses knip's analysis only on code actually shipped, excluding test-only usages, so code that's technically used by a test but never called in production still gets flagged as dead. At Sentry, production mode accounted for over two-thirds of all dead code found, since regular mode could not catch code 'used' only by its own tests.

_daily.dev surfaces practical deep dives like this for teams deciding how to configure dead-code tooling._

### Why doesn't TypeScript flag an unused exported function the way it flags an unused local variable?

TypeScript's TS6133 'declared but never used' check only applies to local, unexported symbols because TypeScript does not perform cross-module usage analysis. Once a function has 'export' added in front of it, TypeScript assumes it might be used elsewhere and stops reporting it as unused, even if no other file actually imports it.

_Developers debugging stale TypeScript warnings can track tooling nuances like this on daily.dev._

### How fast is knip when scanning a large production codebase and how many plugins does it have?

Knip takes around 15 seconds to analyze the large Sentry codebase. It aims to be zero-config but often needs some configuration in serious codebases (80 lines of config at Sentry), and it ships with over 150 (183) plugins that auto-detect frameworks like Vitest and Astro to configure entry points and project files automatically.

_daily.dev helps developers evaluating static-analysis tools like knip keep tabs on real-world adoption details._

## Community discussion

Top comments from developers on daily.dev.

**@nark3d** · 0 upvotes

> Walk me through the 15 seconds, because the whole CI argument rests on it.  A scan that fast only stays fast if the config is kept tight as the codebase grows, and every plugin you switch on is another thing that can start flagging live code as dead.  Production mode finding two-thirds of it is hard to trust on its own, because test-only usage is where a symbol can look dead and be load-bearing, so the figure tells you where to look rather than that the code is safe to delete.  The false positives it turns up need triaging against what the code does before anything goes.

## Similar posts on daily.dev

- [Why Your Codebase Is Forcing Your AI to Underperform](https://daily.dev/posts/why-your-codebase-is-forcing-your-ai-to-underperform-qtppcy9od) · SD Times · 23 upvotes · 2 comments
- [Finding unused and ghost dependencies with Knip](https://daily.dev/posts/finding-unused-and-ghost-dependencies-with-knip-jqhpxviau) · LogRocket · 1 upvotes · 0 comments
- [AI-Assisted Unused & Dead Code Removal](https://daily.dev/posts/ai-assisted-unused-dead-code-removal-dmk06stqs) · Foojay.io · 0 upvotes · 0 comments
- [Stop Sending IDE-Catchable AI Code Errors to Review](https://daily.dev/posts/stop-sending-ide-catchable-ai-code-errors-to-review-lepmps4fa) · JetBrains · 0 upvotes · 0 comments

---

Tags: [#typescript](https://daily.dev/tags/typescript), [#cicd](https://daily.dev/tags/cicd)

[View this post on daily.dev](https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Dead Code Shouldn't Exist","url":"https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp"},"datePublished":"2026-10-20T18:13:14.721Z","dateModified":"2026-10-20T18:55:23.371Z","description":"Dominik, a Sentry design engineering team member, explains how his team removed 28,000 lines of dead code using the static analysis tool knip. Knip scans a...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/28549b19018a296f78e839f3da3a4a02?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/28549b19018a296f78e839f3da3a4a02?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"TkDodo","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"TkDodo","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1656338366/logos/tkdodo","url":"https://daily.dev/sources/tkdodo"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"typescript,cicd","timeRequired":"PT16M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"TkDodo","item":"https://daily.dev/sources/tkdodo"},{"@type":"ListItem","position":3,"name":"Dead Code Shouldn't Exist"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp","comment":[{"@type":"Comment","text":"Walk me through the 15 seconds, because the whole CI argument rests on it.  A scan that fast only stays fast if the config is kept tight as the codebase grows, and every plugin you switch on is another thing that can start flagging live code as dead.  Production mode finding two-thirds of it is hard to trust on its own, because test-only usage is where a symbol can look dead and be load-bearing, so the figure tells you where to look rather than that the code is safe to delete.  The false positives it turns up need triaging against what the code does before anything goes.","datePublished":"2026-10-22T10:23:44.511Z","url":"https://daily.dev/posts/siLRz0CFP#c-ivYzeh45G","author":{"@type":"Person","name":"Adam","url":"https://daily.dev/nark3d","image":"https://avatars.githubusercontent.com/u/2162621?v=4"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/dead-code-shouldn-t-exist-silrz0cfp#faq","mainEntity":[{"@type":"Question","name":"What does knip's production mode do and why is it useful?","acceptedAnswer":{"@type":"Answer","text":"Production mode focuses knip's analysis only on code actually shipped, excluding test-only usages, so code that's technically used by a test but never called in production still gets flagged as dead. At Sentry, production mode accounted for over two-thirds of all dead code found, since regular mode could not catch code 'used' only by its own tests. daily.dev surfaces practical deep dives like this for teams deciding how to configure dead-code tooling."}},{"@type":"Question","name":"Why doesn't TypeScript flag an unused exported function the way it flags an unused local variable?","acceptedAnswer":{"@type":"Answer","text":"TypeScript's TS6133 'declared but never used' check only applies to local, unexported symbols because TypeScript does not perform cross-module usage analysis. Once a function has 'export' added in front of it, TypeScript assumes it might be used elsewhere and stops reporting it as unused, even if no other file actually imports it. Developers debugging stale TypeScript warnings can track tooling nuances like this on daily.dev."}},{"@type":"Question","name":"How fast is knip when scanning a large production codebase and how many plugins does it have?","acceptedAnswer":{"@type":"Answer","text":"Knip takes around 15 seconds to analyze the large Sentry codebase. It aims to be zero-config but often needs some configuration in serious codebases (80 lines of config at Sentry), and it ships with over 150 (183) plugins that auto-detect frameworks like Vitest and Astro to configure entry points and project files automatically. daily.dev helps developers evaluating static-analysis tools like knip keep tabs on real-world adoption details."}}]}
```

