FrameworkCompatibleVersions 1.0.0

<Sdk Name="FrameworkCompatibleVersions" Version="1.0.0" />
                    
For projects that support Sdk, copy this XML node into the project file to reference the package.
#:sdk FrameworkCompatibleVersions@1.0.0
                    
#:sdk directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.

FrameworkCompatibleVersions FrameworkCompatibleVersions

GitHub Workflow Status NuGet NuGet Codacy Grade

An MSBuild Project SDK that lets a consumer mark selected NuGet dependencies as framework-compatible versions without repeating target-framework conditions for every package.

The SDK is deliberately package-agnostic. It contains no list of package IDs and never adds dependencies. Consumers choose the packages by adding FrameworkCompatibleVersion="true" to their own PackageVersion or PackageReference items.

Installation and usage

For any repository with more than a single project, the recommended approach is to pin the SDK version once in global.json and import the SDK once from the root MSBuild files. This keeps individual project files clean and avoids repeating the SDK reference (and version) in every <Project Sdk="..."> line.

  1. Pin the SDK version in global.json:
{
  "msbuild-sdks": {
    "FrameworkCompatibleVersions": "1.0.0"
  }
}
  1. Import the SDK's .props near the top of Directory.Build.props:
<Project>
    

    <Import Project="Sdk.props" Sdk="FrameworkCompatibleVersions" />
</Project>
  1. Import the SDK's .targets near the bottom of Directory.Build.targets:
<Project>
    <Import Project="Sdk.targets" Sdk="FrameworkCompatibleVersions" />

    
</Project>

With this in place, every project under that directory automatically participates. The individual project files remain plain:

<Project Sdk="Microsoft.NET.Sdk">

Because the SDK is package-agnostic, nothing is applied until a project (or a shared Directory.Packages.props/Directory.Build.props) opts specific packages in with FrameworkCompatibleVersion="true". Projects that should not participate can set <FrameworkCompatibleVersionsEnabled>false</FrameworkCompatibleVersionsEnabled>.

Alternative: per-project SDK reference

A single project (or a repository that prefers not to use root MSBuild files) can reference the SDK directly alongside the normal .NET SDK, pinning the version inline:

<Project Sdk="Microsoft.NET.Sdk;FrameworkCompatibleVersions/1.0.0">

Or, with the version centralized in global.json as shown above, the version can be omitted:

<Project Sdk="Microsoft.NET.Sdk;FrameworkCompatibleVersions">

Central Package Management

With Central Package Management, opt packages in where their versions are declared:

<Project>
    <PropertyGroup>
        <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
    </PropertyGroup>

    <ItemGroup>
        <PackageVersion Include="Microsoft.Extensions.Http" FrameworkCompatibleVersion="true" />
        <PackageVersion Include="System.Text.Json" FrameworkCompatibleVersion="MatchingMajor" />
        <PackageVersion Include="Pinned.Package" Version="1.2.3" />
    </ItemGroup>
</Project>

The consuming projects continue to use ordinary versionless package references:

<ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Http" />
    <PackageReference Include="System.Text.Json" />
    <PackageReference Include="Pinned.Package" />
</ItemGroup>

When Central Package Management is enabled, FrameworkCompatibleVersions automatically enables CentralPackageFloatingVersionsEnabled because the selected versions are floating.

Direct PackageReference usage

Without Central Package Management, apply the metadata directly to the package reference:

<ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Http" FrameworkCompatibleVersion="true" />
    <PackageReference Include="System.Text.Json" FrameworkCompatibleVersion="true" />
    <PackageReference Include="Pinned.Package" Version="1.2.3" />
</ItemGroup>

Unmarked package items are left unchanged.

Version policy

FrameworkCompatibleVersions supports two policies, selected per package through the value of the FrameworkCompatibleVersion metadata:

Metadata value Policy
true Highest tested against (the default).
HighestTestedAgainst Identical to true.
MatchingMajor A package major that matches the target framework's own runtime major.

Highest tested against (true / HighestTestedAgainst)

Target framework NuGet version expression
Earlier than .NET 6 [6.*,7.0.0)
.NET 6 and .NET 7 [8.*,9.0.0)
.NET 8 and .NET 9 [10.*,11.0.0)
.NET 10 and later [*,13.0.0)

Matching major (MatchingMajor)

Each target framework resolves to a package major that matches its own runtime major:

Target framework NuGet version expression
.NET 5 [5.*,6.0.0)
.NET 6 [6.*,7.0.0)
.NET 7 [7.*,8.0.0)
.NET 8 [8.*,9.0.0)
.NET 9 [9.*,10.0.0)
.NET 10 [10.*,11.0.0)
.NET 11, 12, 13 [11.*,12.0.0), [12.*,13.0.0), [13.*,14.0.0)
.NET Core App 3.x [3.*,4.0.0)

Target frameworks earlier than .NET 5 are trickier: netstandard, .NET Framework, and legacy TargetFrameworkVersion-only projects have no runtime major, and package majors before the .NET 5 unification are not aligned across ecosystems (for example, the Microsoft.Extensions.* packages have no 4.x). For those, MatchingMajor falls back to the lowest broadly-available major that still supports netstandard2.0 ([2.*,3.0.0)), while .NET Core apps resolve to their own major (netcoreapp2.x[2.*,3.0.0), netcoreapp3.x[3.*,4.0.0)).

NuGet resolves each floating expression to one concrete stable package version during restore.

Multi-targeting

The SDK evaluates the policy separately for each inner build. A project targeting, for example:

<TargetFrameworks>netstandard2.0;net8.0;net10.0</TargetFrameworks>

can declare a package once with FrameworkCompatibleVersion="true"; each target framework receives its corresponding version expression.

Directory.Build.props and Directory.Packages.props

The metadata can live wherever the consumer normally declares the item, including the project file, Directory.Build.props, Directory.Packages.props, nested variants of those files, or explicitly imported .props files. FrameworkCompatibleVersions works against the evaluated PackageVersion and PackageReference items rather than maintaining its own package list.

Legacy .NET Framework projects

Legacy non-SDK-style .NET Framework projects can use FrameworkCompatibleVersions when they use PackageReference, a sufficiently modern MSBuild/NuGet toolchain, and an MSBuild SDK reference. Projects that expose TargetFrameworkVersion receive the pre-.NET-6 policy.

packages.config is intentionally not supported.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 58 9/21/2026

Initial release.