or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdconfiguration.mderror-handling.mdindex.mdplugin-system.mdprogrammatic-api.md

plugin-system.mddocs/

0

# Plugin System

1

2

Size Limit uses a modular plugin architecture that allows different bundlers, measurement tools, and analysis features to be combined flexibly.

3

4

## Capabilities

5

6

### Plugin Interface

7

8

The plugin system defines a standard interface for extending Size Limit functionality.

9

10

```javascript { .api }

11

// Plugin interface for plugin developers

12

interface Plugin {

13

// Plugin identification

14

name: string; // Plugin name (e.g., "@size-limit/webpack")

15

16

// Lifecycle hooks

17

before?(config: object, check: Check): Promise<void>;

18

finally?(config: object, check: Check): Promise<void>;

19

20

// Processing steps (0-100 available)

21

step0?(config: object, check: Check): Promise<void>;

22

step1?(config: object, check: Check): Promise<void>;

23

// ... step2 through step99

24

step100?(config: object, check: Check): Promise<void>;

25

26

// Progress messages for steps

27

wait0?: string; // Progress message for step0

28

wait1?: string; // Progress message for step1

29

// ... wait2 through wait100

30

}

31

32

// Plugin loading system

33

class Plugins {

34

constructor(list: Plugin[]);

35

list: Plugin[]; // Array of loaded plugins

36

isEmpty: boolean; // True if no plugins loaded

37

has(type: string): boolean; // Check if plugin type is available

38

}

39

```

40

41

### Core Plugins

42

43

Official plugins that provide essential Size Limit functionality.

44

45

```javascript { .api }

46

// File measurement plugin

47

// Package: @size-limit/file

48

// Provides: Basic file size measurement with compression options

49

50

// Webpack integration plugin

51

// Package: @size-limit/webpack

52

// Provides: Webpack bundling, tree-shaking, custom config support

53

54

// ESBuild integration plugin

55

// Package: @size-limit/esbuild

56

// Provides: ESBuild bundling, fast compilation, modern JS support

57

58

// Time measurement plugin

59

// Package: @size-limit/time

60

// Provides: Browser execution time measurement, network simulation

61

62

// CSS support plugin

63

// Package: @size-limit/webpack-css

64

// Provides: CSS processing and measurement with webpack

65

66

// Bundle analysis plugins

67

// Package: @size-limit/webpack-why

68

// Package: @size-limit/esbuild-why

69

// Provides: Detailed bundle analysis, dependency graphs, size breakdowns

70

```

71

72

### Plugin Installation

73

74

Plugins are installed as separate npm packages and automatically detected.

75

76

**Usage Examples:**

77

78

```bash

79

# Install individual plugins

80

npm install --save-dev @size-limit/file

81

npm install --save-dev @size-limit/webpack

82

npm install --save-dev @size-limit/time

83

84

# Install preset bundles

85

npm install --save-dev @size-limit/preset-app

86

npm install --save-dev @size-limit/preset-big-lib

87

npm install --save-dev @size-limit/preset-small-lib

88

```

89

90

### Plugin Detection

91

92

Size Limit automatically detects and loads available plugins from project dependencies.

93

94

```javascript { .api }

95

// Plugin detection rules:

96

// 1. Scans package.json dependencies, devDependencies, optionalDependencies

97

// 2. Matches packages with names starting with "@size-limit/" or "size-limit-"

98

// 3. Dynamically imports matching packages

99

// 4. Flattens plugin arrays (plugins can export multiple plugins)

100

// 5. Creates Plugins instance with loaded plugin list

101

102

async function loadPlugins(pkg: PackageInfo): Promise<Plugins>;

103

104

interface PackageInfo {

105

packageJson: {

106

dependencies?: Record<string, string>;

107

devDependencies?: Record<string, string>;

108

optionalDependencies?: Record<string, string>;

109

};

110

path: string;

111

}

112

```

113

114

### Configuration-Based Plugin Usage

115

116

Plugins are activated based on configuration options in each check.

117

118

```javascript { .api }

119

// Plugin activation mapping

120

const PLUGIN_OPTIONS = {

121

brotli: "file", // @size-limit/file

122

gzip: "file", // @size-limit/file

123

webpack: "webpack", // @size-limit/webpack

124

config: ["webpack", "esbuild"], // @size-limit/webpack or @size-limit/esbuild

125

entry: "webpack", // @size-limit/webpack

126

ignore: ["webpack", "esbuild"], // @size-limit/webpack or @size-limit/esbuild

127

import: ["webpack", "esbuild"], // @size-limit/webpack or @size-limit/esbuild

128

modifyWebpackConfig: "webpack", // @size-limit/webpack

129

modifyEsbuildConfig: "esbuild", // @size-limit/esbuild

130

running: "time", // @size-limit/time

131

time: "time", // @size-limit/time

132

uiReports: "webpack", // @size-limit/webpack

133

compareWith: "webpack" // @size-limit/webpack

134

};

135

```

136

137

**Configuration Examples:**

138

139

```json

140

{

141

"size-limit": [

142

{

143

"name": "File only",

144

"path": "dist/lib.js",

145

"webpack": false,

146

"running": false

147

},

148

{

149

"name": "Webpack + Time",

150

"path": "src/app.js",

151

"webpack": true,

152

"running": true,

153

"time": {

154

"networkSpeed": "3G"

155

}

156

},

157

{

158

"name": "ESBuild",

159

"path": "src/modern.js",

160

"config": "esbuild.config.js",

161

"modifyEsbuildConfig": "(config) => ({ ...config, target: 'es2020' })"

162

}

163

]

164

}

165

```

166

167

### Preset Packages

168

169

Preset packages provide pre-configured plugin combinations for common use cases.

170

171

```javascript { .api }

172

// @size-limit/preset-app

173

// Includes: @size-limit/webpack, @size-limit/time, @size-limit/file

174

// Use case: Large applications with custom bundlers

175

176

// @size-limit/preset-big-lib

177

// Includes: @size-limit/webpack, @size-limit/file

178

// Use case: Libraries > 10kB that need bundling

179

180

// @size-limit/preset-small-lib

181

// Includes: @size-limit/file

182

// Use case: Small libraries < 10kB that don't need bundling

183

```

184

185

**Preset Usage:**

186

187

```bash

188

# Install preset

189

npm install --save-dev @size-limit/preset-app

190

191

# Configuration automatically uses included plugins

192

{

193

"size-limit": [

194

{

195

"path": "dist/app.js",

196

"limit": "100 kB"

197

}

198

]

199

}

200

```

201

202

### Plugin Execution Flow

203

204

Size Limit executes plugins through a structured lifecycle with numbered steps.

205

206

```javascript { .api }

207

// Plugin execution order:

208

// 1. before() hook for all plugins

209

// 2. step0() through step100() for all plugins (in sequence)

210

// 3. finally() hook for all plugins (always executed, even on error)

211

212

// Example execution flow:

213

async function executePlugins(plugins: Plugins, config: object) {

214

try {

215

// Before phase

216

for (let plugin of plugins.list) {

217

if (plugin.before) {

218

await plugin.before(config, check);

219

}

220

}

221

222

// Step phases

223

for (let stepNumber = 0; stepNumber <= 100; stepNumber++) {

224

for (let plugin of plugins.list) {

225

const stepMethod = `step${stepNumber}`;

226

if (plugin[stepMethod]) {

227

await plugin[stepMethod](config, check);

228

}

229

}

230

}

231

} finally {

232

// Finally phase

233

for (let plugin of plugins.list) {

234

if (plugin.finally) {

235

await plugin.finally(config, check);

236

}

237

}

238

}

239

}

240

```

241

242

### Creating Custom Plugins

243

244

Developers can create custom plugins following the standard interface.

245

246

**Custom Plugin Example:**

247

248

```javascript

249

// custom-plugin.js

250

export default {

251

name: "custom-size-plugin",

252

253

// Initialize plugin

254

async before(config, check) {

255

console.log(`Starting analysis for ${check.name}`);

256

},

257

258

// Main processing step

259

async step50(config, check) {

260

// Custom size calculation logic

261

const customSize = await calculateCustomSize(check.files);

262

check.customMetric = customSize;

263

},

264

265

// Cleanup

266

async finally(config, check) {

267

console.log(`Finished analysis for ${check.name}`);

268

},

269

270

// Progress messages

271

wait50: "Calculating custom metrics..."

272

};

273

274

// Usage with programmatic API

275

import sizeLimit from "size-limit";

276

import filePlugin from "@size-limit/file";

277

import customPlugin from "./custom-plugin.js";

278

279

const results = await sizeLimit(

280

[filePlugin, customPlugin],

281

["dist/bundle.js"]

282

);

283

```

284

285

### Plugin Development Guidelines

286

287

Guidelines for developing Size Limit plugins.

288

289

```javascript { .api }

290

// Plugin development best practices:

291

// 1. Use descriptive plugin names with @size-limit/ or size-limit- prefix

292

// 2. Implement appropriate lifecycle hooks (before/finally for setup/cleanup)

293

// 3. Use numbered steps (step0-step100) for main processing

294

// 4. Provide wait messages for long-running steps

295

// 5. Handle errors gracefully and clean up resources in finally

296

// 6. Modify check objects to add measurements

297

// 7. Respect existing check properties and plugin interactions

298

// 8. Document plugin configuration options and requirements

299

```

300

301

### Error Handling in Plugins

302

303

Plugin errors are handled gracefully with proper cleanup.

304

305

```javascript { .api }

306

// Error handling flow:

307

// 1. If any step throws an error, execution stops

308

// 2. finally() hooks are always called for cleanup

309

// 3. Progress spinners are marked as failed

310

// 4. Error is propagated to CLI or API caller

311

312

// Error handling example in plugin:

313

export default {

314

name: "example-plugin",

315

316

async step10(config, check) {

317

try {

318

await riskyOperation(check);

319

} catch (error) {

320

// Log error context

321

console.error(`Plugin ${this.name} failed:`, error);

322

// Re-throw to stop execution

323

throw error;

324

}

325

},

326

327

async finally(config, check) {

328

// Always cleanup, even on error

329

await cleanup();

330

}

331

};

332

```