or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

executors.mdgenerators.mdindex.mdpackage-management.mdplugin-development.mdproject-graph.mdtree-operations.mdutilities.mdworkspace-configuration.md
tile.json

tessl/npm-nx--devkit

The Nx Devkit provides utilities for creating custom generators, executors, and plugins to extend the Nx build system for different technologies and use cases.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@nx/devkit@21.4.x

To install, run

npx @tessl/cli install tessl/npm-nx--devkit@21.4.0

index.mddocs/

Nx Devkit

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.

Package Information

  • Package Name: @nx/devkit
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install @nx/devkit

Core Imports

import {
  Tree,
  generateFiles,
  formatFiles,
  addProjectConfiguration,
  readProjectConfiguration,
  updateProjectConfiguration,
  getProjects,
  runExecutor,
  logger
} from "@nx/devkit";

For CommonJS:

const {
  generateFiles,
  formatFiles,
  addProjectConfiguration,
  readProjectConfiguration,
  updateProjectConfiguration,
  getProjects,
  runExecutor,
  logger
} = require("@nx/devkit");

Basic Usage

import {
  Tree,
  generateFiles,
  formatFiles,
  addProjectConfiguration,
  names,
  offsetFromRoot,
} from "@nx/devkit";
import * as path from "path";

// Example generator that creates a new library
export default async function (tree: Tree, options: { name: string; directory?: string }) {
  const { name, className, fileName } = names(options.name);
  const projectDirectory = options.directory ? `libs/${options.directory}` : `libs/${fileName}`;
  
  // Add project configuration
  addProjectConfiguration(tree, name, {
    root: projectDirectory,
    projectType: "library",
    sourceRoot: `${projectDirectory}/src`,
    targets: {
      build: {
        executor: "@nx/js:tsc",
        outputs: [`{workspaceRoot}/dist/${projectDirectory}`],
        options: {
          main: `${projectDirectory}/src/index.ts`,
          tsConfig: `${projectDirectory}/tsconfig.lib.json`,
        },
      },
    },
  });

  // Generate files from templates
  generateFiles(
    tree,
    path.join(__dirname, "files"),
    projectDirectory,
    {
      ...options,
      ...names(options.name),
      offsetFromRoot: offsetFromRoot(projectDirectory),
      tmpl: "",
    }
  );

  // Format all generated files
  await formatFiles(tree);
}

Architecture

The Nx Devkit is built around several key architectural concepts:

  • Tree-based File System: All file operations use the Tree interface for change tracking and batching
  • Generator/Executor Pattern: Separation of code generation (generators) and task execution (executors)
  • Plugin Architecture: Extensible plugin system with lifecycle hooks for project discovery and dependency creation
  • Project Graph-Centric: Dependency analysis drives intelligent task execution and caching
  • Configuration-driven: Declarative configuration through nx.json and project.json files
  • Task Graph Execution: Intelligent task scheduling based on project dependencies
  • Multi-package Manager Support: Works seamlessly with npm, yarn, and pnpm

Capabilities

File System Operations

Core file system operations using the Tree interface for generators and executors. Provides change tracking, batching, and safe file manipulation.

interface Tree {
  root: string;
  read(filePath: string): Buffer | null;
  read(filePath: string, encoding: BufferEncoding): string | null;
  write(filePath: string, content: Buffer | string): void;
  exists(filePath: string): boolean;
  delete(filePath: string): void;
  rename(from: string, to: string): void;
  listChanges(): FileChange[];
}

interface FileChange {
  path: string;
  type: "CREATE" | "UPDATE" | "DELETE";
  content: Buffer | null;
}

File System Operations

Workspace Configuration

Comprehensive workspace and project configuration management for reading, creating, updating, and organizing Nx workspaces and projects.

function addProjectConfiguration(
  tree: Tree,
  projectName: string,
  projectConfiguration: ProjectConfiguration
): void;

function readProjectConfiguration(
  tree: Tree,
  projectName: string
): ProjectConfiguration;

function updateProjectConfiguration(
  tree: Tree,
  projectName: string,
  projectConfiguration: ProjectConfiguration
): void;

function getProjects(tree: Tree): Map<string, ProjectConfiguration>;

Workspace Configuration

Code Generation

Powerful code generation utilities for creating files from templates, formatting code, and managing project scaffolding with EJS templating support.

function generateFiles(
  tree: Tree,
  srcFolder: string,
  target: string,
  substitutions: { [k: string]: any },
  options?: GenerateFilesOptions
): void;

function formatFiles(
  tree: Tree,
  options?: { sortRootTsconfigPaths?: boolean }
): Promise<void>;

type Generator<T = any> = (
  tree: Tree,
  schema: T
) => void | GeneratorCallback | Promise<void | GeneratorCallback>;

type GeneratorCallback = () => void | Promise<void>;

Code Generation

Task Execution

Task execution system for running executors, parsing targets, and integrating with Nx's task graph for intelligent build orchestration.

function runExecutor<T = any>(
  targetDescription: Target,
  options: T,
  context: ExecutorContext
): Promise<AsyncIterableIterator<any>>;

function parseTargetString(
  targetString: string,
  executorContext: ExecutorContext
): Target;

interface Target {
  project: string;
  target: string;
  configuration?: string;
}

interface ExecutorContext {
  root: string;
  cwd: string;
  workspace: WorkspaceJsonConfiguration;
  isVerbose: boolean;
  projectName?: string;
  targetName?: string;
  configurationName?: string;
}

Task Execution

Package Management

Package management utilities for adding dependencies, managing package.json files, and ensuring required packages are available.

function addDependenciesToPackageJson(
  tree: Tree,
  dependencies: Record<string, string>,
  devDependencies: Record<string, string>,
  packageJsonPath?: string,
  keepExistingVersions?: boolean
): GeneratorCallback;

function ensurePackage<T = any>(pkg: string, version: string): T;

function installPackagesTask(
  tree: Tree,
  alwaysRun?: boolean,
  cwd?: string,
  packageManager?: PackageManager
): void;

Package Management

Project Graph Operations

Project dependency graph operations for analyzing relationships between projects, creating dependency graphs, and understanding workspace structure.

function createProjectGraphAsync(
  opts?: CreateProjectGraphOptions
): Promise<ProjectGraph>;

function readCachedProjectGraph(): ProjectGraph;

interface ProjectGraph {
  nodes: Record<string, ProjectGraphProjectNode>;
  dependencies: Record<string, ProjectGraphDependency[]>;
  externalNodes?: Record<string, ProjectGraphExternalNode>;
}

interface ProjectGraphProjectNode {
  name: string;
  type: ProjectType;
  data: ProjectConfiguration & { files?: ProjectFileMap };
}

Project Graph Operations

Utility Functions

General utility functions for string manipulation, path operations, naming conventions, and workspace layout management.

function names(name: string): {
  name: string;
  className: string;
  propertyName: string;
  constantName: string;
  fileName: string;
};

function offsetFromRoot(fullPathToDir: string): string;

function joinPathFragments(...fragments: string[]): string;

function normalizePath(osSpecificPath: string): string;

function getWorkspaceLayout(tree: Tree): {
  appsDir: string;
  libsDir: string;
  standaloneAsDefault: boolean;
};

function stripIndents(strings: TemplateStringsArray, ...values: any[]): string;

const workspaceRoot: string;

const logger: {
  debug(message: string, ...args: any[]): void;
  info(message: string, ...args: any[]): void;
  warn(message: string, ...args: any[]): void;
  error(message: string, ...args: any[]): void;
  fatal(message: string, ...args: any[]): void;
  log(message: string, ...args: any[]): void;
};

const output: {
  write(str: string): void;
  writeLine(str: string): void;
  addVerticalSeparator(): void;
  addHorizontalSeparator(): void;
  success(message: string): void;
  error(message: string): void;
  warn(message: string): void;
  note(message: string): void;
};

Utility Functions

Plugin Development

Plugin system for extending Nx with custom project discovery, dependency creation, and build integration capabilities.

interface NxPluginV2<TOptions = any> {
  name: string;
  createNodesV2?: CreateNodesV2<TOptions>;
  createDependencies?: CreateDependencies;
  createMetadata?: CreateMetadata;
}

interface CreateNodesV2<T = any> {
  (
    configFiles: string[],
    options: T | undefined,
    context: CreateNodesContextV2
  ): Promise<CreateNodesResultV2>;
}

interface CreateNodesResultV2 {
  projects?: Record<string, CreateNodesResult>;
}

Plugin Development

Task Hashing and Caching

Advanced utilities for task hashing, caching, and performance optimization.

type Hash = string;

interface TaskHasher {
  hashTask(task: Task): Promise<Hash>;
  hashTasks(tasks: Task[]): Promise<Hash[]>;
}

interface Hasher {
  hashFile(path: string): string;
  hashFiles(files: string[]): string;
  hashArray(values: any[]): string;
}

function hashArray(values: any[]): string;

function defaultTasksRunner<T = any>(
  tasks: Task[],
  options: DefaultTasksRunnerOptions,
  context: TasksRunnerContext
): Observable<TaskResult>;

interface DefaultTasksRunnerOptions {
  parallel?: number;
  maxParallel?: number;
  cacheableOperations?: string[];
  cacheDirectory?: string;
  skipNxCache?: boolean;
  captureStderr?: boolean;
  passWithNoTests?: boolean;
  remoteCache?: RemoteCache;
}

interface RemoteCache {
  retrieve: (hash: string, cacheDirectory: string) => Promise<boolean>;
  store: (hash: string, cacheDirectory: string) => Promise<boolean>;
}

interface TasksRunnerContext {
  root: string;
  workspace: WorkspaceJsonConfiguration;
  isVerbose: boolean;
  projectGraph: ProjectGraph;
  target?: string;
}

interface Observable<T> {
  subscribe(observer: (value: T) => void): void;
}

const cacheDir: string;

function isDaemonEnabled(): boolean;

Types

Common Interfaces

interface ProjectConfiguration {
  name?: string;
  root: string;
  sourceRoot?: string;
  projectType?: ProjectType;
  targets?: Record<string, TargetConfiguration>;
  tags?: string[];
  implicitDependencies?: string[];
  generators?: Record<string, any>;
  namedInputs?: Record<string, (string | InputDefinition)[]>;
}

interface TargetConfiguration<T = any> {
  executor?: string;
  options?: T;
  configurations?: Record<string, Partial<T>>;
  defaultConfiguration?: string;
  dependsOn?: TargetDependencyConfig[];
  inputs?: (InputDefinition | string)[];
  outputs?: string[];
}

type ProjectType = "application" | "library";

enum OverwriteStrategy {
  Overwrite = "overwrite",
  KeepExisting = "keepExisting",
  ThrowIfExisting = "throwIfExisting"
}

type PackageManager = "npm" | "yarn" | "pnpm";

Task and Result Types

interface Task {
  id: string;
  target: Target;
  projectRoot?: string;
  overrides: Record<string, any>;
  hash?: string;
  cache?: boolean;
}

interface TaskResult {
  success: boolean;
  task: Task;
  startTime?: number;
  endTime?: number;
  terminalOutput?: string;
  [key: string]: any;
}

interface TaskResults {
  [taskId: string]: TaskResult;
}

interface TaskGraph {
  tasks: Record<string, Task>;
  dependencies: Record<string, string[]>;
  roots: string[];
}

Workspace Configuration Types

interface NxJsonConfiguration<T = "*" | string[]> {
  implicitDependencies?: ImplicitDependencyEntry<T>;
  affected?: NxAffectedConfig;
  workspaceLayout?: {
    appsDir?: string;
    libsDir?: string;
  };
  tasksRunnerOptions?: {
    [tasksRunnerName: string]: {
      runner?: string;
      options?: any;
    };
  };
  targetDefaults?: TargetDefaults;
  namedInputs?: { [inputName: string]: (string | InputDefinition)[] };
  generators?: Record<string, Record<string, any>>;
  cli?: {
    packageManager?: PackageManager;
    defaultCollection?: string;
  };
  plugins?: PluginConfiguration[];
  defaultBase?: string;
}

interface WorkspaceJsonConfiguration extends ProjectsConfigurations {
  version: number;
}

interface ProjectsConfigurations {
  version: number;
  projects: Record<string, ProjectConfiguration>;
}