The Nx Devkit provides utilities for creating custom generators, executors, and plugins to extend the Nx build system for different technologies and use cases.
npx @tessl/cli install tessl/npm-nx--devkit@21.4.00
# Nx Devkit
1
2
The Nx Devkit is a comprehensive toolkit for customizing and extending the Nx build system. It provides utilities for creating custom generators that scaffold new code and configurations, building executors that define how tasks are run, and managing workspace configurations programmatically. The devkit includes functions for file system operations, Abstract Syntax Tree (AST) manipulation, workspace and project configuration management, and integration with Nx's task scheduling and caching systems.
3
4
## Package Information
5
6
- **Package Name**: @nx/devkit
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @nx/devkit`
10
11
## Core Imports
12
13
```typescript
14
import {
15
Tree,
16
generateFiles,
17
formatFiles,
18
addProjectConfiguration,
19
readProjectConfiguration,
20
updateProjectConfiguration,
21
getProjects,
22
runExecutor,
23
logger
24
} from "@nx/devkit";
25
```
26
27
For CommonJS:
28
29
```javascript
30
const {
31
generateFiles,
32
formatFiles,
33
addProjectConfiguration,
34
readProjectConfiguration,
35
updateProjectConfiguration,
36
getProjects,
37
runExecutor,
38
logger
39
} = require("@nx/devkit");
40
```
41
42
## Basic Usage
43
44
```typescript
45
import {
46
Tree,
47
generateFiles,
48
formatFiles,
49
addProjectConfiguration,
50
names,
51
offsetFromRoot,
52
} from "@nx/devkit";
53
import * as path from "path";
54
55
// Example generator that creates a new library
56
export default async function (tree: Tree, options: { name: string; directory?: string }) {
57
const { name, className, fileName } = names(options.name);
58
const projectDirectory = options.directory ? `libs/${options.directory}` : `libs/${fileName}`;
59
60
// Add project configuration
61
addProjectConfiguration(tree, name, {
62
root: projectDirectory,
63
projectType: "library",
64
sourceRoot: `${projectDirectory}/src`,
65
targets: {
66
build: {
67
executor: "@nx/js:tsc",
68
outputs: [`{workspaceRoot}/dist/${projectDirectory}`],
69
options: {
70
main: `${projectDirectory}/src/index.ts`,
71
tsConfig: `${projectDirectory}/tsconfig.lib.json`,
72
},
73
},
74
},
75
});
76
77
// Generate files from templates
78
generateFiles(
79
tree,
80
path.join(__dirname, "files"),
81
projectDirectory,
82
{
83
...options,
84
...names(options.name),
85
offsetFromRoot: offsetFromRoot(projectDirectory),
86
tmpl: "",
87
}
88
);
89
90
// Format all generated files
91
await formatFiles(tree);
92
}
93
```
94
95
## Architecture
96
97
The Nx Devkit is built around several key architectural concepts:
98
99
- **Tree-based File System**: All file operations use the `Tree` interface for change tracking and batching
100
- **Generator/Executor Pattern**: Separation of code generation (generators) and task execution (executors)
101
- **Plugin Architecture**: Extensible plugin system with lifecycle hooks for project discovery and dependency creation
102
- **Project Graph-Centric**: Dependency analysis drives intelligent task execution and caching
103
- **Configuration-driven**: Declarative configuration through nx.json and project.json files
104
- **Task Graph Execution**: Intelligent task scheduling based on project dependencies
105
- **Multi-package Manager Support**: Works seamlessly with npm, yarn, and pnpm
106
107
## Capabilities
108
109
### File System Operations
110
111
Core file system operations using the Tree interface for generators and executors. Provides change tracking, batching, and safe file manipulation.
112
113
```typescript { .api }
114
interface Tree {
115
root: string;
116
read(filePath: string): Buffer | null;
117
read(filePath: string, encoding: BufferEncoding): string | null;
118
write(filePath: string, content: Buffer | string): void;
119
exists(filePath: string): boolean;
120
delete(filePath: string): void;
121
rename(from: string, to: string): void;
122
listChanges(): FileChange[];
123
}
124
125
interface FileChange {
126
path: string;
127
type: "CREATE" | "UPDATE" | "DELETE";
128
content: Buffer | null;
129
}
130
```
131
132
[File System Operations](./tree-operations.md)
133
134
### Workspace Configuration
135
136
Comprehensive workspace and project configuration management for reading, creating, updating, and organizing Nx workspaces and projects.
137
138
```typescript { .api }
139
function addProjectConfiguration(
140
tree: Tree,
141
projectName: string,
142
projectConfiguration: ProjectConfiguration
143
): void;
144
145
function readProjectConfiguration(
146
tree: Tree,
147
projectName: string
148
): ProjectConfiguration;
149
150
function updateProjectConfiguration(
151
tree: Tree,
152
projectName: string,
153
projectConfiguration: ProjectConfiguration
154
): void;
155
156
function getProjects(tree: Tree): Map<string, ProjectConfiguration>;
157
```
158
159
[Workspace Configuration](./workspace-configuration.md)
160
161
### Code Generation
162
163
Powerful code generation utilities for creating files from templates, formatting code, and managing project scaffolding with EJS templating support.
164
165
```typescript { .api }
166
function generateFiles(
167
tree: Tree,
168
srcFolder: string,
169
target: string,
170
substitutions: { [k: string]: any },
171
options?: GenerateFilesOptions
172
): void;
173
174
function formatFiles(
175
tree: Tree,
176
options?: { sortRootTsconfigPaths?: boolean }
177
): Promise<void>;
178
179
type Generator<T = any> = (
180
tree: Tree,
181
schema: T
182
) => void | GeneratorCallback | Promise<void | GeneratorCallback>;
183
184
type GeneratorCallback = () => void | Promise<void>;
185
```
186
187
[Code Generation](./generators.md)
188
189
### Task Execution
190
191
Task execution system for running executors, parsing targets, and integrating with Nx's task graph for intelligent build orchestration.
192
193
```typescript { .api }
194
function runExecutor<T = any>(
195
targetDescription: Target,
196
options: T,
197
context: ExecutorContext
198
): Promise<AsyncIterableIterator<any>>;
199
200
function parseTargetString(
201
targetString: string,
202
executorContext: ExecutorContext
203
): Target;
204
205
interface Target {
206
project: string;
207
target: string;
208
configuration?: string;
209
}
210
211
interface ExecutorContext {
212
root: string;
213
cwd: string;
214
workspace: WorkspaceJsonConfiguration;
215
isVerbose: boolean;
216
projectName?: string;
217
targetName?: string;
218
configurationName?: string;
219
}
220
```
221
222
[Task Execution](./executors.md)
223
224
### Package Management
225
226
Package management utilities for adding dependencies, managing package.json files, and ensuring required packages are available.
227
228
```typescript { .api }
229
function addDependenciesToPackageJson(
230
tree: Tree,
231
dependencies: Record<string, string>,
232
devDependencies: Record<string, string>,
233
packageJsonPath?: string,
234
keepExistingVersions?: boolean
235
): GeneratorCallback;
236
237
function ensurePackage<T = any>(pkg: string, version: string): T;
238
239
function installPackagesTask(
240
tree: Tree,
241
alwaysRun?: boolean,
242
cwd?: string,
243
packageManager?: PackageManager
244
): void;
245
```
246
247
[Package Management](./package-management.md)
248
249
### Project Graph Operations
250
251
Project dependency graph operations for analyzing relationships between projects, creating dependency graphs, and understanding workspace structure.
252
253
```typescript { .api }
254
function createProjectGraphAsync(
255
opts?: CreateProjectGraphOptions
256
): Promise<ProjectGraph>;
257
258
function readCachedProjectGraph(): ProjectGraph;
259
260
interface ProjectGraph {
261
nodes: Record<string, ProjectGraphProjectNode>;
262
dependencies: Record<string, ProjectGraphDependency[]>;
263
externalNodes?: Record<string, ProjectGraphExternalNode>;
264
}
265
266
interface ProjectGraphProjectNode {
267
name: string;
268
type: ProjectType;
269
data: ProjectConfiguration & { files?: ProjectFileMap };
270
}
271
```
272
273
[Project Graph Operations](./project-graph.md)
274
275
### Utility Functions
276
277
General utility functions for string manipulation, path operations, naming conventions, and workspace layout management.
278
279
```typescript { .api }
280
function names(name: string): {
281
name: string;
282
className: string;
283
propertyName: string;
284
constantName: string;
285
fileName: string;
286
};
287
288
function offsetFromRoot(fullPathToDir: string): string;
289
290
function joinPathFragments(...fragments: string[]): string;
291
292
function normalizePath(osSpecificPath: string): string;
293
294
function getWorkspaceLayout(tree: Tree): {
295
appsDir: string;
296
libsDir: string;
297
standaloneAsDefault: boolean;
298
};
299
300
function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;
301
302
const workspaceRoot: string;
303
304
const logger: {
305
debug(message: string, ...args: any[]): void;
306
info(message: string, ...args: any[]): void;
307
warn(message: string, ...args: any[]): void;
308
error(message: string, ...args: any[]): void;
309
fatal(message: string, ...args: any[]): void;
310
log(message: string, ...args: any[]): void;
311
};
312
313
const output: {
314
write(str: string): void;
315
writeLine(str: string): void;
316
addVerticalSeparator(): void;
317
addHorizontalSeparator(): void;
318
success(message: string): void;
319
error(message: string): void;
320
warn(message: string): void;
321
note(message: string): void;
322
};
323
```
324
325
[Utility Functions](./utilities.md)
326
327
### Plugin Development
328
329
Plugin system for extending Nx with custom project discovery, dependency creation, and build integration capabilities.
330
331
```typescript { .api }
332
interface NxPluginV2<TOptions = any> {
333
name: string;
334
createNodesV2?: CreateNodesV2<TOptions>;
335
createDependencies?: CreateDependencies;
336
createMetadata?: CreateMetadata;
337
}
338
339
interface CreateNodesV2<T = any> {
340
(
341
configFiles: string[],
342
options: T | undefined,
343
context: CreateNodesContextV2
344
): Promise<CreateNodesResultV2>;
345
}
346
347
interface CreateNodesResultV2 {
348
projects?: Record<string, CreateNodesResult>;
349
}
350
```
351
352
[Plugin Development](./plugin-development.md)
353
354
### Task Hashing and Caching
355
356
Advanced utilities for task hashing, caching, and performance optimization.
357
358
```typescript { .api }
359
type Hash = string;
360
361
interface TaskHasher {
362
hashTask(task: Task): Promise<Hash>;
363
hashTasks(tasks: Task[]): Promise<Hash[]>;
364
}
365
366
interface Hasher {
367
hashFile(path: string): string;
368
hashFiles(files: string[]): string;
369
hashArray(values: any[]): string;
370
}
371
372
function hashArray(values: any[]): string;
373
374
function defaultTasksRunner<T = any>(
375
tasks: Task[],
376
options: DefaultTasksRunnerOptions,
377
context: TasksRunnerContext
378
): Observable<TaskResult>;
379
380
interface DefaultTasksRunnerOptions {
381
parallel?: number;
382
maxParallel?: number;
383
cacheableOperations?: string[];
384
cacheDirectory?: string;
385
skipNxCache?: boolean;
386
captureStderr?: boolean;
387
passWithNoTests?: boolean;
388
remoteCache?: RemoteCache;
389
}
390
391
interface RemoteCache {
392
retrieve: (hash: string, cacheDirectory: string) => Promise<boolean>;
393
store: (hash: string, cacheDirectory: string) => Promise<boolean>;
394
}
395
396
interface TasksRunnerContext {
397
root: string;
398
workspace: WorkspaceJsonConfiguration;
399
isVerbose: boolean;
400
projectGraph: ProjectGraph;
401
target?: string;
402
}
403
404
interface Observable<T> {
405
subscribe(observer: (value: T) => void): void;
406
}
407
408
const cacheDir: string;
409
410
function isDaemonEnabled(): boolean;
411
```
412
413
## Types
414
415
### Common Interfaces
416
417
```typescript { .api }
418
interface ProjectConfiguration {
419
name?: string;
420
root: string;
421
sourceRoot?: string;
422
projectType?: ProjectType;
423
targets?: Record<string, TargetConfiguration>;
424
tags?: string[];
425
implicitDependencies?: string[];
426
generators?: Record<string, any>;
427
namedInputs?: Record<string, (string | InputDefinition)[]>;
428
}
429
430
interface TargetConfiguration<T = any> {
431
executor?: string;
432
options?: T;
433
configurations?: Record<string, Partial<T>>;
434
defaultConfiguration?: string;
435
dependsOn?: TargetDependencyConfig[];
436
inputs?: (InputDefinition | string)[];
437
outputs?: string[];
438
}
439
440
type ProjectType = "application" | "library";
441
442
enum OverwriteStrategy {
443
Overwrite = "overwrite",
444
KeepExisting = "keepExisting",
445
ThrowIfExisting = "throwIfExisting"
446
}
447
448
type PackageManager = "npm" | "yarn" | "pnpm";
449
```
450
451
### Task and Result Types
452
453
```typescript { .api }
454
interface Task {
455
id: string;
456
target: Target;
457
projectRoot?: string;
458
overrides: Record<string, any>;
459
hash?: string;
460
cache?: boolean;
461
}
462
463
interface TaskResult {
464
success: boolean;
465
task: Task;
466
startTime?: number;
467
endTime?: number;
468
terminalOutput?: string;
469
[key: string]: any;
470
}
471
472
interface TaskResults {
473
[taskId: string]: TaskResult;
474
}
475
476
interface TaskGraph {
477
tasks: Record<string, Task>;
478
dependencies: Record<string, string[]>;
479
roots: string[];
480
}
481
```
482
483
### Workspace Configuration Types
484
485
```typescript { .api }
486
interface NxJsonConfiguration<T = "*" | string[]> {
487
implicitDependencies?: ImplicitDependencyEntry<T>;
488
affected?: NxAffectedConfig;
489
workspaceLayout?: {
490
appsDir?: string;
491
libsDir?: string;
492
};
493
tasksRunnerOptions?: {
494
[tasksRunnerName: string]: {
495
runner?: string;
496
options?: any;
497
};
498
};
499
targetDefaults?: TargetDefaults;
500
namedInputs?: { [inputName: string]: (string | InputDefinition)[] };
501
generators?: Record<string, Record<string, any>>;
502
cli?: {
503
packageManager?: PackageManager;
504
defaultCollection?: string;
505
};
506
plugins?: PluginConfiguration[];
507
defaultBase?: string;
508
}
509
510
interface WorkspaceJsonConfiguration extends ProjectsConfigurations {
511
version: number;
512
}
513
514
interface ProjectsConfigurations {
515
version: number;
516
projects: Record<string, ProjectConfiguration>;
517
}
518
```