.NET
netstandardapp
netcoreapp
TFMs
software development

What's the difference between the new netstandardapp and netcoreapp TFMs?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The short answer is that netcoreapp is a real application target framework, while netstandardapp was a historical, transitional idea from the early .NET Core and project.json era rather than a long-term target developers should build around. In current .NET work, you should think in terms of netstandard for broadly reusable libraries and netcoreapp or modern netX.Y TFMs for runnable applications.

What a TFM Is Meant to Communicate

A Target Framework Moniker tells the build tools which API surface and runtime family your project expects. It answers questions such as:

  • is this project a runnable application or a reusable library
  • which APIs are available at compile time
  • which runtime families can consume the output

That is why small differences in TFM naming matter so much. They change compatibility and deployment expectations.

What netcoreapp Means

netcoreapp is the application TFM for .NET Core-era applications. Historically, it meant “this project runs on the .NET Core runtime and can use the full application model available there.”

A simple SDK-style example looked like this:

xml
1<Project Sdk="Microsoft.NET.Sdk">
2  <PropertyGroup>
3    <OutputType>Exe</OutputType>
4    <TargetFramework>netcoreapp3.1</TargetFramework>
5  </PropertyGroup>
6</Project>

In later .NET releases, the naming moved forward to net5.0, net6.0, net8.0, and so on, but the idea is the same: application TFMs target a concrete runtime.

What netstandardapp Was

netstandardapp appeared during the old project.json transition period as an attempt to describe application targeting built on .NET Standard plus application-specific behavior. It was never the long-term TFM that most developers should have standardized on.

That is why modern documentation and tooling discussions focus on:

  • 'netstandard for reusable cross-runtime libraries'
  • 'netcoreapp for .NET Core applications in the .NET Core era'
  • 'netX.Y for modern unified .NET applications and libraries'

So if you encounter netstandardapp in an old post, treat it as historical context, not as a target you should choose for new code.

The Real Library Versus Application Distinction

The concept that matters more than the old name is this:

  • 'netstandard describes a shared API contract for libraries'
  • 'netcoreapp or later concrete runtime TFMs describe actual runnable environments'

A library might target netstandard2.0 so that multiple .NET implementations can consume it.

xml
1<Project Sdk="Microsoft.NET.Sdk">
2  <PropertyGroup>
3    <TargetFramework>netstandard2.0</TargetFramework>
4  </PropertyGroup>
5</Project>

An application should target a runtime-capable TFM instead.

xml
1<Project Sdk="Microsoft.NET.Sdk.Web">
2  <PropertyGroup>
3    <TargetFramework>net8.0</TargetFramework>
4  </PropertyGroup>
5</Project>

That separation is still the right way to think about project targeting today.

How to Read Old Guidance Safely

If you are reading older migration guides or archived discussions, translate them into current terms:

  • old netcoreapp examples still map conceptually to runtime-specific targets
  • old netstandardapp references are usually artifacts of the transition period
  • new applications should use current netX.Y TFMs, not resurrect old names

This matters because cargo-culting historical TFMs into a modern SDK-style project leads to confusion fast.

Choosing a TFM Today

For current codebases, a simple rule usually works:

  • target netstandard only if you truly need broad library compatibility with older or multiple .NET consumers
  • target current netX.Y for most new applications
  • target current netX.Y for libraries too if you only support modern .NET

That guidance is far more useful than trying to reason about netstandardapp as if it were still an active mainstream choice.

Common Pitfalls

A common mistake is reading a very old blog post and assuming netstandardapp is still a current application target. It is not the practical path for modern projects.

Another mistake is using netstandard for an application project. netstandard is a library contract, not a runnable app target.

It is also easy to over-target for compatibility. If your consumers are all on modern .NET, using the latest supported concrete TFM is often simpler than chasing historical compatibility layers.

Summary

  • 'netcoreapp was the real application TFM for .NET Core-era applications.'
  • 'netstandardapp was historical transitional vocabulary, not a long-term mainstream target.'
  • The modern distinction is still library contract versus concrete runtime target.
  • Use netstandard only when broad library compatibility is genuinely required.
  • For new applications, target current netX.Y rather than old transitional TFMs.

Course illustration
Course illustration

All Rights Reserved.