Starting in Nx version 18, plugins can infer tasks for your projects automatically by analyzing existing tool configuration files. Instead of duplicating build, test, and lint configuration inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/nrwl/nx/llms.txt
Use this file to discover all available pages before exploring further.
project.json, Nx reads it from the source of truth — the tool’s own config file.
This feature is also known as Project Crystal.
How task inference works
Every plugin implements its own inference logic, but all plugins follow the same two-step process:Detect tool configuration in the workspace
The plugin scans the workspace for files associated with a specific tool. For example,
@nx/vite/plugin searches for vite.config.ts (or .js, .mts) files. For each config file found, the plugin creates task configuration for the project that owns that file.Create inferred tasks
The plugin generates one or more named targets based on the tool’s configuration. Target names are determined by the plugin’s options in
nx.json. For example, @nx/vite/plugin creates build, serve, preview, and test targets by default, with cache settings derived from the values in vite.config.ts.What gets inferred
When a plugin infers a task, it configures:| Property | Description |
|---|---|
| Command | How the tool is invoked (e.g., vite build, jest) |
| Cache | Whether results are cached by Nx |
| Inputs | Which files and env vars factor into the cache key |
| Outputs | Which files are stored in and restored from the cache |
| Task dependencies | Which other tasks must complete first (e.g., dependsOn: ["^build"]) |
Example: @nx/vite infers tasks from vite.config.ts
Given a project with avite.config.ts file and the @nx/vite/plugin registered in nx.json:
nx.json
project.json target entries required:
Viewing inferred tasks
To see the full resolved task configuration for a project — including everything inferred by plugins — run:Plugin order and conflict resolution
Plugins are processed in the order they appear in theplugins array in nx.json. If two plugins try to create a target with the same name for the same project, the plugin listed last wins.
For example, if a project has both a vite.config.js and a webpack.config.js, both @nx/vite and @nx/webpack will attempt to create a build target. The one that appears last in plugins takes precedence.
Scoping plugins to specific projects
Useinclude and exclude glob patterns to control which projects a plugin processes:
nx.json
@nx/jest/plugin only infers tasks for projects whose jest.config.ts path matches packages/**/* but not **/*-e2e/**/*.
This is also useful for registering the same plugin twice with different options for different sets of projects.
Overriding inferred task configuration
Inferred configuration is a starting point, not a hard constraint. You can override it at two levels:Override for all projects — use targetDefaults in nx.json
Override for all projects — use targetDefaults in nx.json
nx.json
targetDefaults applies to all projects and overrides inferred configuration for matching target names.Override for a single project — use project.json or package.json
Override for a single project — use project.json or package.json
apps/myapp/project.json
Configuration precedence
From lowest to highest priority:- Inferred task configuration from plugins (registered in
nx.json) targetDefaultsinnx.json- Project-level configuration in
project.jsonorpackage.json
Inferred tasks in existing workspaces
If you upgrade an existing Nx workspace to version 18+, the migration setsuseInferencePlugins: false in nx.json automatically. This preserves the existing behavior — newly generated projects continue to use explicit executor-based targets, and nx add @nx/some-plugin does not register the plugin for inference.
To adopt inferred tasks in an existing repo, follow the migrating to inferred tasks guide.
Even after fully adopting inferred tasks,
project.json remains useful. It is the right place to override inferred options, declare tasks that cannot be inferred from a config file, and define targets that require executor features not available from a plain CLI command.