Where package code can run in a NuGet workflow
Reproduced with the .NET 10 SDK (10.0.113), October 25, 2026. NuGet has no npm-style install hook: steps 2 and 3 are the execution surface.
- 1Restore
dotnet restorenuget restorePackages are downloaded and unzipped into the global packages folder. No package-supplied code runs. Under PackageReference, legacy
no package code executesinstall.ps1andinit.ps1scripts are ignored. - 2Build
dotnet buildExecutesA package's
MSBuild runs package-supplied build logicbuild/*.props(evaluation) andbuild/*.targets(execution) are imported into the consumer's MSBuild build and run as the project compiles. In our test a shipped.targetsprinted during the consumer build. - 3Assembly load
[ModuleInitializer]ExecutesThe CLR runs module initializers, type static constructors, and JIT compilation on first load. In our test the package's module initializer ran before the consumer's
code runs before application codeMain. This is where the NuGet credential-stealer campaigns hookclrjit. - 4Runtime
app calls the libraryOrdinary method calls into the package. A dormant payload can also wait here, firing only when a specific helper or date is reached.
expected execution
