Skip to main content
Executors are functions that run a task — a build, a test run, a deployment step, or anything else that can be scripted. Defining a task as an executor gives you:
  • Schema validation for options, with --help output in the terminal.
  • Nx caching — Nx can cache executor outputs and replay them on cache hits.
  • Composability — executors can invoke other executors via runExecutor.
  • Nx Console integration — options are rendered as a form in the editor.

Creating an executor

1

Add the plugin package if you don't have one yet

2

Scaffold a new executor

This creates the following files:

Defining the schema

schema.json describes the options your executor accepts:
The TypeScript interface in schema.d.ts mirrors the JSON schema:

Executor function signature

Every executor exports a default async function that receives the resolved options and an ExecutorContext. It must return Promise<{ success: boolean }>.

Accessing project information via context

The ExecutorContext object contains the full project graph and the name of the project and target being run:

Registering an executor in project.json

Add the executor to the relevant project’s targets block in project.json:
Use the name field from tools/my-plugin/package.json when referencing your plugin — not the folder path.
Then run the executor:
Expected output:

Composing executors with runExecutor

Executors can invoke other executors. This is useful when a task is a combination of multiple steps:

Custom hashers

By default, Nx hashes all files in a project to determine cache validity. If your executor only depends on a subset of files, or on external data not in the project, you can provide a custom hasher. Generate an executor with a hasher included:
Or add a hasher manually by creating hasher.ts and registering it in executors.json:
The hasher receives the full Task and a HasherContext:
A custom hasher replaces the default hashing — it does not extend it. If the hash never changes, every run of that target will be a cache hit. Make sure all inputs that affect the executor’s output are included in your hash.

Key devkit utilities for executors