0
# Compatibility System
1
2
The compatibility system in @nuxt/schema provides module compatibility checking and validation to ensure proper module integration with specific Nuxt versions and build systems.
3
4
## Core Compatibility Types
5
6
### NuxtCompatibility Interface
7
8
Defines compatibility requirements for modules and packages.
9
10
```typescript { .api }
11
interface NuxtCompatibility {
12
/** Required Nuxt version in semver format */
13
nuxt?: string
14
/** Builder compatibility requirements */
15
builder?: Partial<Record<'vite' | 'webpack' | 'rspack' | (string & {}), false | string>>
16
}
17
```
18
19
### Compatibility Issues
20
21
Types for handling and reporting compatibility issues.
22
23
```typescript { .api }
24
interface NuxtCompatibilityIssue {
25
name: string
26
message: string
27
}
28
29
interface NuxtCompatibilityIssues extends Array<NuxtCompatibilityIssue> {
30
/** Return formatted error message */
31
toString(): string
32
}
33
```
34
35
## Compatibility Declaration
36
37
### Module Compatibility
38
39
```typescript
40
import type { NuxtModule, NuxtCompatibility } from '@nuxt/schema';
41
42
const myModule: NuxtModule = {
43
meta: {
44
name: 'my-module',
45
version: '2.0.0',
46
compatibility: {
47
// Require Nuxt 3.2.0 or higher
48
nuxt: '^3.2.0',
49
50
// Builder-specific compatibility
51
builder: {
52
vite: '^4.0.0', // Require Vite 4.0.0+
53
webpack: '^5.0.0', // Require Webpack 5.0.0+
54
rspack: false // Not compatible with Rspack
55
}
56
} satisfies NuxtCompatibility
57
},
58
59
setup(options, nuxt) {
60
// Module setup - compatibility is checked before this runs
61
}
62
};
63
```
64
65
### Advanced Compatibility Requirements
66
67
```typescript
68
const advancedModule: NuxtModule = {
69
meta: {
70
name: 'advanced-module',
71
compatibility: {
72
// Require specific Nuxt version range
73
nuxt: '>=3.8.0 <4.0.0',
74
75
// Complex builder requirements
76
builder: {
77
vite: '^5.0.0', // Latest Vite
78
webpack: '>=5.88.0', // Minimum Webpack version
79
rspack: '^1.0.0' // Rspack support
80
}
81
}
82
},
83
84
setup(options, nuxt) {
85
// Check for additional runtime compatibility
86
if (nuxt.options.ssr === false && !options.spaMode) {
87
throw new Error('This module requires SSR or explicit SPA mode configuration');
88
}
89
}
90
};
91
```
92
93
## Compatibility Checking
94
95
### Automatic Compatibility Validation
96
97
Nuxt automatically validates module compatibility during installation:
98
99
```typescript
100
// This validation happens automatically
101
export default defineNuxtConfig({
102
modules: [
103
// ✅ Compatible module
104
['my-compatible-module', { /* options */ }],
105
106
// ❌ Would throw compatibility error if requirements not met
107
['incompatible-module', { /* options */ }]
108
]
109
});
110
```
111
112
### Manual Compatibility Checking
113
114
```typescript
115
import type { NuxtCompatibility, NuxtCompatibilityIssues } from '@nuxt/schema';
116
117
function checkCompatibility(
118
compatibility: NuxtCompatibility,
119
nuxtVersion: string,
120
builderName: string,
121
builderVersion: string
122
): NuxtCompatibilityIssues {
123
const issues: NuxtCompatibilityIssues = [] as any;
124
125
// Check Nuxt version compatibility
126
if (compatibility.nuxt) {
127
if (!satisfies(nuxtVersion, compatibility.nuxt)) {
128
issues.push({
129
name: 'nuxt-version',
130
message: `Requires Nuxt ${compatibility.nuxt}, but found ${nuxtVersion}`
131
});
132
}
133
}
134
135
// Check builder compatibility
136
if (compatibility.builder) {
137
const builderReq = compatibility.builder[builderName];
138
139
if (builderReq === false) {
140
issues.push({
141
name: 'builder-incompatible',
142
message: `Not compatible with ${builderName}`
143
});
144
} else if (builderReq && !satisfies(builderVersion, builderReq)) {
145
issues.push({
146
name: 'builder-version',
147
message: `Requires ${builderName} ${builderReq}, but found ${builderVersion}`
148
});
149
}
150
}
151
152
// Add toString method
153
issues.toString = function() {
154
return this.map(issue => `- ${issue.message}`).join('\n');
155
};
156
157
return issues;
158
}
159
```
160
161
### Compatibility Hook Integration
162
163
```typescript
164
export default defineNuxtModule({
165
meta: {
166
name: 'compatibility-aware-module'
167
},
168
169
setup(options, nuxt) {
170
// Listen for compatibility checks
171
nuxt.hook('kit:compatibility', (compatibility, issues) => {
172
console.log('Compatibility check:', compatibility);
173
174
if (issues.length > 0) {
175
console.warn('Compatibility issues found:', issues.toString());
176
}
177
});
178
179
// Perform custom compatibility checks
180
const customCompatibility: NuxtCompatibility = {
181
nuxt: '^3.0.0',
182
builder: {
183
vite: '^4.0.0'
184
}
185
};
186
187
const issues = checkCompatibility(
188
customCompatibility,
189
nuxt.options._nuxtVersion || '3.0.0',
190
nuxt.options.builder === '@nuxt/vite-builder' ? 'vite' : 'webpack',
191
'4.0.0' // Would normally detect actual version
192
);
193
194
if (issues.length > 0) {
195
nuxt.callHook('kit:compatibility', customCompatibility, issues);
196
}
197
}
198
});
199
```
200
201
## Builder-Specific Compatibility
202
203
### Vite-Only Modules
204
205
```typescript
206
const viteOnlyModule: NuxtModule = {
207
meta: {
208
name: 'vite-only-module',
209
compatibility: {
210
nuxt: '^3.0.0',
211
builder: {
212
vite: '^4.0.0',
213
webpack: false, // Explicitly not compatible
214
rspack: false // Explicitly not compatible
215
}
216
}
217
},
218
219
setup(options, nuxt) {
220
// This will only run with Vite builder
221
if (nuxt.options.builder !== '@nuxt/vite-builder') {
222
throw new Error('This module requires Vite builder');
223
}
224
}
225
};
226
```
227
228
### Multi-Builder Support
229
230
```typescript
231
const multiBuiderModule: NuxtModule = {
232
meta: {
233
name: 'multi-builder-module',
234
compatibility: {
235
nuxt: '^3.0.0',
236
builder: {
237
vite: '^4.0.0',
238
webpack: '^5.0.0',
239
rspack: '^1.0.0'
240
}
241
}
242
},
243
244
setup(options, nuxt) {
245
// Different setup based on builder
246
if (nuxt.options.builder === '@nuxt/vite-builder') {
247
// Vite-specific setup
248
nuxt.hook('vite:extend', ({ config }) => {
249
config.plugins = config.plugins || [];
250
config.plugins.push(myVitePlugin());
251
});
252
} else if (nuxt.options.builder === '@nuxt/webpack-builder') {
253
// Webpack-specific setup
254
nuxt.hook('webpack:config', (configs) => {
255
configs.forEach(config => {
256
config.plugins = config.plugins || [];
257
config.plugins.push(new MyWebpackPlugin());
258
});
259
});
260
}
261
}
262
};
263
```
264
265
## Feature-Based Compatibility
266
267
### Experimental Feature Dependencies
268
269
```typescript
270
const experimentalModule: NuxtModule = {
271
meta: {
272
name: 'experimental-module',
273
compatibility: {
274
nuxt: '^3.8.0' // Requires newer Nuxt for experimental features
275
}
276
},
277
278
setup(options, nuxt) {
279
// Check for required experimental features
280
if (!nuxt.options.experimental?.componentIslands) {
281
throw new Error('This module requires experimental.componentIslands to be enabled');
282
}
283
284
if (!nuxt.options.experimental?.typedPages) {
285
console.warn('This module works best with experimental.typedPages enabled');
286
}
287
}
288
};
289
```
290
291
### Runtime Compatibility Checks
292
293
```typescript
294
const runtimeCompatibleModule: NuxtModule = {
295
setup(options, nuxt) {
296
// Check Node.js version
297
const nodeVersion = process.version;
298
const requiredNodeVersion = '>=18.0.0';
299
300
if (!satisfies(nodeVersion, requiredNodeVersion)) {
301
throw new Error(`Requires Node.js ${requiredNodeVersion}, found ${nodeVersion}`);
302
}
303
304
// Check for required dependencies
305
const requiredDeps = ['@vue/composition-api', 'pinia'];
306
307
for (const dep of requiredDeps) {
308
try {
309
require.resolve(dep);
310
} catch {
311
throw new Error(`Missing required dependency: ${dep}`);
312
}
313
}
314
315
// Environment compatibility
316
if (nuxt.options.nitro?.preset === 'cloudflare-pages' && options.useFileSystem) {
317
throw new Error('File system operations not supported on Cloudflare Pages');
318
}
319
}
320
};
321
```
322
323
## Compatibility Utilities
324
325
### Version Checking Helper
326
327
```typescript
328
import semver from 'semver';
329
330
export function createCompatibilityChecker() {
331
return {
332
checkNuxtVersion(required: string, actual: string): boolean {
333
return semver.satisfies(actual, required);
334
},
335
336
checkBuilderVersion(
337
builderName: string,
338
required: string | false,
339
actual: string
340
): boolean {
341
if (required === false) return false;
342
if (!required) return true;
343
return semver.satisfies(actual, required);
344
},
345
346
formatCompatibilityMessage(
347
moduleName: string,
348
issues: NuxtCompatibilityIssue[]
349
): string {
350
if (issues.length === 0) return '';
351
352
return `
353
Module "${moduleName}" has compatibility issues:
354
${issues.map(issue => `- ${issue.message}`).join('\n')}
355
356
Please check the module documentation for supported versions.
357
`.trim();
358
}
359
};
360
}
361
```
362
363
### Compatibility Warning System
364
365
```typescript
366
export function createCompatibilityWarningSystem(nuxt: Nuxt) {
367
const warnings = new Set<string>();
368
369
return {
370
warn(moduleName: string, message: string) {
371
const key = `${moduleName}:${message}`;
372
if (warnings.has(key)) return;
373
374
warnings.add(key);
375
console.warn(`[${moduleName}] ${message}`);
376
},
377
378
checkAndWarn(
379
moduleName: string,
380
compatibility: NuxtCompatibility,
381
context: {
382
nuxtVersion: string,
383
builderName: string,
384
builderVersion: string
385
}
386
) {
387
const issues = checkCompatibility(
388
compatibility,
389
context.nuxtVersion,
390
context.builderName,
391
context.builderVersion
392
);
393
394
issues.forEach(issue => {
395
this.warn(moduleName, issue.message);
396
});
397
398
return issues.length === 0;
399
}
400
};
401
}
402
```
403
404
The compatibility system ensures that modules work correctly with specific Nuxt versions and build configurations, providing clear error messages and warnings when compatibility issues are detected.