And ASP.NET is one of the few large projects which managed to survive a large breaking changes. Almost to Python 2->3 level. You had to change how your web app behaved completely if you relied on their magic session which worked hard to keep state synched between back and front.
Feels good to have 3 trillion dollars interested in improving the stack you use and actually care.
Developers! Developers! Developers!
Even for new projects there are problems I run into that force me to use 4.8. Like if you build an Excel formula, the mandatory async/await approach just doesn't work. It's not an asynchronous operation and runs into a UI context where you deadlock if you wait. They also broke a lot of the windows integration, where in a corporate environment the same network calls with the same syntax authenticate successfully with 4.8 but fail with core.
And because they broke backward compatibility on so many libraries, it's a non trivial effort to convert a complex code base to core.
It's great that they focus on performance, but the .net framework fossilised in term of functionality. It took like 15 years before they added a json serializer to the standard library, and don't even think about support for any new major image format (webp, heic). Everything has become complicated, there isn't a day where I don't see a crash message in visual studio. I used to be a big .net fan but I miss Anders' leadership.
As to the breaking changes... .Net Core 1.0 was nearly a decade ago... I understand that some people may want to continue running Windows 7 too, but eventually the world moves on and you either update or use a stale version.
The shift to Core and the breakup of a lot of bits comes down to the need to better support running on platforms outside windows... or, .Net itself would have likely died off completely. Most of the .Net projects I've worked on for close to a decade now have been deploying to Linux/Docker... If it weren't for Core/5+ as a shift, it would have been under another language/toolkit entirely.
Just because you think something is hard, doesn't mean it is hard.
Last time I did excel interop it was COM based and there wasn't any async part of it. I'm curious if you were using COM interop also? Also, async/await was explicitly designed to work in UI contexts like Winforms and WPF where there is only a single UI thread...?
> It took like 15 years before they added a json serializer to the standard library..
That isn't really true. DataContractJsonSerializer [0] landed in .NET 3.5 which was in 2007. Admittedly, it kinda sucked but it was there and was usable. And also JSON.Net was around by that point and was/is excellent.
> ...and don't even think about support for any new major image format (webp, heic).
Image support on windows was historically provided by WIC [1] and does support the formats you talked about. But you are correct that native .NET support for many image formats is non-existent.
> And because they broke backward compatibility on so many libraries, it's a non trivial effort to convert a complex code base to core.
This is very true, and I felt it firsthand. My employer still has a codebase on .NET Framework (compiled against 4.5.2 but deployed against 4.8). It is WCF based and the jump to Core was a massive break. But in the end, I think the break was a good decision. There were just too many design mistakes, bad assumptions and underlying system changes to keep compat across the big leap to a modern multi-platform framework. .NET today is faster, more flexible and has more capabilities than .NET Framework ever did. Even if it did take a long time to get here.
And besides, even if new features are not coming to .NET Framework anymore, Microsoft has support .NET 3.5.1 until 2029! [2] Isn't 22 years of support enough? (.NET 4.8's EOL hasn't even been announced yet!)
[0] https://learn.microsoft.com/en-us/dotnet/api/system.runtime.... [1] https://learn.microsoft.com/en-us/windows/win32/wic/native-w... [2] https://learn.microsoft.com/en-us/lifecycle/products/microso...
I have been reaching for GO with simple tooling and HTTP back end. .NET is useful for other solutions.
I have had too many issues with their frameworks, like WPF, needing to implement Win32 hacks. Example, .Net 9 was the first Windows version that properly returns all network interfaces. Older runtimes only expose Enabled NICs. I still have to maintain Windows 7 support for some solutions.
EFCore by default is pretty performant - and pretty basic. You need to manually .Include() joins etc. which makes it pretty hard to become slow.
A close second would be TS + Hono + Zod-OpenApi and SwaggerUI.. but setting up my context types is slightly more of a pain.
We wanted the option for distro maintainers to include .NET in the native distro package feeds. This means that distro maintainers have to build the product, not us, and that means creating a build system that meets their requirements. So you either end up with two build systems, or you try and unify. The only direction that it's feasible to go is towards the Linux distro model. It's the most restrictive.
The good news is that the distro model is SIMPLER. It may not be the most performant. A really good distributed system with caching would be far faster. But that's not a solution that's easy to implement or compatible with distro maintainer workflows. Optimizing for simpler in this case is better though. We want the community to be able to participate in a meaningful way. Build for BSD, build for S390x, build and include in distro feeds, etc. We can't feasibly support every platform and scenario that the community wants.
[1]: https://github.com/dotnet/source-build/blob/main/README.md#n...
We could have hot machines ready to go at all times and eliminate any queue time. There's also machine-learning based model for predictive spin-up. The downside is primarily cost to maintain all the various SKUs needed in a live and ready state. We compromise a bit there.
Reading something like this, which outlines a coordinated effort (diagrams and even a realistic use case for agentic LLM usage and all!) to actually and effectively make things better was a breath of fresh air, even if towards the end it notes that the remarkable investment in quality will not be in full force in the future.
Even if you don't care about .NET and/or Microsoft, this is worth reading, doubly so if you're in charge of re-engineering just about anything -- this is how it's done!
Why so many variants?
Then you've got the .NET SDK/aspnet/runtime (on x64/arm32/arm64 linux/mac/windows), and also the various SDK packages themselves.
I hope this churn in .NET builds is temporary because a lot of people might be looking to go back to something stable especially after the recent supply chain attacks on the Node ecosystem.
Can you elaborate a bit? This article talks about internal machinery of building .net releases. What does that have to do with "this churn", whatever that is?
I think node is just more flexible and unless .NET Framework like forever releases or much longer term support make a come back, there’s no good trade off from node, since you don’t even get more stability.
.NET has a really refreshingly sane release life cycle, similar to nodejs:
- There's a new major release every year (in November)
- Even numbers are LTS releases, and get 3 years of support/patches
- Odd numbers get 18 months of support/patches
This means if you target LTS, you have 2 years of support before the next LTS, and a full year overlap where both are supported. If you upgrade every release, you have at least 6 months of overlap
There's very few breaking changes between releases anyway, and it's often in infrastructure stuff (config, startup, project structure) as opposed to actual application code.
The recently fixed the friction with odd number releases by providing 24 months of support.
The .Net platform is honestly the most stable it has ever been.
It's hard for me to imagine a version increment being much easier than this.
You should be able to go from .NET 6->10 without almost any changes at all.
Or what is a pretty standard feature in other tech-stacks needs some bespoke solution that takes 3 dev cycles to implement... and of course there's going to be bugs.
And it's ALWAYS been this way. For some reason .NET has acolytes who have _always_ viewed .NET has the pinnacle of programming frameworks. .NET, Core, .NET framework, it doesn't matter.
You always get the same comments. For decades at the point.
Except the experience and outcomes don't match the claims.
Just before I get the reply, I'm pretty familiar with .NET since the 2000's.
A few years ago even most people actively working in .Net development couldn't tell what the hell was going on. It's better now. I distinctly recall when .Net Framework v4.8 had been released and a few months later .Net Core 3.0 came out and they announced that .Net Standard 2.0 was going to be the last version of that. Nobody had any idea what anything was.
.Net 5 helped a lot. Even then, MS has been releasing new versions of .Net at a breakneck pace. We're on .Net 10, and .Net Core 1.0 was 9 years ago. There's literally been a major version release every year for almost a decade. This is for a standard software framework! v10 is an LTS version of a software framework with all of 3 years of support. Yeah, it's only supported until 2028, and that's the LTS version.
It never takes a few minutes in big corp, everything has to be validated, the CI/CD pipelines updated, and now with .NET 10, IT has to clear permission to install VS 2026.
In many cases you get assigned virtual computers via Citrix/RDP/VNC, and there is a whole infra team responsible for handling tickets of the various contractors.
I love the new features of .Net, but in my experience a lot of software written in .Net has very large code bases with a lot of customer specific modifications that must be supported. Those companies explicitly do not want their software framework moving major supported versions as quickly as .Net does right now, because they can't just say "oh, the new version should work just fine." They'd have to double or triple the team size just to handle all the re-validation.
Once again, I feel like I am begging HN to recognize not everyone is at a 25 person microservice startup.
The migrations where I've worked at have always been a normal ticket/epic. You plan it in the release, you do the migration, you do the other features planned, do the system tests, fix everything broken, retest, fix, repeat until OK, release.
Otherwise you're hoping you know exactly how things interact and what can possibly have broken, and I doubt anyone knows that. Everyone's broken things at first sight seemingly completely unrelated to their changes at some point. Especially in large systems it happens constantly. Probably above 1% of our merges break the nightly in unexpected places since no one has the entire system in their head.
Or you're keeping a dead product just barely alive via surgical precision and a lot of prayers that the surgeon remains faultless prior to every release.
As to the CI/CD pipelines... I just edited my .github/workflow/* to bump the target version, and off to the races... though if you're deploying to bare metal as opposed to containers, it does take a couple extra steps.
As to the "permission to install..." that's what happens when companies don't trust the employees that already write the software that can make or break the company anyway... Defelopers should have local admin privs, or a jump box (rdp) that does... or at the very least a linux environment you can remote-develop on that, again, has local admin privs.
I'm in a locked down environment currently, for a govt agency and hasn't been an issue. Similar for past environments which include major banking institutions.
There are legions of developers for whom Visual Studio on Windows is the only place they have ever been comfortable. And upgrading between versions of .NET is a point-click exercise between the various UIs (Visual Studio Installer, “Get New Components or Features”, and the NuGet package manager)
The advent of .NET Core happened to coincide with initiatives to adapt:
* toward the cloud and away from IIS and Windows Server
* toward Git and away from TFS
* toward remote CI/CD and away from “drag my files into inetpub”
* toward SPAs and away from ASP.NET XAML programming (Blazor notwithstanding)
* toward a broader toolkit where the familiarity with OSS and open specs is advantageous, and away from Visual Studio as the center of the universe (though it still arguably reigns supreme in its class of IDEs)
Coming from the Linux/Docker world before going deep in .NET, I was both resented and leaned on heavily for these teams’ transitions. Most of my teammates had never read the contents of their .csproj or .sln files, or run a build command from a terminal and read its log output. They were annoyed by my requests to do so when helping them troubleshoot; some just rejected the idea outright (“there’s no need to look at VS internals here”, “we shouldn’t need to run DOS commands in today’s world, VS should hable this!”)
I can definitely sympathize with developers who were sold on what seemed like a promise that deep VS/IIS/etc knowledge would be the rock-solid foundation for business software for the rest of their careers. During the uprooting process, other promises like “netstandard2.0 will be forever for your core libraries and all future .NET runtimes!” end up with asterisks the following year.
I am 100% in agreement that .NET dev team is doing an amazing job, but it’s precisely because of their continued shakeups when they see major opportunities to improve it from the ground up, and probably the same reason that others feel wary of it
Anyways, I work with .NET Framework and .NET. Being a developer is a joy where you can learn daily new tricks and satisfy your curiosity.
So to me this reads so alien that people fail to learn new tricks within .NET world. For me it's like a stream of amazement: Ohh, this is so much better with new language features. Ohh, this code is so much more clean. Woa, logging is so simple with ILogger and I can plug whatever underlying log engine I want! Configuration via JSON files, niice. I can override with Env variables out of the box? Amazing. This all follows particular rules and patterns. Ohh, I can customize the way I read configuration any way I want if I need it so. Ohh, I can build and run from CLI using simple commands! Ohh, I can package in docker and run on Linux. Oh, wow, .csproj is so much more clean, gotta use SDK-style project for my .NET Framework projects too!
To temper my comment, the resistance I faced as the new guy brought in to modernize is natural for these engineers who knew their tools and systems well, in their defense. Eventually they warmed up from full pushback to friendly banter “Mr. Linux and command line over here” and accepted that running my little scripts helped address the confusion/frustration of Visual Studio disagreeing with Jenkins/GitHub Actions automations and runtime behavior in Kubernetes.
I haven't seen a good logger implementation for .Net that does a similar good job without a bunch of byzantine configurations.
I couldn't even tell you how to do certain things in the VS gui at this point... I've got Rider and VS installed only because Rider is nicer for refactoring and I've had to fix VS launch issues a couple times (VS backend, vite/react frontent).
Prior to .Net core I had one foot out the door, mostly towards Node... Now, I'm fine with either/both... though all my shell scripting is now with Deno/TS.
I know their release/LTS cycles are now much shorter than the 20+ years that some framework versions have seen, but keeping things "current" hasn't been that hard. IMO, it's just part of maintenance for "rapid" software development. Companies want software in weeks instead of many years of planning, that means ongoing maintenance work.
At least exactly due to performance issues, I get some excuses to push for C++ addons in some cases.
The problem with the community is that this statement has been said for every version in every era despite how untrue it is lol. No matter what ills or blights .NET will put on your solution the developers will always sing its real or imagined praises.
This is the #1 reason I avoid interacting and working with .NET teams because it's still true to this day.
Honesty would go a long way.
This could also change but in my experience AI is better at generating Python code versus dotnet.
Depending on your framework Python is at best ~3x slower (FastAPI) and at worst ~20x (Django) than asp.net on the techempower benchmarks, which maps pretty well to my real world experience.
Modern PHP is a joy, and it's much faster these days, but performance is still a problem. It was chosen over 25 years ago, and I'm sure they thought the same thing about never getting the amount of load they eventually got.
Modern PHP is virtually indistinguishable from dotnet, with some php-isms sprinkled on top. They should've chosen dotnet all those years ago.
.NET is certainly better than Python, but I'm not very happy with the type system and the code organization versus my Rust projects.
Have you given F# a whirl?
That said, Rust+Axum is pretty nice as well.
Horses for courses… also, a Horizontal Pod Autoscaler and Load Balancer setup is pretty cheap.
In python and node it is _so_ painful to use multiple cores, whereas in .net you have parallel for loops and Task.WhenAll for over a decade. Java is similar in this sense that you don't have to do anything to use multiple cores and can just run multiple tasks without having to worry about passing state etc between 'workers'.
This actually becomes a really big problem for web performance, something I'm deeply passionate about. Not everything is just IO driven holdups, sometimes you do need to use a fair bit of CPU to solve a problem, and when you can't do it in parallel easily it ends up causing a lot of UX issues.
Gradle with Kotlin DSL is nice, what's annoying is Gradle's constant API reshuffling for the sake of it that breaks plugins. Some plugins also introduce pointless breaking changes just to have a fancier DSL.
The IDE support is not an issue in practice, in my opinion, because IDEA is the best IDE for both Java and Kotlin. The official Kotlin LSP was released 6 months ago, but I haven't tried it.
> Introduces a very messy and complex history which would not work for the repo of our size > Apparently the support in git is buggy and can lead to problems in the repo (the SO is full of examples) > Doesn't support cloaking
(I think by "cloaking" they are referring to https://github.com/premun/dotnet/blob/766c564dd379e634c38739... )
I cant see .net win againts those odds tbh
Same goes with Python with its data science and ML/AI background.
And the general malus is Microsoft as a company.
In summary: it is not the tech. It is the landscape.
TS drags JS into the world of modern languages, but it's not good enough IMO.
Taylor Swift is the most popular artist of all time. Is she also the best and your favorite?
Popularity is important, but it doesn't mean anything by itself.
You don't need to sold me, I already use both of them
Hope you can migrate out of these legacy tech stack
Node and Python are dynamically typed and at least originally scripting focused. They are not the right choice for many development active which are focused.
.NET plays with Go and Java in the same category of use cases. And there it boils down to devs you have.
Regards ecosystem: I am at home in both, .NET and JavaScript (browser more) and I can tell you: ecosystem is in 2025 no problem. Was back in the 2010s.
About the devs: you have what you have and hire along. Like Java, it will not go away. You get good ones and bad ones. Like for any other language.
Let us be less religious here. Objectively, .NET is like Go and Java a fit contender for its niche and selection goes along the lines what you have as workforce/systems already in place. In a startup situation you follow the preferences of your CTO.
Feeling motivated enough to deep dive into .NET 10
And that’s ignoring how you’re essentially severely handicapping yourself in terms of what is possible.
Unless you’re in an environment stuck 20 years in the past (which implies serious security liabilities considering they must be a Microsoft shop), this is a mind bogglingly bizarre strategy.
At the end of the day both solutions/syntaxes work, but..