0
# @swc/jest
1
2
@swc/jest provides SWC integration for the Jest test runner, offering fast TypeScript and JavaScript compilation during testing. It serves as a drop-in replacement for ts-jest or babel-jest with significantly faster compilation speeds, while supporting modern JavaScript features, TypeScript, JSX, and custom SWC configuration.
3
4
## Package Information
5
6
- **Package Name**: @swc/jest
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install -D jest @swc/core @swc/jest`
10
- **Peer Dependencies**: `@swc/core` (required)
11
- **Export Pattern**: CommonJS (`export = { createTransformer }`)
12
13
## Core Imports
14
15
```javascript { .api }
16
const swcJest = require("@swc/jest");
17
const { createTransformer } = swcJest;
18
```
19
20
For TypeScript projects:
21
22
```typescript { .api }
23
import swcJest from "@swc/jest";
24
const { createTransformer } = swcJest;
25
```
26
27
## Basic Usage
28
29
### Simple Configuration
30
31
Configure Jest to use @swc/jest as a transformer:
32
33
```javascript
34
// jest.config.js
35
module.exports = {
36
transform: {
37
'^.+\\.(t|j)sx?$': '@swc/jest',
38
},
39
};
40
```
41
42
### Advanced Configuration
43
44
```javascript
45
// jest.config.js
46
module.exports = {
47
transform: {
48
'^.+\\.(t|j)sx?$': ['@swc/jest', {
49
jsc: {
50
target: 'es2021',
51
parser: {
52
syntax: 'typescript',
53
tsx: true,
54
},
55
},
56
experimental: {
57
customCoverageInstrumentation: {
58
enabled: true,
59
},
60
},
61
}],
62
},
63
};
64
```
65
66
## Capabilities
67
68
### Transformer Creation
69
70
Creates a Jest transformer that uses SWC for fast compilation of TypeScript and JavaScript files.
71
72
```typescript { .api }
73
/**
74
* Creates a Jest transformer that uses SWC for compilation
75
* @param swcTransformOpts - SWC options with optional experimental coverage settings
76
* @returns Jest Transformer instance
77
*/
78
function createTransformer(
79
swcTransformOpts?: Options & {
80
experimental?: {
81
customCoverageInstrumentation?: CoverageInstrumentationOptions;
82
};
83
}
84
): Transformer;
85
86
interface CoverageInstrumentationOptions {
87
/** Enable custom coverage instrumentation */
88
enabled: boolean;
89
/** Coverage variable name (default: '__coverage__') */
90
coverageVariable?: string;
91
/** Compact output format */
92
compact?: boolean;
93
/** Report logic coverage */
94
reportLogic?: boolean;
95
/** Array of class method names to ignore during instrumentation */
96
ignoreClassMethods?: Array<string>;
97
/** Instrumentation logging configuration */
98
instrumentLog?: {
99
level: string;
100
enableTrace: boolean;
101
};
102
}
103
```
104
105
### Jest Transformer Interface
106
107
The returned transformer implements the Jest Transformer interface with these methods:
108
109
```typescript { .api }
110
interface Transformer {
111
/** Indicates whether the transformer can instrument code for coverage */
112
canInstrument: boolean;
113
114
/**
115
* Synchronously transforms source code using SWC
116
* Module type behavior: Uses 'commonjs' unless jestOptions.supportsStaticESM is true, then uses 'es6'
117
* @param src - Source code to transform
118
* @param filename - File path for the source
119
* @param jestOptions - Jest transformation options
120
* @returns Transformed code result
121
*/
122
process(
123
src: string,
124
filename: string,
125
jestOptions: TransformOptions
126
): TransformResult;
127
128
/**
129
* Asynchronously transforms source code using SWC
130
* Module type behavior: Always uses 'es6' module format for async transformations
131
* @param src - Source code to transform
132
* @param filename - File path for the source
133
* @param jestOptions - Jest transformation options
134
* @returns Promise resolving to transformed code result
135
*/
136
processAsync(
137
src: string,
138
filename: string,
139
jestOptions: TransformOptions
140
): Promise<TransformResult>;
141
142
/**
143
* Generates cache key for transformed files
144
* @param src - Source code
145
* @param filename - File path
146
* @param rest - Additional Jest transform parameters
147
* @returns SHA-1 hash string for caching
148
*/
149
getCacheKey(
150
src: string,
151
filename: string,
152
...rest: any[]
153
): string;
154
}
155
156
interface TransformOptions {
157
/** Whether Jest supports static ESM */
158
supportsStaticESM?: boolean;
159
/** Whether to instrument code for coverage */
160
instrument?: boolean;
161
}
162
163
interface TransformResult {
164
/** Transformed code */
165
code: string;
166
/** Source map (optional) */
167
map?: string | object;
168
}
169
```
170
171
## Configuration
172
173
### Automatic Configuration Processing
174
175
@swc/jest applies several automatic configuration behaviors when creating a transformer:
176
177
1. **Configuration Loading**: Automatically loads SWC configuration from `.swcrc` in the current working directory if no options are provided to `createTransformer()`
178
2. **Node.js Target Detection**: When no explicit `jsc.target` is configured, automatically sets the target based on your Node.js version
179
3. **Hidden Jest Flag**: Automatically sets `jsc.transform.hidden.jest = true` for Jest-specific optimizations (this flag enables SWC's Jest compatibility mode)
180
4. **Default Source Maps**: Sets `sourceMaps: "inline"` if not explicitly configured
181
5. **Base URL Resolution**: Resolves `jsc.baseUrl` to an absolute path if specified
182
6. **Module Type Override**: Dynamically sets the module type (`commonjs` or `es6`) based on Jest's `supportsStaticESM` option, regardless of your SWC configuration
183
184
### SWC Configuration (.swcrc)
185
186
Configuration is loaded automatically from a `.swcrc` file in the project root when no options are provided:
187
188
```json
189
{
190
"jsc": {
191
"target": "es2021",
192
"parser": {
193
"syntax": "typescript",
194
"tsx": true,
195
"decorators": true
196
},
197
"transform": {
198
"react": {
199
"runtime": "automatic"
200
}
201
}
202
},
203
"module": {
204
"type": "commonjs"
205
},
206
"sourceMaps": true
207
}
208
```
209
210
### Node.js Target Defaults
211
212
When no explicit target is configured, @swc/jest automatically sets the `jsc.target` based on your Node.js version:
213
214
| Node Version | Default Target |
215
|--------------|----------------|
216
| 18+ | es2023 |
217
| 17 | es2022 |
218
| 15 | es2021 |
219
| 14 | es2020 |
220
| 13 | es2019 |
221
| <13 | es2018 |
222
223
### Coverage Instrumentation
224
225
Enable custom coverage instrumentation through SWC plugins:
226
227
```javascript
228
// jest.config.js
229
module.exports = {
230
transform: {
231
'^.+\\.(t|j)sx?$': ['@swc/jest', {
232
experimental: {
233
customCoverageInstrumentation: {
234
enabled: true,
235
coverageVariable: '__coverage__',
236
compact: false,
237
reportLogic: true,
238
ignoreClassMethods: ['constructor'],
239
instrumentLog: {
240
level: 'info',
241
enableTrace: false,
242
},
243
},
244
},
245
}],
246
},
247
collectCoverage: true,
248
};
249
```
250
251
## ESM Support
252
253
For ESM (ECMAScript Module) support:
254
255
1. Add `"type": "module"` to package.json for JavaScript projects
256
2. Configure Jest for ESM:
257
258
```javascript
259
// jest.config.js
260
module.exports = {
261
preset: 'ts-jest/presets/default-esm',
262
extensionsToTreatAsEsm: ['.ts', '.tsx'],
263
transform: {
264
'^.+\\.(t|j)sx?$': '@swc/jest',
265
},
266
};
267
```
268
269
3. Run tests with Node.js experimental modules flag:
270
271
```bash
272
cross-env NODE_OPTIONS=--experimental-vm-modules jest
273
```
274
275
## Types
276
277
### SWC Options
278
279
The transformer accepts all standard SWC Options from `@swc/core`:
280
281
```typescript { .api }
282
interface Options {
283
/** ECMAScript target version */
284
jsc?: {
285
target?: 'es3' | 'es5' | 'es2015' | 'es2016' | 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'es2023';
286
parser?: {
287
syntax: 'ecmascript' | 'typescript';
288
jsx?: boolean;
289
tsx?: boolean;
290
decorators?: boolean;
291
};
292
transform?: {
293
react?: {
294
runtime?: 'automatic' | 'classic';
295
pragma?: string;
296
pragmaFrag?: string;
297
};
298
};
299
baseUrl?: string;
300
};
301
/** Module system configuration */
302
module?: {
303
type?: 'commonjs' | 'umd' | 'amd' | 'es6';
304
};
305
/** Source map generation */
306
sourceMaps?: boolean | 'inline';
307
/** Environment preset */
308
env?: {
309
targets?: string | string[] | object;
310
};
311
}
312
```
313
314
## Error Handling
315
316
The package handles several error conditions with specific error messages:
317
318
### Configuration Errors
319
320
- **Invalid .swcrc parsing**: Uses `jsonc-parser` to provide detailed error information with line/column positions when `.swcrc` contains invalid JSON
321
- **Node.js version parsing**: Throws `Error("Could not parse major version from ${process.version}")` if the Node.js version string cannot be parsed
322
- **SWC configuration errors**: Invalid SWC options passed to `createTransformer()` result in SWC-specific error messages
323
324
### Transform Errors
325
326
- **SWC transform failures**: Transform errors from SWC core are propagated with original stack traces
327
- **File processing errors**: Errors during `process()` or `processAsync()` include filename context
328
329
**Example error scenarios:**
330
331
```javascript
332
// Invalid .swcrc file
333
try {
334
const transformer = createTransformer(); // Will try to load .swcrc
335
} catch (error) {
336
console.error('Configuration error:', error.message);
337
// Example: "Error parsing /path/to/.swcrc: Unexpected token..."
338
}
339
340
// Invalid SWC options
341
try {
342
const transformer = createTransformer({
343
jsc: { target: 'invalid-target' }
344
});
345
} catch (error) {
346
console.error('SWC configuration error:', error.message);
347
}
348
349
// Node.js version parsing failure (rare)
350
// Would occur if process.version is malformed
351
```
352
353
### Coverage Instrumentation
354
355
The coverage instrumentation feature automatically handles plugin conflicts:
356
- If `swc-plugin-coverage-instrument` is already configured in `jsc.experimental.plugins`, it won't be added again
357
- Coverage instrumentation only activates when both `jestOptions.instrument` is true and `customCoverageInstrumentation.enabled` is true