banashark
yesterday at 11:11 PM
I've worked with dotnet and node for a while now (15 years of experience, with roughly half in each, and work at a company that is heavily invested in both stacks).
I've had the opportunity to interview engineers switching to my team that have come from both backgrounds (a node engineer switching to my dotnet team, a dotnet engineer switching to my node team).
Dotnet has plenty of advantages over node, which I'm sure you're familiar with based on the perspective of your comment, but there have been some interesting learnings when having folks from dotnet teams come over to node teams that might interest you:
* Agility in the small
Relevant to the featured framework of the OP, if I want to create an executable with node/bun, it's _very_ fast to get started. I can create a native executing "hello world" with 2 commands: `bun init && bun build ./index.ts --compile --outfile mycli`. This results in a 56MB[1] executable.
_The below is incorrect, dotnet can publish single file executables as well without needing to worry about AOT library compatibility_
~~Getting a NAOT executable with C# isn't too much extra work either, _however_ that's where the iteration speed tanks. With node/bun I can add whatever libraries I want and don't really have to think about "is this AOT compatible?" or "are the accompanying libraries that this library goes with AOT compatible, or do I need to select a different library?". I've seen some momentum starting up to make things a bit more NAOT friendly, but it's a far cry from how effortless node/bun seem in comparison.~~
* The default stack is more modular
This is actually in my perspective also a con. Dotnet comes with a ton builtin, which is excellent, however what I've experienced and had corroborated by other dotnet engineers is that what is builtin to the framework often times is _just enough_ _not_ what is needed, that they need to seek out an external library. Although the modular approach has its own downsides, it means that using an integrating separate modules is often more of a trodden path than with dotnet. An example here is dotnet identity, which while an excellent library (I think it's actually underrated in some ways) often isn't enough to cover the need for things like SAML SSO that are fairly common in enterprise environments as table-stakes nowadays. With node, perhaps you just plugin better-auth which has it by default. Or, your authentication library probably has simple documented extension points, and someone has implemented it already.
I think the distinction here is that in dotnet I tend to do more implementation vs in node I tend to do more api gluing together. There are tradeoffs in either direction.
* It's more simple to debug libraries
One of the benefits of node is that if a library appears to have a bug, I can just go tweak the file in my `node_modules` and reload and see if it's fixed. Stack traces also tend to be much more manageable compared to aspnetcore framework stack traces (it's not spring, but it's not small either), so the time-to-finding-out-the-path-to-a-library-function-getting-hit (and being able to reason about it) is often more quick and requires less context within my head to be maintained.
* A thriving community of open source projects and blog posters
Quantity is not quality, but often times when I hit a path in dotnet that doesn't seem written about much (other than perhaps a outdated project on GitHub), I'll see "I wonder how folks are doing this in java or node" where I'll find much more modern and lively discussion on topics.
Microsoft itself does an excellent job of communicating about the projects they're focused on (example: aspire), but they haven't built the same type of community that can support other amazing, but under recognized libraries that they don't have the time to shine the spotlight on (TPL dataflow, etc).
----
All this being said, I think that dotnet really has a more solid foundation. Avalonia exists and is probably the best that the node ecosystem has had yet in an all-in-one server-side framework, but there is a ton of scope that isn't well covered by it or other libraries (first thing that comes to mind is data redaction, but there are other things) and EF Core, while missing lots of features still (glad that left joins are actually coming as first-class lol) is still miles ahead of ORMs in just about any ecosystem (coming from someone who often prefers raw sql).
This is just info to help provide another perspective.
[1] While I agree that 56MB is insane for a hello world in theory, in practice the size of executables has never proven an issue. Devs have tons of disk space and so these things don't even make a dent.
seabrookmx
yesterday at 11:41 PM
Dotnet allows you to make stand-alone builds without AOT compilation as well. Like with bun, it simply bundles the JIT and you get a large executable. The command looks like `dotnet publish -r linux-x64 --self-contained true` (substitute your platform obviously).
banashark
today at 12:02 AM
Ah I had completely forgotten about that with all of the AOT stuff I've been watching. That's a great point.
Yes I find the modularity to be a huge mistake (for a certain definition of modularity obviously). If nothing else the quality of documentation seems to drop off a cliff.
Maybe I'm just going mad but it seems like simple OIDC integration work is an utter pain.
And the database point is a good one. There doesn't seem to be any innovation in ideology or design the dotnet ecosystem along these lines.