0
# Programmatic API
1
2
The @vercel/ncc programmatic API provides a Node.js interface for integrating ncc into build processes and tools. It offers all CLI features plus additional programmatic options for custom webpack configurations and asset handling.
3
4
## Capabilities
5
6
### Main API Function
7
8
The core ncc function that bundles Node.js modules programmatically.
9
10
```javascript { .api }
11
/**
12
* Compiles a Node.js module into a single file with all dependencies bundled
13
* @param entry - Path to the input file to compile
14
* @param options - Configuration object with build options
15
* @returns Promise resolving to NccResult or NccWatcher when watch: true
16
*/
17
function ncc(entry: string, options?: NccOptions): Promise<NccResult> | NccWatcher;
18
19
interface NccOptions {
20
/** Custom cache path or disable caching */
21
cache?: string | boolean;
22
/** Custom asset emission function */
23
customEmit?: (path: string) => boolean | void;
24
/** Enable ES module output */
25
esm?: boolean;
26
/** External modules to exclude from bundling */
27
externals?: string[] | { [key: string]: string };
28
/** Output filename (default: 'index.js') */
29
filename?: string;
30
/** Enable minification */
31
minify?: boolean;
32
/** Generate source maps */
33
sourceMap?: boolean;
34
/** Include source-map-support */
35
sourceMapRegister?: boolean;
36
/** Source map base prefix */
37
sourceMapBasePrefix?: string;
38
/** Build nested JS assets recursively */
39
assetBuilds?: boolean;
40
/** Enable watch mode */
41
watch?: boolean;
42
/** Enable V8 compile cache */
43
v8cache?: boolean;
44
/** Directory filter for assets */
45
filterAssetBase?: string;
46
/** List of existing asset names */
47
existingAssetNames?: string[];
48
/** Disable build summaries */
49
quiet?: boolean;
50
/** Enable debug logging */
51
debugLog?: boolean;
52
/** Use TypeScript transpile-only mode */
53
transpileOnly?: boolean;
54
/** License file output */
55
license?: string;
56
/** ECMAScript target version */
57
target?: string;
58
/** Production mode */
59
production?: boolean;
60
/** Package.json main fields resolution order */
61
mainFields?: string[];
62
}
63
64
interface NccResult {
65
/** Compiled JavaScript code */
66
code: string;
67
/** Source map JSON string (if enabled) */
68
map?: string;
69
/** Asset files with their content and permissions */
70
assets: { [filename: string]: { source: Buffer | string; permissions: number } };
71
/** Symbolic links mapping */
72
symlinks: { [path: string]: string };
73
/** Webpack compilation statistics */
74
stats: any;
75
}
76
77
interface NccWatcher {
78
/** Set build completion handler */
79
handler(callback: (result: NccResult & { err?: any }) => void): void;
80
/** Set rebuild start handler */
81
rebuild(callback: () => void): void;
82
/** Close the watcher */
83
close(): void;
84
}
85
```
86
87
**Usage Examples:**
88
89
```javascript
90
const ncc = require('@vercel/ncc');
91
92
// Basic compilation
93
const { code, map, assets } = await ncc('/path/to/input.js', {
94
minify: false,
95
sourceMap: false
96
});
97
98
// Write the compiled code
99
require('fs').writeFileSync('dist/index.js', code);
100
101
// With external dependencies
102
const result = await ncc('/path/to/server.js', {
103
externals: ['aws-sdk', 'sharp'],
104
minify: true,
105
sourceMap: true
106
});
107
108
// TypeScript compilation
109
const tsResult = await ncc('/path/to/main.ts', {
110
transpileOnly: false,
111
target: 'es2020'
112
});
113
```
114
115
### Watch Mode API
116
117
When `watch: true` is specified, ncc returns a watcher object instead of a promise.
118
119
```javascript { .api }
120
interface NccWatcher {
121
/**
122
* Set build completion handler
123
* Called whenever a build completes (initial or rebuild)
124
* @param callback - Handler function receiving build result or error
125
*/
126
handler(callback: (result: NccResult & { err?: any }) => void): void;
127
128
/**
129
* Set rebuild start handler
130
* Called when a file change triggers a rebuild
131
* @param callback - Handler function called before rebuild starts
132
*/
133
rebuild(callback: () => void): void;
134
135
/**
136
* Close the watcher
137
* Stops watching and cleans up resources
138
*/
139
close(): void;
140
}
141
```
142
143
**Watch Mode Examples:**
144
145
```javascript
146
const ncc = require('@vercel/ncc');
147
148
// Watch mode
149
const watcher = ncc('/path/to/input.js', {
150
watch: true,
151
minify: false
152
});
153
154
// Handle build completion
155
watcher.handler(({ err, code, assets }) => {
156
if (err) {
157
console.error('Build failed:', err);
158
return;
159
}
160
161
console.log('Build completed successfully');
162
require('fs').writeFileSync('dist/index.js', code);
163
164
// Write assets
165
for (const [filename, asset] of Object.entries(assets)) {
166
require('fs').writeFileSync(`dist/${filename}`, asset.source);
167
}
168
});
169
170
// Handle rebuild start
171
watcher.rebuild(() => {
172
console.log('Rebuilding...');
173
});
174
175
// Close watcher when done
176
process.on('SIGINT', () => {
177
watcher.close();
178
process.exit(0);
179
});
180
```
181
182
### Configuration Options
183
184
#### Cache Options
185
186
```javascript { .api }
187
// Disable caching
188
const result = await ncc('/path/to/input.js', { cache: false });
189
190
// Custom cache directory
191
const result = await ncc('/path/to/input.js', { cache: '/tmp/my-cache' });
192
193
// Default cache (uses system temp directory)
194
const result = await ncc('/path/to/input.js', { cache: true });
195
```
196
197
#### External Dependencies
198
199
```javascript { .api }
200
// Array format
201
const result = await ncc('/path/to/input.js', {
202
externals: ['aws-sdk', 'sharp', 'canvas']
203
});
204
205
// Object format for aliasing
206
const result = await ncc('/path/to/input.js', {
207
externals: {
208
'aws-sdk': 'aws-sdk',
209
'node-gyp': false // exclude completely
210
}
211
});
212
213
// RegExp patterns (as strings in object format)
214
const result = await ncc('/path/to/input.js', {
215
externals: {
216
'/^@aws-sdk\\/.*$/': '@aws-sdk/$1' // RegExp as string
217
}
218
});
219
```
220
221
#### Output Configuration
222
223
```javascript { .api }
224
// ES Module output
225
const result = await ncc('/path/to/input.js', {
226
esm: true,
227
filename: 'index.mjs'
228
});
229
230
// CommonJS output with custom filename
231
const result = await ncc('/path/to/input.js', {
232
esm: false,
233
filename: 'bundle.cjs'
234
});
235
236
// With source maps and minification
237
const result = await ncc('/path/to/input.js', {
238
minify: true,
239
sourceMap: true,
240
sourceMapBasePrefix: '../../'
241
});
242
```
243
244
#### TypeScript Options
245
246
```javascript { .api }
247
// Fast TypeScript compilation (no type checking)
248
const result = await ncc('/path/to/main.ts', {
249
transpileOnly: true,
250
target: 'es2018'
251
});
252
253
// Full TypeScript compilation with type checking
254
const result = await ncc('/path/to/main.ts', {
255
transpileOnly: false,
256
target: 'es2020'
257
});
258
```
259
260
#### Asset Handling
261
262
```javascript { .api }
263
// Recursive asset building
264
const result = await ncc('/path/to/input.js', {
265
assetBuilds: true,
266
filterAssetBase: process.cwd(),
267
existingAssetNames: ['package.json']
268
});
269
270
// Custom asset emission
271
const result = await ncc('/path/to/input.js', {
272
customEmit: (assetPath) => {
273
// Return true to emit asset, false to skip
274
return !assetPath.includes('test');
275
}
276
});
277
```
278
279
### Error Handling
280
281
The ncc function throws errors for various failure conditions:
282
283
```javascript
284
const ncc = require('@vercel/ncc');
285
286
try {
287
const result = await ncc('/path/to/input.js', {
288
target: 'invalid-target' // Will throw error
289
});
290
} catch (error) {
291
if (error.message.includes('Invalid "target" value')) {
292
console.error('Invalid ECMAScript target specified');
293
} else if (error.message.includes('Can\'t resolve')) {
294
console.error('Module resolution failed');
295
} else {
296
console.error('Build failed:', error.message);
297
}
298
}
299
```
300
301
### Integration Examples
302
303
#### Build Tool Integration
304
305
```javascript
306
// Custom build script
307
const ncc = require('@vercel/ncc');
308
const { writeFileSync, mkdirSync } = require('fs');
309
const { join } = require('path');
310
311
async function buildProject(entry, outputDir) {
312
try {
313
const { code, assets, symlinks } = await ncc(entry, {
314
minify: true,
315
sourceMap: true,
316
externals: ['aws-sdk']
317
});
318
319
// Ensure output directory exists
320
mkdirSync(outputDir, { recursive: true });
321
322
// Write main file
323
writeFileSync(join(outputDir, 'index.js'), code);
324
325
// Write assets
326
for (const [filename, asset] of Object.entries(assets)) {
327
writeFileSync(join(outputDir, filename), asset.source);
328
}
329
330
// Create symlinks
331
for (const [linkPath, targetPath] of Object.entries(symlinks)) {
332
require('fs').symlinkSync(targetPath, join(outputDir, linkPath));
333
}
334
335
console.log('Build completed successfully');
336
return true;
337
} catch (error) {
338
console.error('Build failed:', error);
339
return false;
340
}
341
}
342
```
343
344
#### Development Server Integration
345
346
```javascript
347
// Development server with hot reloading
348
const ncc = require('@vercel/ncc');
349
const express = require('express');
350
351
function startDevServer(entry) {
352
const app = express();
353
let currentCode = '';
354
355
const watcher = ncc(entry, {
356
watch: true,
357
sourceMap: true,
358
quiet: true
359
});
360
361
watcher.handler(({ err, code }) => {
362
if (err) {
363
console.error('Build error:', err);
364
return;
365
}
366
currentCode = code;
367
console.log('Code updated');
368
});
369
370
app.get('/bundle.js', (req, res) => {
371
res.type('application/javascript');
372
res.send(currentCode);
373
});
374
375
const server = app.listen(3000, () => {
376
console.log('Dev server running on port 3000');
377
});
378
379
process.on('SIGINT', () => {
380
watcher.close();
381
server.close();
382
process.exit(0);
383
});
384
}
385
```