0
# Builder Detection
1
2
Automatic detection of project frameworks and configuration of appropriate build strategies for Vercel deployments.
3
4
## Capabilities
5
6
### Framework Detection
7
8
#### detectBuilders
9
10
Analyzes project files and configuration to determine appropriate builders and routing configuration.
11
12
```typescript { .api }
13
/**
14
* Detects appropriate builders for project
15
* @param files - Array of file paths in the project
16
* @param pkg - Package.json content (optional)
17
* @param options - Detection options
18
* @returns Promise resolving to detection results
19
*/
20
function detectBuilders(
21
files: string[],
22
pkg?: PackageJson | undefined | null,
23
options?: Options
24
): Promise<{
25
builders: Builder[] | null;
26
errors: ErrorResponse[] | null;
27
warnings: ErrorResponse[];
28
defaultRoutes: Route[] | null;
29
redirectRoutes: Route[] | null;
30
rewriteRoutes: Route[] | null;
31
errorRoutes: Route[] | null;
32
}>;
33
34
interface Options {
35
tag?: 'canary' | 'latest' | string;
36
functions?: BuilderFunctions;
37
ignoreBuildScript?: boolean;
38
projectSettings?: {
39
framework?: string | null;
40
devCommand?: string | null;
41
installCommand?: string | null;
42
buildCommand?: string | null;
43
outputDirectory?: string | null;
44
createdAt?: number;
45
};
46
cleanUrls?: boolean;
47
trailingSlash?: boolean;
48
featHandleMiss?: boolean;
49
}
50
51
interface Builder {
52
use: string;
53
src?: string;
54
config?: Config;
55
}
56
57
interface ErrorResponse {
58
code: string;
59
message: string;
60
action?: string;
61
link?: string;
62
}
63
```
64
65
**Usage Examples:**
66
67
```typescript
68
import { detectBuilders } from "@vercel/build-utils";
69
70
// Basic detection
71
const files = [
72
"package.json",
73
"index.js",
74
"api/users.js",
75
"public/index.html"
76
];
77
78
const packageJson = {
79
name: "my-app",
80
scripts: {
81
build: "npm run build:next",
82
start: "next start"
83
},
84
dependencies: {
85
next: "13.0.0",
86
react: "18.0.0"
87
}
88
};
89
90
const result = await detectBuilders(files, packageJson);
91
92
if (result.errors) {
93
console.error("Detection errors:", result.errors);
94
} else {
95
console.log("Detected builders:", result.builders);
96
console.log("Default routes:", result.defaultRoutes);
97
}
98
99
// Detection with custom options
100
const customResult = await detectBuilders(files, packageJson, {
101
tag: "canary",
102
functions: {
103
"api/*.js": {
104
memory: 512,
105
maxDuration: 30
106
}
107
},
108
projectSettings: {
109
framework: "nextjs",
110
outputDirectory: "dist",
111
buildCommand: "npm run build"
112
},
113
cleanUrls: true,
114
trailingSlash: false
115
});
116
117
// Detection with framework override
118
const frameworkResult = await detectBuilders(files, packageJson, {
119
projectSettings: {
120
framework: "nuxtjs", // Force specific framework
121
buildCommand: "npm run generate"
122
}
123
});
124
```
125
126
#### detectFramework
127
128
Detects the framework used by the project based on file patterns and dependencies.
129
130
```typescript { .api }
131
/**
132
* Detects project framework
133
* @param options - Framework detection options
134
* @returns Promise resolving to detected framework or null
135
*/
136
function detectFramework(options: DetectFrameworkOptions): Promise<Framework | null>;
137
138
interface DetectFrameworkOptions {
139
fs: DetectorFilesystem;
140
frameworkList: Framework[];
141
}
142
143
interface Framework {
144
slug: string;
145
name: string;
146
logo?: string;
147
description?: string;
148
settings?: {
149
installCommand?: string;
150
buildCommand?: string;
151
devCommand?: string;
152
outputDirectory?: string;
153
};
154
detectors?: {
155
every?: FrameworkDetectionItem[];
156
some?: FrameworkDetectionItem[];
157
};
158
}
159
160
interface FrameworkDetectionItem {
161
path: string;
162
matchContent?: string;
163
}
164
```
165
166
**Usage Examples:**
167
168
```typescript
169
import { detectFramework, DetectorFilesystem } from "@vercel/build-utils";
170
171
// Create filesystem interface
172
const fs = new DetectorFilesystem("/project");
173
174
// Detect framework
175
const framework = await detectFramework({
176
fs,
177
frameworkList: [] // Usually provided by @vercel/frameworks
178
});
179
180
if (framework) {
181
console.log(`Detected framework: ${framework.name}`);
182
console.log(`Build command: ${framework.settings?.buildCommand}`);
183
console.log(`Output directory: ${framework.settings?.outputDirectory}`);
184
}
185
```
186
187
### Directory and File Detection
188
189
#### detectOutputDirectory
190
191
Detects the output directory from builder configuration.
192
193
```typescript { .api }
194
/**
195
* Detects output directory from builders
196
* @param builders - Array of detected builders
197
* @returns Output directory path or null
198
*/
199
function detectOutputDirectory(builders: Builder[]): string | null;
200
```
201
202
**Usage Examples:**
203
204
```typescript
205
import { detectOutputDirectory } from "@vercel/build-utils";
206
207
const builders = [
208
{
209
use: "@vercel/static",
210
src: "dist/**/*",
211
config: { zeroConfig: true }
212
}
213
];
214
215
const outputDir = detectOutputDirectory(builders);
216
console.log(`Output directory: ${outputDir}`); // "dist"
217
```
218
219
#### detectApiDirectory
220
221
Detects the API directory from builder configuration.
222
223
```typescript { .api }
224
/**
225
* Detects API directory from builders
226
* @param builders - Array of detected builders
227
* @returns API directory path or null
228
*/
229
function detectApiDirectory(builders: Builder[]): string | null;
230
```
231
232
**Usage Examples:**
233
234
```typescript
235
import { detectApiDirectory } from "@vercel/build-utils";
236
237
const builders = [
238
{
239
use: "@vercel/node",
240
src: "api/*.js",
241
config: { zeroConfig: true }
242
}
243
];
244
245
const apiDir = detectApiDirectory(builders);
246
console.log(`API directory: ${apiDir}`); // "api"
247
```
248
249
#### detectApiExtensions
250
251
Detects API file extensions from builder configuration.
252
253
```typescript { .api }
254
/**
255
* Detects API file extensions
256
* @param builders - Array of detected builders
257
* @returns Set of file extensions
258
*/
259
function detectApiExtensions(builders: Builder[]): Set<string>;
260
```
261
262
**Usage Examples:**
263
264
```typescript
265
import { detectApiExtensions } from "@vercel/build-utils";
266
267
const builders = [
268
{
269
use: "@vercel/node",
270
src: "api/*.js",
271
config: { zeroConfig: true }
272
},
273
{
274
use: "@vercel/python",
275
src: "api/*.py",
276
config: { zeroConfig: true }
277
}
278
];
279
280
const extensions = detectApiExtensions(builders);
281
console.log([...extensions]); // [".js", ".py"]
282
```
283
284
### DetectorFilesystem
285
286
Filesystem abstraction for framework detection.
287
288
```typescript { .api }
289
/**
290
* Filesystem abstraction for detection
291
*/
292
class DetectorFilesystem {
293
constructor(basePath: string);
294
295
/**
296
* Check if path exists
297
* @param path - File or directory path
298
* @returns Promise resolving to true if path exists
299
*/
300
hasPath(path: string): Promise<boolean>;
301
302
/**
303
* Check if path is a file
304
* @param path - Path to check
305
* @returns Promise resolving to true if path is a file
306
*/
307
isFile(path: string): Promise<boolean>;
308
309
/**
310
* Read file content
311
* @param path - File path
312
* @returns Promise resolving to file content
313
*/
314
readFile(path: string): Promise<Buffer>;
315
}
316
```
317
318
**Usage Examples:**
319
320
```typescript
321
import { DetectorFilesystem } from "@vercel/build-utils";
322
323
const fs = new DetectorFilesystem("/project");
324
325
// Check if Next.js config exists
326
const hasNextConfig = await fs.hasPath("next.config.js");
327
328
// Read package.json
329
if (await fs.isFile("package.json")) {
330
const packageContent = await fs.readFile("package.json");
331
const pkg = JSON.parse(packageContent.toString());
332
console.log("Dependencies:", pkg.dependencies);
333
}
334
335
// Check for various framework indicators
336
const frameworkFiles = [
337
"next.config.js",
338
"nuxt.config.js",
339
"gatsby-config.js",
340
"vue.config.js"
341
];
342
343
for (const file of frameworkFiles) {
344
if (await fs.hasPath(file)) {
345
console.log(`Found ${file} - framework detected`);
346
}
347
}
348
```
349
350
## Builder Types
351
352
Common builder types returned by detection:
353
354
### Static Builders
355
- `@vercel/static` - Static files
356
- `@vercel/static-build` - Static site generators
357
358
### Runtime Builders
359
- `@vercel/node` - Node.js functions
360
- `@vercel/python` - Python functions
361
- `@vercel/go` - Go functions
362
- `@vercel/ruby` - Ruby functions
363
364
### Framework Builders
365
- `@vercel/next` - Next.js applications
366
- `@vercel/nuxt` - Nuxt.js applications
367
- `@vercel/gatsby` - Gatsby applications
368
- `@vercel/vue` - Vue.js applications
369
- `@vercel/angular` - Angular applications
370
371
## Route Configuration
372
373
Detection results include routing configuration:
374
375
```typescript
376
// Example detection result
377
{
378
builders: [
379
{
380
use: "@vercel/next",
381
src: "package.json"
382
}
383
],
384
defaultRoutes: [
385
{
386
src: "/(.*)",
387
dest: "/$1"
388
}
389
],
390
redirectRoutes: null,
391
rewriteRoutes: null,
392
errorRoutes: null,
393
errors: null,
394
warnings: []
395
}
396
```
397
398
## Error Handling
399
400
Detection errors are returned in the result object:
401
402
```typescript
403
const result = await detectBuilders(files, pkg);
404
405
if (result.errors) {
406
for (const error of result.errors) {
407
console.error(`${error.code}: ${error.message}`);
408
if (error.link) {
409
console.error(`See: ${error.link}`);
410
}
411
}
412
}
413
414
if (result.warnings.length > 0) {
415
console.warn("Warnings:", result.warnings);
416
}
417
```