Build utilities for Vercel platform builders and serverless functions, providing utilities for creating and managing Lambda functions, file operations, and build-time helpers for the Vercel deployment platform
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Automatic detection of project frameworks and configuration of appropriate build strategies for Vercel deployments.
Analyzes project files and configuration to determine appropriate builders and routing configuration.
/**
* Detects appropriate builders for project
* @param files - Array of file paths in the project
* @param pkg - Package.json content (optional)
* @param options - Detection options
* @returns Promise resolving to detection results
*/
function detectBuilders(
files: string[],
pkg?: PackageJson | undefined | null,
options?: Options
): Promise<{
builders: Builder[] | null;
errors: ErrorResponse[] | null;
warnings: ErrorResponse[];
defaultRoutes: Route[] | null;
redirectRoutes: Route[] | null;
rewriteRoutes: Route[] | null;
errorRoutes: Route[] | null;
}>;
interface Options {
tag?: 'canary' | 'latest' | string;
functions?: BuilderFunctions;
ignoreBuildScript?: boolean;
projectSettings?: {
framework?: string | null;
devCommand?: string | null;
installCommand?: string | null;
buildCommand?: string | null;
outputDirectory?: string | null;
createdAt?: number;
};
cleanUrls?: boolean;
trailingSlash?: boolean;
featHandleMiss?: boolean;
}
interface Builder {
use: string;
src?: string;
config?: Config;
}
interface ErrorResponse {
code: string;
message: string;
action?: string;
link?: string;
}Usage Examples:
import { detectBuilders } from "@vercel/build-utils";
// Basic detection
const files = [
"package.json",
"index.js",
"api/users.js",
"public/index.html"
];
const packageJson = {
name: "my-app",
scripts: {
build: "npm run build:next",
start: "next start"
},
dependencies: {
next: "13.0.0",
react: "18.0.0"
}
};
const result = await detectBuilders(files, packageJson);
if (result.errors) {
console.error("Detection errors:", result.errors);
} else {
console.log("Detected builders:", result.builders);
console.log("Default routes:", result.defaultRoutes);
}
// Detection with custom options
const customResult = await detectBuilders(files, packageJson, {
tag: "canary",
functions: {
"api/*.js": {
memory: 512,
maxDuration: 30
}
},
projectSettings: {
framework: "nextjs",
outputDirectory: "dist",
buildCommand: "npm run build"
},
cleanUrls: true,
trailingSlash: false
});
// Detection with framework override
const frameworkResult = await detectBuilders(files, packageJson, {
projectSettings: {
framework: "nuxtjs", // Force specific framework
buildCommand: "npm run generate"
}
});Detects the framework used by the project based on file patterns and dependencies.
/**
* Detects project framework
* @param options - Framework detection options
* @returns Promise resolving to detected framework or null
*/
function detectFramework(options: DetectFrameworkOptions): Promise<Framework | null>;
interface DetectFrameworkOptions {
fs: DetectorFilesystem;
frameworkList: Framework[];
}
interface Framework {
slug: string;
name: string;
logo?: string;
description?: string;
settings?: {
installCommand?: string;
buildCommand?: string;
devCommand?: string;
outputDirectory?: string;
};
detectors?: {
every?: FrameworkDetectionItem[];
some?: FrameworkDetectionItem[];
};
}
interface FrameworkDetectionItem {
path: string;
matchContent?: string;
}Usage Examples:
import { detectFramework, DetectorFilesystem } from "@vercel/build-utils";
// Create filesystem interface
const fs = new DetectorFilesystem("/project");
// Detect framework
const framework = await detectFramework({
fs,
frameworkList: [] // Usually provided by @vercel/frameworks
});
if (framework) {
console.log(`Detected framework: ${framework.name}`);
console.log(`Build command: ${framework.settings?.buildCommand}`);
console.log(`Output directory: ${framework.settings?.outputDirectory}`);
}Detects the output directory from builder configuration.
/**
* Detects output directory from builders
* @param builders - Array of detected builders
* @returns Output directory path or null
*/
function detectOutputDirectory(builders: Builder[]): string | null;Usage Examples:
import { detectOutputDirectory } from "@vercel/build-utils";
const builders = [
{
use: "@vercel/static",
src: "dist/**/*",
config: { zeroConfig: true }
}
];
const outputDir = detectOutputDirectory(builders);
console.log(`Output directory: ${outputDir}`); // "dist"Detects the API directory from builder configuration.
/**
* Detects API directory from builders
* @param builders - Array of detected builders
* @returns API directory path or null
*/
function detectApiDirectory(builders: Builder[]): string | null;Usage Examples:
import { detectApiDirectory } from "@vercel/build-utils";
const builders = [
{
use: "@vercel/node",
src: "api/*.js",
config: { zeroConfig: true }
}
];
const apiDir = detectApiDirectory(builders);
console.log(`API directory: ${apiDir}`); // "api"Detects API file extensions from builder configuration.
/**
* Detects API file extensions
* @param builders - Array of detected builders
* @returns Set of file extensions
*/
function detectApiExtensions(builders: Builder[]): Set<string>;Usage Examples:
import { detectApiExtensions } from "@vercel/build-utils";
const builders = [
{
use: "@vercel/node",
src: "api/*.js",
config: { zeroConfig: true }
},
{
use: "@vercel/python",
src: "api/*.py",
config: { zeroConfig: true }
}
];
const extensions = detectApiExtensions(builders);
console.log([...extensions]); // [".js", ".py"]Filesystem abstraction for framework detection.
/**
* Filesystem abstraction for detection
*/
class DetectorFilesystem {
constructor(basePath: string);
/**
* Check if path exists
* @param path - File or directory path
* @returns Promise resolving to true if path exists
*/
hasPath(path: string): Promise<boolean>;
/**
* Check if path is a file
* @param path - Path to check
* @returns Promise resolving to true if path is a file
*/
isFile(path: string): Promise<boolean>;
/**
* Read file content
* @param path - File path
* @returns Promise resolving to file content
*/
readFile(path: string): Promise<Buffer>;
}Usage Examples:
import { DetectorFilesystem } from "@vercel/build-utils";
const fs = new DetectorFilesystem("/project");
// Check if Next.js config exists
const hasNextConfig = await fs.hasPath("next.config.js");
// Read package.json
if (await fs.isFile("package.json")) {
const packageContent = await fs.readFile("package.json");
const pkg = JSON.parse(packageContent.toString());
console.log("Dependencies:", pkg.dependencies);
}
// Check for various framework indicators
const frameworkFiles = [
"next.config.js",
"nuxt.config.js",
"gatsby-config.js",
"vue.config.js"
];
for (const file of frameworkFiles) {
if (await fs.hasPath(file)) {
console.log(`Found ${file} - framework detected`);
}
}Common builder types returned by detection:
@vercel/static - Static files@vercel/static-build - Static site generators@vercel/node - Node.js functions@vercel/python - Python functions@vercel/go - Go functions@vercel/ruby - Ruby functions@vercel/next - Next.js applications@vercel/nuxt - Nuxt.js applications@vercel/gatsby - Gatsby applications@vercel/vue - Vue.js applications@vercel/angular - Angular applicationsDetection results include routing configuration:
// Example detection result
{
builders: [
{
use: "@vercel/next",
src: "package.json"
}
],
defaultRoutes: [
{
src: "/(.*)",
dest: "/$1"
}
],
redirectRoutes: null,
rewriteRoutes: null,
errorRoutes: null,
errors: null,
warnings: []
}Detection errors are returned in the result object:
const result = await detectBuilders(files, pkg);
if (result.errors) {
for (const error of result.errors) {
console.error(`${error.code}: ${error.message}`);
if (error.link) {
console.error(`See: ${error.link}`);
}
}
}
if (result.warnings.length > 0) {
console.warn("Warnings:", result.warnings);
}Install with Tessl CLI
npx tessl i tessl/npm-vercel--build-utils