or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

analysis.mdcli.mdconfiguration.mdindex.mdissues.mdplugins.mdreporting.md
tile.json

plugins.mddocs/

0

# Plugin System

1

2

Extensive plugin architecture supporting 129+ tools and frameworks with automatic detection and configuration. Plugins extend Knip's analysis capabilities to understand project-specific patterns and configurations.

3

4

## Capabilities

5

6

### Plugin Interface

7

8

Core plugin interface for extending Knip functionality.

9

10

```typescript { .api }

11

/**

12

* Plugin interface for extending Knip analysis

13

*/

14

interface Plugin {

15

/** Display name for the plugin */

16

title: string;

17

/** CLI argument configuration */

18

args?: Args;

19

/** Path to package.json or function to check manifest */

20

packageJsonPath?: string | ((manifest: PackageJson) => unknown);

21

/** Dependencies/files that enable this plugin */

22

enablers?: IgnorePatterns | string;

23

/** Custom plugin enablement logic */

24

isEnabled?: IsPluginEnabled;

25

/** Only run in root workspace */

26

isRootOnly?: boolean;

27

/** Configuration file patterns */

28

config?: string[];

29

/** Entry file patterns */

30

entry?: string[];

31

/** Production-specific file patterns */

32

production?: string[];

33

/** Project file patterns */

34

project?: string[];

35

/** Plugin setup function */

36

setup?: PluginSetup;

37

/** Plugin teardown function */

38

teardown?: PluginTeardown;

39

/** Function to determine if config should be loaded */

40

isLoadConfig?: IsLoadConfig;

41

/** Function to resolve configuration files */

42

resolveConfig?: ResolveConfig;

43

/** Function to resolve additional inputs */

44

resolve?: Resolve;

45

/** Function to resolve inputs from AST */

46

resolveFromAST?: ResolveFromAST;

47

}

48

49

type IsPluginEnabled = (options: IsPluginEnabledOptions) => boolean | Promise<boolean>;

50

51

interface IsPluginEnabledOptions {

52

cwd: string;

53

manifest: PackageJson;

54

dependencies: Set<string>;

55

config: WorkspaceConfiguration;

56

}

57

58

type PluginSetup = (options: PluginOptions) => Promise<void> | void;

59

type PluginTeardown = (options: PluginOptions) => Promise<void> | void;

60

type IsLoadConfig = (options: PluginOptions, dependencies: Set<string>) => boolean;

61

type ResolveConfig<T = any> = (config: T, options: PluginOptions) => Promise<Input[]> | Input[];

62

type Resolve = (options: PluginOptions) => Promise<Input[]> | Input[];

63

```

64

65

**Usage Examples:**

66

67

### Creating Custom Plugins

68

69

```typescript

70

import type { Plugin } from "knip";

71

72

const myCustomPlugin: Plugin = {

73

title: "My Custom Tool",

74

enablers: ["my-custom-tool"],

75

config: ["my-tool.config.{js,json}"],

76

entry: ["src/my-tool-entries/**/*.js"],

77

resolve: async (options) => {

78

// Custom logic to find additional entry points

79

return [

80

{ filePath: "src/generated.js" },

81

{ filePath: "scripts/build.js" }

82

];

83

}

84

};

85

```

86

87

### Available Plugins

88

89

Knip includes 129+ built-in plugins for popular tools and frameworks.

90

91

```typescript { .api }

92

/** Map of all available plugins */

93

const plugins: Record<PluginName, Plugin>;

94

95

/** Union type of all plugin names */

96

type PluginName =

97

| 'angular' | 'astro' | 'ava' | 'babel' | 'biome' | 'bun' | 'c8'

98

| 'capacitor' | 'changelogen' | 'changesets' | 'commitizen' | 'commitlint'

99

| 'convex' | 'create-typescript-app' | 'cspell' | 'cucumber' | 'cypress'

100

| 'dependency-cruiser' | 'docusaurus' | 'drizzle' | 'eleventy' | 'eslint'

101

| 'expo' | 'gatsby' | 'github-actions' | 'glob' | 'graphql-codegen'

102

| 'husky' | 'jest' | 'knip' | 'lefthook' | 'lint-staged' | 'markdownlint'

103

| 'mocha' | 'msw' | 'next' | 'node-test-runner' | 'nodemon' | 'npm-package-json-lint'

104

| 'nuxt' | 'nx' | 'oclif' | 'playwright' | 'postcss' | 'prettier'

105

| 'react' | 'release-it' | 'remix' | 'rollup' | 'rush' | 'semantic-release'

106

| 'storybook' | 'tailwind' | 'tsup' | 'typescript' | 'unbuild' | 'vite'

107

| 'vitest' | 'vue' | 'webpack' | 'wireit' | 'xo' | 'yarn'

108

// ... and 80+ more

109

;

110

```

111

112

**Popular Plugins:**

113

114

### Framework Plugins

115

116

```typescript

117

// Next.js plugin

118

const nextPlugin: Plugin = {

119

title: "Next.js",

120

enablers: ["next"],

121

config: ["next.config.{js,mjs,ts}"],

122

entry: ["pages/**/*.{js,jsx,ts,tsx}", "app/**/*.{js,jsx,ts,tsx}"]

123

};

124

125

// React plugin

126

const reactPlugin: Plugin = {

127

title: "React",

128

enablers: ["react", "react-dom"],

129

entry: ["src/**/*.{jsx,tsx}"]

130

};

131

132

// Vue plugin

133

const vuePlugin: Plugin = {

134

title: "Vue",

135

enablers: ["vue"],

136

entry: ["src/**/*.vue"]

137

};

138

```

139

140

### Testing Framework Plugins

141

142

```typescript

143

// Jest plugin

144

const jestPlugin: Plugin = {

145

title: "Jest",

146

enablers: ["jest"],

147

config: ["jest.config.{js,ts,mjs,cjs,json}"],

148

entry: ["**/*.{test,spec}.{js,ts,tsx,jsx}"]

149

};

150

151

// Cypress plugin

152

const cypressPlugin: Plugin = {

153

title: "Cypress",

154

enablers: ["cypress"],

155

config: ["cypress.config.{js,ts}"],

156

entry: ["cypress/**/*.{js,ts}"]

157

};

158

159

// Playwright plugin

160

const playwrightPlugin: Plugin = {

161

title: "Playwright",

162

enablers: ["@playwright/test", "playwright"],

163

config: ["playwright.config.{js,ts}"],

164

entry: ["**/*.{test,spec}.{js,ts}"]

165

};

166

```

167

168

### Build Tool Plugins

169

170

```typescript

171

// Webpack plugin

172

const webpackPlugin: Plugin = {

173

title: "Webpack",

174

enablers: ["webpack"],

175

config: ["webpack.config.{js,ts}"],

176

entry: ["webpack.config.{js,ts}"]

177

};

178

179

// Vite plugin

180

const vitePlugin: Plugin = {

181

title: "Vite",

182

enablers: ["vite"],

183

config: ["vite.config.{js,ts,mjs}"],

184

entry: ["vite.config.{js,ts,mjs}"]

185

};

186

187

// Rollup plugin

188

const rollupPlugin: Plugin = {

189

title: "Rollup",

190

enablers: ["rollup"],

191

config: ["rollup.config.{js,ts,mjs}"],

192

entry: ["rollup.config.{js,ts,mjs}"]

193

};

194

```

195

196

### Plugin Options

197

198

Configuration options passed to plugin functions.

199

200

```typescript { .api }

201

interface PluginOptions {

202

/** Root working directory */

203

rootCwd: string;

204

/** Current working directory */

205

cwd: string;

206

/** Set of npm script names */

207

manifestScriptNames: Set<string>;

208

/** Package.json manifest */

209

manifest: PackageJson;

210

/** Plugin configuration */

211

config: EnsuredPluginConfiguration;

212

/** Configuration file directory */

213

configFileDir: string;

214

/** Configuration file name */

215

configFileName: string;

216

/** Configuration file path */

217

configFilePath: string;

218

/** Production mode flag */

219

isProduction: boolean;

220

/** List of enabled plugins */

221

enabledPlugins: string[];

222

/** Function to get inputs from npm scripts */

223

getInputsFromScripts: GetInputsFromScriptsPartial;

224

}

225

226

interface EnsuredPluginConfiguration {

227

/** Configuration file patterns */

228

config: string[] | null;

229

/** Entry file patterns */

230

entry: string[] | null;

231

/** Project file patterns */

232

project: string[] | null;

233

}

234

235

type GetInputsFromScriptsPartial = (

236

npmScripts: string | string[] | Set<string>,

237

options?: Partial<GetInputsFromScriptsOptions>

238

) => Input[];

239

```

240

241

### Plugin Resolution

242

243

Functions for resolving plugin inputs and configurations.

244

245

```typescript { .api }

246

/**

247

* Input representing a file or dependency

248

*/

249

interface Input {

250

/** File path */

251

filePath: string;

252

/** Optional specifier for the input */

253

specifier?: string;

254

}

255

256

/**

257

* Resolve configuration function type

258

*/

259

type ResolveConfig<T = any> = (

260

config: T,

261

options: PluginOptions

262

) => Promise<Input[]> | Input[];

263

264

/**

265

* Resolve function type for finding additional inputs

266

*/

267

type Resolve = (

268

options: PluginOptions

269

) => Promise<Input[]> | Input[];

270

271

/**

272

* Resolve from AST function type

273

*/

274

type ResolveFromAST = (

275

sourceFile: ts.SourceFile,

276

options: PluginOptions & {

277

getSourceFile: GetSourceFile;

278

getReferencedInternalFilePath: GetReferencedInternalFilePath;

279

}

280

) => Input[];

281

282

type GetSourceFile = (filePath: string) => ts.SourceFile | undefined;

283

type GetReferencedInternalFilePath = (input: Input) => string | undefined;

284

```

285

286

**Plugin Resolution Examples:**

287

288

```typescript

289

// Example plugin with custom resolution

290

const examplePlugin: Plugin = {

291

title: "Example Plugin",

292

enablers: ["example-tool"],

293

294

resolve: async (options) => {

295

// Find additional entry points from package.json scripts

296

const inputs = options.getInputsFromScripts(

297

options.manifest.scripts?.build || [],

298

{ containingFilePath: options.configFilePath }

299

);

300

301

return inputs;

302

},

303

304

resolveConfig: async (config, options) => {

305

// Parse configuration file to find referenced files

306

return config.files?.map((file: string) => ({

307

filePath: path.resolve(options.configFileDir, file)

308

})) || [];

309

},

310

311

resolveFromAST: (sourceFile, options) => {

312

// Analyze TypeScript AST to find dynamic imports

313

const inputs: Input[] = [];

314

315

// Custom AST traversal logic here

316

// to find require() calls, dynamic imports, etc.

317

318

return inputs;

319

}

320

};

321

```

322

323

### Plugin Configuration

324

325

Plugins can be configured globally or per workspace.

326

327

```typescript { .api }

328

type PluginConfiguration = boolean | EnsuredPluginConfiguration;

329

330

type PluginsConfiguration = Record<PluginName, PluginConfiguration>;

331

332

interface WorkspaceConfiguration {

333

/** Plugin configurations for this workspace */

334

[pluginName: string]: PluginConfiguration | any;

335

}

336

```

337

338

**Configuration Examples:**

339

340

```json

341

{

342

"jest": true,

343

"eslint": {

344

"config": ["eslint.config.js"],

345

"entry": ["src/**/*.test.js"]

346

},

347

"webpack": false,

348

"workspaces": {

349

"frontend": {

350

"react": true,

351

"jest": {

352

"config": ["jest.config.frontend.js"]

353

}

354

}

355

}

356

}

357

```