0
# Issue Detection & Management
1
2
Comprehensive issue detection system categorizing different types of unused code and dependency problems. Knip identifies 14 different issue types across files, dependencies, and code symbols.
3
4
## Capabilities
5
6
### Issue Types
7
8
Core issue detection categories that Knip analyzes.
9
10
```typescript { .api }
11
/** All available issue types */
12
type IssueType =
13
| 'files' // Unused files
14
| 'dependencies' // Unused dependencies
15
| 'devDependencies' // Unused devDependencies
16
| 'optionalPeerDependencies' // Referenced optional peerDependencies
17
| 'unlisted' // Unlisted dependencies
18
| 'binaries' // Unlisted binaries
19
| 'unresolved' // Unresolved imports
20
| 'exports' // Unused exports
21
| 'nsExports' // Exports in used namespace
22
| 'types' // Unused exported types
23
| 'nsTypes' // Exported types in used namespace
24
| 'enumMembers' // Unused exported enum members
25
| 'classMembers' // Unused exported class members
26
| 'duplicates'; // Duplicate exports
27
28
/** Issue type titles for display */
29
const ISSUE_TYPE_TITLE: Record<IssueType, string> = {
30
files: 'Unused files',
31
dependencies: 'Unused dependencies',
32
devDependencies: 'Unused devDependencies',
33
optionalPeerDependencies: 'Referenced optional peerDependencies',
34
unlisted: 'Unlisted dependencies',
35
binaries: 'Unlisted binaries',
36
unresolved: 'Unresolved imports',
37
exports: 'Unused exports',
38
nsExports: 'Exports in used namespace',
39
types: 'Unused exported types',
40
nsTypes: 'Exported types in used namespace',
41
enumMembers: 'Unused exported enum members',
42
classMembers: 'Unused exported class members',
43
duplicates: 'Duplicate exports'
44
};
45
```
46
47
**Usage Examples:**
48
49
```typescript
50
import { main } from "knip";
51
52
const results = await main({ cwd: process.cwd() });
53
54
// Check specific issue types
55
console.log(`Unused files: ${results.counters.files}`);
56
console.log(`Unused dependencies: ${results.counters.dependencies}`);
57
console.log(`Unused exports: ${results.counters.exports}`);
58
59
// Process all issues
60
for (const issueType of Object.keys(results.issues) as IssueType[]) {
61
const count = results.counters[issueType];
62
if (count > 0) {
63
console.log(`Found ${count} ${issueType} issues`);
64
}
65
}
66
```
67
68
### Issue Structure
69
70
Detailed information about each detected issue.
71
72
```typescript { .api }
73
interface Issue {
74
/** Type of issue detected */
75
type: SymbolIssueType;
76
/** File path where issue occurs */
77
filePath: string;
78
/** Workspace containing the issue */
79
workspace: string;
80
/** Symbol name with the issue */
81
symbol: string;
82
/** Additional symbols involved in the issue */
83
symbols?: IssueSymbol[];
84
/** Type of symbol (variable, function, class, etc.) */
85
symbolType?: SymbolType;
86
/** Parent symbol if applicable (e.g., class for method) */
87
parentSymbol?: string;
88
/** Import specifier if applicable */
89
specifier?: string;
90
/** Issue severity level */
91
severity?: IssueSeverity;
92
/** Position in file (character offset) */
93
pos?: number;
94
/** Line number in file */
95
line?: number;
96
/** Column number in file */
97
col?: number;
98
/** Whether issue was automatically fixed */
99
isFixed?: boolean;
100
}
101
102
interface IssueSymbol {
103
/** Symbol name */
104
symbol: string;
105
/** Position in file (character offset) */
106
pos?: number;
107
/** Line number */
108
line?: number;
109
/** Column number */
110
col?: number;
111
}
112
113
enum SymbolType {
114
VARIABLE = 'variable',
115
TYPE = 'type',
116
INTERFACE = 'interface',
117
ENUM = 'enum',
118
FUNCTION = 'function',
119
CLASS = 'class',
120
MEMBER = 'member',
121
UNKNOWN = 'unknown'
122
}
123
124
type SymbolIssueType = Exclude<IssueType, 'files'>;
125
type IssueSeverity = 'error' | 'warn' | 'off';
126
```
127
128
**Issue Processing Examples:**
129
130
```typescript
131
// Process unused exports
132
for (const [filePath, fileIssues] of Object.entries(results.issues.exports)) {
133
for (const [symbol, issue] of Object.entries(fileIssues)) {
134
console.log(`Unused export "${symbol}" in ${filePath}:${issue.line}`);
135
136
if (issue.symbolType === 'function') {
137
console.log(` - Unused function: ${symbol}`);
138
} else if (issue.symbolType === 'class') {
139
console.log(` - Unused class: ${symbol}`);
140
}
141
}
142
}
143
144
// Process unresolved imports
145
for (const [filePath, fileIssues] of Object.entries(results.issues.unresolved)) {
146
for (const [specifier, issue] of Object.entries(fileIssues)) {
147
console.log(`Unresolved import "${specifier}" in ${filePath}:${issue.line}`);
148
}
149
}
150
151
// Process unused dependencies
152
for (const [workspace, deps] of Object.entries(results.issues.dependencies)) {
153
for (const [depName, issue] of Object.entries(deps)) {
154
console.log(`Unused dependency "${depName}" in workspace ${workspace}`);
155
}
156
}
157
```
158
159
### Issue Collection
160
161
The IssueCollector class manages issue detection and categorization.
162
163
```typescript { .api }
164
/**
165
* Issue collection and management
166
*/
167
class IssueCollector {
168
constructor(options: MainOptions);
169
170
/** Get all collected issues with counters and hints */
171
getIssues(): {
172
issues: Issues;
173
counters: Counters;
174
tagHints: Set<TagHint>;
175
configurationHints: Set<ConfigurationHint>;
176
};
177
}
178
179
interface Issues {
180
/** Unused files */
181
files: Set<string>;
182
/** Internal representation of unused files */
183
_files: Record<string, Record<string, Issue>>;
184
/** Unused dependencies by workspace */
185
dependencies: Record<string, Record<string, Issue>>;
186
/** Unused devDependencies by workspace */
187
devDependencies: Record<string, Record<string, Issue>>;
188
/** Referenced optional peerDependencies */
189
optionalPeerDependencies: Record<string, Record<string, Issue>>;
190
/** Unlisted dependencies by workspace */
191
unlisted: Record<string, Record<string, Issue>>;
192
/** Unlisted binaries by workspace */
193
binaries: Record<string, Record<string, Issue>>;
194
/** Unresolved imports by file */
195
unresolved: Record<string, Record<string, Issue>>;
196
/** Unused exports by file */
197
exports: Record<string, Record<string, Issue>>;
198
/** Unused exported types by file */
199
types: Record<string, Record<string, Issue>>;
200
/** Exports in used namespace by file */
201
nsExports: Record<string, Record<string, Issue>>;
202
/** Exported types in used namespace by file */
203
nsTypes: Record<string, Record<string, Issue>>;
204
/** Duplicate exports by file */
205
duplicates: Record<string, Record<string, Issue>>;
206
/** Unused exported enum members by file */
207
enumMembers: Record<string, Record<string, Issue>>;
208
/** Unused exported class members by file */
209
classMembers: Record<string, Record<string, Issue>>;
210
}
211
212
interface Counters {
213
files: number;
214
dependencies: number;
215
devDependencies: number;
216
optionalPeerDependencies: number;
217
unlisted: number;
218
binaries: number;
219
unresolved: number;
220
exports: number;
221
types: number;
222
nsExports: number;
223
nsTypes: number;
224
duplicates: number;
225
enumMembers: number;
226
classMembers: number;
227
/** Total processed files */
228
processed: number;
229
/** Total issues found */
230
total: number;
231
}
232
```
233
234
### Issue Fixing
235
236
Automatic fixing capabilities for certain issue types.
237
238
```typescript { .api }
239
/**
240
* Issue fixing functionality
241
*/
242
class IssueFixer {
243
constructor(options: MainOptions);
244
245
/**
246
* Fix identified issues automatically
247
* @param issues - Issues to fix
248
* @returns Set of modified file paths
249
*/
250
fixIssues(issues: Issues): Promise<Set<string>>;
251
}
252
```
253
254
**Fixable Issue Types:**
255
256
- **Unused imports**: Remove unused import statements
257
- **Unused exports**: Remove unused export declarations
258
- **Unused variables**: Remove unused variable declarations
259
- **Unused dependencies**: Update package.json to remove unused deps
260
261
**Usage Examples:**
262
263
```typescript
264
import { main } from "knip";
265
266
// Analyze and fix issues
267
const results = await main({
268
cwd: process.cwd(),
269
isFix: true,
270
isFormat: true // Format files after fixing
271
});
272
273
// Check what was fixed
274
const fixedIssues = Object.values(results.issues)
275
.flatMap(issueGroup =>
276
Object.values(issueGroup).flatMap(Object.values)
277
)
278
.filter(issue => issue.isFixed);
279
280
console.log(`Fixed ${fixedIssues.length} issues`);
281
```
282
283
### Issue Filtering
284
285
Control which issues are reported using include/exclude patterns.
286
287
```typescript { .api }
288
interface Report {
289
files: boolean;
290
dependencies: boolean;
291
devDependencies: boolean;
292
optionalPeerDependencies: boolean;
293
unlisted: boolean;
294
binaries: boolean;
295
unresolved: boolean;
296
exports: boolean;
297
types: boolean;
298
nsExports: boolean;
299
nsTypes: boolean;
300
duplicates: boolean;
301
enumMembers: boolean;
302
classMembers: boolean;
303
}
304
305
interface Rules {
306
files: IssueSeverity;
307
dependencies: IssueSeverity;
308
devDependencies: IssueSeverity;
309
exports: IssueSeverity;
310
types: IssueSeverity;
311
unresolved: IssueSeverity;
312
// ... other rule types
313
}
314
```
315
316
**Filtering Examples:**
317
318
```typescript
319
// Include only specific issue types
320
const results = await main({
321
cwd: process.cwd(),
322
includedIssueTypes: {
323
dependencies: true,
324
exports: true,
325
files: false, // Don't report unused files
326
types: false // Don't report unused types
327
}
328
});
329
330
// Configure issue severity
331
const options = {
332
rules: {
333
dependencies: 'error', // Exit with error code
334
exports: 'warn', // Show warning
335
types: 'off' // Ignore completely
336
}
337
};
338
```
339
340
### Issue Tags
341
342
Support for tagged exports to control issue reporting.
343
344
```typescript { .api }
345
interface TagHint {
346
type: 'tag';
347
filePath: string;
348
identifier: string;
349
tagName: string;
350
}
351
352
/** Supported tag types */
353
const PUBLIC_TAG = '@public';
354
const INTERNAL_TAG = '@internal';
355
const BETA_TAG = '@beta';
356
const ALIAS_TAG = '@alias';
357
```
358
359
**Tag Usage Examples:**
360
361
```typescript
362
// Mark exports with tags to control reporting
363
export const internalUtil = () => {}; // @internal
364
365
/**
366
* Public API function
367
* @public
368
*/
369
export const publicFunction = () => {};
370
371
/**
372
* Beta feature - may be removed
373
* @beta
374
*/
375
export const betaFeature = () => {};
376
```