As someone who has come from a JVM/go background, I was kinda shocked how amateur hour it felt tbh.
As someone who has come from a JVM/go background, I was kinda shocked how amateur hour it felt tbh.
That's what I experienced too. But I think the deeper problem is Node's cooperative multitasking model. A preemptive multitasking (like Go) wouldn't block the whole event-loop (other concurrent tasks) during serializing a large response (often the case with GraphQL, but possible with any other API too). Yeah, it does kinda feel like amateur hour.
Nowadays Node is JavaScript. They are the guys driving JavaScript standards and new features for a decade or so. Nothing prevents them from incrementally starting to add proper parallelism, multithreading, ...
Yes, there have been a lot of advances in modern JS for things like atomics and other fun memory stuff, but that's just the natrual progression for a language as popular as JS. The 3 main JS engines are still developed primarily for web browsers, and web developers are the primary audience considered in ES language discussions (although I'll concede that in recent years server runtimes have been considered more and more)
Clients are 90% still v8, so hardly different than Node.
In principle perhaps not. In practice it is abundantly clear now from repeated experience that trying to retrofit such things on to a scripting language that has been single-threaded for decades is an extremely difficult and error-prone process that can easily take a decade to reach production quality, if indeed it ever does, and then take another decade or more to become something you can just expect to work, expect to find libraries that use properly, etc.
I don't think it's intrinsic to scripting languages. I think someone could greenfield one and have no more problems with multithreading than any other language. It's trying to put it into something that has been single-threaded for a decade or two already that is very, very hard. And to be honest, given what we've seen from the other languages that have done this, I'd have a very, very, very serious discussion with the dev team as to whether it's actually worth it. Other scripting languages have put a lot of work into this and it is not my perception that the result has been worth the effort.
NodeJS is intended for IO-heavy workloads. Specifically, it's intended for workloads that don't benefit from parallel processing in the CPU.
This is because Javascript is strictly a single-threaded language; IE, it doesn't support shared access to memory from multiple threads. (And this is because Javascript was written for controlling a UI, and historically UI is all handled on a single thread.)
If you need true multithreading, there are plenty of languages that support it. Either you picked the wrong language, or you might want to consider creating a library in another language and calling into it from NodeJS.
I didn't say multithreading anywhere. Mutitasking (concurrency) != Multithreading.
You can do pre-emptive concurrency with a single thread in other runtimes, where each task gets a pre-defined amount of CPU time slice, that solves fair scheduling for both IO and CPU-bound workloads. Nobody is supposed to pick NodeJS for CPU-bound workload, but you cannot escape JSON parse/stringify event-loop blocking in practice (which is CPU-bound).
Just so. It is, or at least can be, the plurality of the sequential part of any Amdahl's Law calculation for Nodejs.
I'm curious if any of the 'side effect free' commentary in this post is about moving parts of the JSON calculation off of the event loop. That would certainly be very interesting if true.
However for concurrency reasons I suspect it could never be fully off. The best you could likely do is have multiple threads converting the object while the event loop remains blocked. Not entirely unlike concurrent marking in the JVM.
I cannot go with such a messy ecosystem. I find Python highly preferrable for my backend code for more or less low and middle traffic stuff.
I know Python is not that good deployment-wise, but the language is really understandable, I have tools for every use case, I can easily provide bindings from C++ code and it is a joy to work with.
If on top of that, they keep increasing its performance, I think I will stick to it for lots of backend tasks (except for high performance, where I have lately been doing with C++ and Capnproto RPC for distributed stuff).
I would like to love Jupyter notebooks because Notebooks are great for prototyping, but Jupyter and Python plotting libs are so clunky and slow, I always have to fall back to Node or writing a web page with JS and svg for plotting and prototyping.
What I like from Python os that I can code fast and put something there that will work, at least for backend and with tools like Poetry.
Another different topic is packaging for other users. That is an entirely different story and way worse than just doing what I do.
- Rapid application development
VB was easier and quicker
- GUI development
At least on Windows, in my opinion, VB is still the best language ever created for that. Borland had a good stab at it with their IDEs but nothing really came close to VB6 in terms of speed and ease of development.
Granted this isn't JS's fault, but CSS et al is just a mess in comparison.
- Cross-platform development
You have a point there. VB6 was a different era though.
- Type safety
VB6 wins here again
- Readability
This is admittedly subjective, but I personally don't find idiomatic node.js code all that readable. VB's ALGOL-inspired roots aren't for everyone but if I personally don't mind Begin/End blocks.
- Consistency
JS has so many weird edge cases. That's not to say that VB didn't have its own quirks. However they were less numerous in my experience.
Then you have inconsistencies between different JS implementations too.
- Concurrency
Both languages fail badly here. Yeah node has async/await but i personally hate that design and, ultimately, node.js is still single-threaded at its core. So while JS is technically better, it's still so bad that I cannot justify giving it the win here.
- Developer familiarity
JS is used by more people.
- Code longevity
Does this metric even deserve a rebuttal given the known problem of Javascript framework churn? You can't even recompile any sizable 2 year old Javascript projects without running into problems. Literally every other popular language trumps Javascript in that regard.
- Developer tooling
VB6 came with everything you needed and worked from the moment you finished the VB Visual Studio install.
With node.js you have a plethora of different moving parts you need to manually configure just to get started.
---
I'm not suggesting people should write new software in VB. But it was unironically a good language for what it was designed for.
Node/JS isn't even a good language for its intended purpose. It's just a clusterfuck of an ecosystem. Even people who maintain core JS components know this -- which is what tooling is constantly being migrated to other languages like Rust and Go. And why some many people are creating businesses around their bespoke JS runtimes aiming to solve the issues that node.js create (and thus creating more problems due to ever-increasing numbers of "standards").
Literally the only redeemable factor of node.js is the network effect of everyone using it. But to me that feels more like Stockholm Syndrome than a ringing endorsement.
And if the best compliment you can give node.js is "it's better than this other ecosystem that died 2 decades ago" then you must realise yourself just how bad things really are.
Just an FYI, but Stockholm Syndrome isn't real. In general I agree with the intended point though, people just like what they are familiar with and probably have a bias for what they learned first or used longest.
A single language to rule them all: on the server, on the client, in the browser, in appliances. It truly was everywhere at some point.
Then people massively wish for something better and move to dedicated languages.
Put another way, for most shops the productivity gains and of having single languages are far from incredible, to being negatives in the most typical settings.
JS is here to stay as the main scripting language for the web which means there probably will be a place for node as a back end scripting language. A lot of back ends are relatively simple CRUD API stuff where using node is completely feasible and there are real benefits to being able to share type definitions etc across front end and back end
There are benefits, but cons as well. As you point out, if the backend is only straight proxying the DB, any language will do so you might as well use the same as the frontend.
I think very few companies running for a few years still have backends that simple. At some point you'll want to hide or abstract things from the frontend. Your backend will do more and more processing, more validation, it will handle more and more domain specific logic (tax/money, auditing, scheduling etc). It becomes more and more of a beast on its own and you won't stay stuck with a language which's only real benefit is partially sharing types with the frontend.
There is a significant gain from running a single language everywhere. Not enough to completely overwhelm everything else - using two good languages will still beat one bad language - but all else being equal, using a single language will do a lot better.
It made me think about the amount of work that went into JS to make it the powerhouse it is today.
Even in the browser, we're only able to do all these crazy things because of herculian efforts from Google, Apple and Firefox to optimize every corner and build runtimes that have basically the same complexity as the OS they run on, to the point we got Chrome OS as a side product.
From that POV, we could probably take any language, pour that much effort into it and make it a more than decently performing platform. Java could have been that, if we really wanted it hard enough. There just was no incentive to do so for any of the bigger players outside of Sun and Oracle.
> all else being equal, using a single language will do a lot better.
Yes, there will be specific cases where a dedicated server stack is more of a liability. I still haven't found many, tbh. In the most extreme cases, people will turn to platforms like Firebase, and throw money at the pb to completely abstract the server side.
I've only rarely needed to do this. The two examples that stick in my mind are firstly event and calendar logic, and secondly implementing protocols that wrap webrtc.
My blog post here isn’t as good as it should be, but hopefully it gets the point across
On types, I think the real value proposition is having a single source of truth for all domain types but because there's a serialisation layer in the way (http) it's rarely that simple. I've fallen back to typing my frontend explicitly where I need to, way simpler and not that much work.
(basically as soon as you have any kind of context-specific serialisation, maybe excluding or transforming a field, maybe you have "populated" options in your API for relations, etc - you end up writing type mapping code between the BE and FE that tends to become brittle fast)
TL;DR, this value prop is limited.
The maintenance burden shifts from hand syncing types, to setting up and maintaining the often quite complex codegen steps. Once you have it configured and working smoothly, it is a nice system and often worth it in my experience.
The biggest benefit is not the productivity increase when creating new types, but the overall reliability and ease of changing stuff around that already exists.
I’ve been doing this for a long time and have never once “shared code between front end and back end” but sharing types between languages is the sweet spot.
Just define your API interface as a collection of types that pull from your API route function definitions. Have the API functions pull types from your model layer. Transform those types into their post-JSON deserialization form and now you're trickling up schema from the database right into the client. No client to compile. No watcher to run. It's always in sync and fast to evaluate.
Plus, openapi can be useful for other things as well: generating api documentation for example, mock servers or clients in multiple programming languages.
I'm not disagreeing with you, what is best always depends on context and also on the professional judgement of the one who is making the trade-offs. A certain perspective or even taste always slips into these judgement calls as well, which isn't invalid.