Nx brings smart task execution and caching to your .NET monorepo. .NET is a free, cross-platform, open-source developer platform for building many different types of applications. With .NET, you can use multiple languages, editors, and libraries to build for web, mobile, desktop, games, IoT, and more.
The Nx plugin for .NET registers .NET projects in your Nx workspace. It allows MSBuild tasks to be run through Nx. Nx effortlessly makes your CI faster.
Nx adds the following features to your workspace:
- Cache task results
- Distribute task execution
- Run only tasks affected by a PR
- Interactively explore your workspace
Setup @nx/dotnet
Section titled “Setup @nx/dotnet”Install Nx
Section titled “Install Nx”You can install Nx globally. Depending on your package manager, use one of the following commands:
npm add --global nx@latestbrew install nxchoco install nxsudo add-apt-repository ppa:nrwl/nxsudo apt updatesudo apt install nxAdd Nx to a .NET workspace
Section titled “Add Nx to a .NET workspace”In any .NET workspace, run the following command to add Nx and the @nx/dotnet plugin:
nx initThen, you can run .NET tasks using Nx. For example:
nx build <your dotnet project>Add .NET to an existing Nx workspace
Section titled “Add .NET to an existing Nx workspace”If you already have an Nx workspace set up, you can add the @nx/dotnet plugin by running the following command:
nx add @nx/dotnetNew projects can be created with the dotnet new CLI command, or any other method you may be familiar with. For example:
dotnet new webapi -o ./apps/my-apiFull project creation docs can be found here on the official Microsoft documentation.
How @nx/dotnet infers tasks
Section titled “How @nx/dotnet infers tasks”The @nx/dotnet plugin uses MSBuild to analyze your .NET solution and project structure. When using nx add, the plugin is automatically configured in your nx.json file.
The plugin automatically detects .NET projects by scanning for the following project file patterns:
**/*.csproj(C# projects)**/*.fsproj(F# projects)**/*.vbproj(Visual Basic projects)
The plugin analyzes your MSBuild project files to determine:
- Project dependencies (via
<ProjectReference>elements) - Available build targets (build, test, clean, etc.)
- Project outputs and configuration
What counts as an input
Section titled “What counts as an input”Every cacheable target hashes the project's own files, the outputs of the projects it depends on, and the files MSBuild read from outside the project directory while evaluating it:
- The nearest
Directory.Build.props,Directory.Build.targets,Directory.Build.rsp,Directory.Solution.props,Directory.Solution.targets,Directory.Packages.props, andglobal.jsonabove the project. - Every
nuget.configand.editorconfigbetween the project and the workspace root, since NuGet and the analyzers read all of them. - Any other file the project imports, plus any
Compile,AdditionalFiles,EmbeddedResource, orContentitem linked in from another directory. - The
NUGET_PACKAGESenvironment variable, because the restore output records the packages folder by absolute path.
Editing any of these files updates the project graph without an nx reset.
restore isn't cached and isn't part of the task chain. Run it once before build. The files it writes to the top level of obj are excluded from the outputs of build, publish, and pack, so a cache hit doesn't replace your restore.
Test project detection
Section titled “Test project detection”A project gets a test target, and loses its pack target, when either MSBuild property is true:
IsTestProject, whichMicrosoft.NET.Test.Sdksets.IsTestingPlatformApplication, which Microsoft.Testing.Platform sets. The xunit.v3 and TUnit runners set this one, and may leaveIsTestProjectunset.
These are the two properties the .NET SDK itself checks before it will run a project. Nx therefore agrees with dotnet test about what a test project is. Referencing a framework such as xunit or NUnit is not enough on its own, which is what lets a library expose test helpers and keep its pack target. publish and run depend only on OutputType, so a runner built as an executable keeps both.
Both properties arrive with a restored package, so neither has a value before the project has been restored. Until then Nx falls back to a Microsoft.NET.Test.Sdk or Microsoft.Testing.* package reference, which it reads straight from the project file. Restore writes its imports under obj, which Nx doesn't watch, so run nx reset once afterwards to pick the properties up.
Set IsTestProject yourself to settle it and skip all of the above. IsTestingPlatformApplication is not read this way, because it describes the runner rather than the project, and MSTest.Sdk sets it to false on a project it has already marked as a test:
<PropertyGroup> <IsTestProject>false</IsTestProject></PropertyGroup>Test results
Section titled “Test results”dotnet test writes nothing to disk on its own. Results appear only when a file logger or a coverage collector is configured, and they land in TestResults inside the project directory unless you say otherwise. To send them somewhere else and let Nx cache them, pass results-directory through target options together with the logger. The test target declares {projectRoot}/{options.results-directory} as an output. The value is relative to the project directory, the same way dotnet test reads the flag:
{ "targetDefaults": { "test": [ { "filter": { "plugin": "@nx/dotnet" }, "options": { "args": ["...", "--logger", "trx"], "results-directory": "../../dist/test-reports/{projectRoot}" } } ] }}View inferred tasks
Section titled “View inferred tasks”To view inferred tasks for a project, open the project details view in Nx Console or run nx show project my-project in the command line.
@nx/dotnet configuration
Section titled “@nx/dotnet configuration”The @nx/dotnet is configured in the plugins array in nx.json.
Each target type can be configured with:
targetName- Rename the target if needed (e.g., change "build" to "compile")- Additional target configuration properties (options, configurations, dependsOn, cache, inputs, outputs)
- Set to
falseto disable a target
For example:
{ "plugins": [ { "plugin": "@nx/dotnet", "options": { "build": { "targetName": "compile", "configurations": { "production": { "optimization": true } } }, "test": { "targetName": "unit-test", "dependsOn": ["build"] }, "pack": false } } ]}Once a .NET project file has been identified, the targets are created with the configuration you specify in the nx.json plugins array. The default names for the inferred targets are:
build- Compiles the projecttest- Runs unit tests (for test projects)clean- Removes build outputsrestore- Restores NuGet package dependenciespublish- Publishes the application (for executable projects)pack- Creates a NuGet package (for library projects)watch- Watches the project for changes and rebuilds (automatically marked as continuous)run- Runs the application (for executable projects)
Use include and exclude glob patterns on the plugin entry to scope inference. A target defaults plugin filter must use the exact identifier @nx/dotnet.
Target availability
Section titled “Target availability”Not all targets are available for every project type. The plugin intelligently determines which targets to create based on the project type:
- Console Applications & Web Projects: build, clean, restore, publish, watch, run
- Class Libraries: build, clean, restore, pack, watch
- Test Projects: build, clean, restore, test, watch
Continuous tasks
Section titled “Continuous tasks”The @nx/dotnet plugin automatically marks the watch target as continuous, ensuring Nx handles it correctly during development. Unlike watch, run is not automatically marked as continuous as it may exit depending on the type of application. To mark run as continuous, you can configure it manually in project.json or nx.json.
In the nx.json, you can specify that run should be continuous like so:
{ "plugins": [ { "plugin": "@nx/dotnet", "options": { "run": { "continuous": true } } } ]}Alternatively, you can create a new project.json file in the root of your project (next to the .csproj file) and configure the run target as continuous like so:
{ "run": { "continuous": true }}Working with configurations
Section titled “Working with configurations”The @nx/dotnet plugin supports MSBuild configurations (Debug, Release, etc.) through Nx configuration system. You can run tasks with specific configurations:
# Build with Release configurationnx build my-app --configuration release
# Build with Debug configuration (usually the default)nx build my-app --configuration debugSet up CI for your .NET monorepo
Section titled “Set up CI for your .NET monorepo”In CI, Nx runs nx affected to rebuild and retest only the projects a change touches, and caches results to skip repeated work.
For a complete pipeline, see Set up CI.