* The ecosystem is pretty strong and constantly evolving. Lots of companies and individuals are putting a serious amount of work into making high-quality tooling and libraries. (Although with that also comes a lot of lower quality stuff and its sometimes hard to tell)
* The language isn't owned by any single company and is well specified
* TypeScript provides a powerful and flexible type system with advanced dependant-types like features. Lets you gradually evolve from a messy JS prototype to well-organized code with fairly strict type checking
* Fastest dynamic language. The performance is also quite comparable to statically typed GCed languages. (For example, you can probably get to 50%-90% of Java performance on most single-threaded workloads)
* wasm support in the runtime a promising escape hatch to the integration with other languages should that become needed. (Similarly not owned by a single company and well-specified)
* sharing code and types between client and server, including interfaces, validation and data models.
* particularly well suited to handling heterogeneous structured data due to how cheap it is to define new object types (even in typescript)
* Async-IO-first (in fact, async-only IO for the most part)
Main weaknesses:
* Poor standard library with an anemic set of classes, anemic set of implementable protocols/interfaces (more stuff like Symbol.asyncIterable needed) and lacking convenience functions. E.g. see https://api.dart.dev/stable/2.7.1/dart-async/Stream-class.ht... and compare with... well nothing in the language! The official node streams have a terrible API.
* Combining lack of both protocols and standard library leads to pretty bad userspace library fragmentation. (What is the go-to stream library?)
* Restricted data sharing between threads (only SharedArrayBuffer) makes it quite limited for multi-threaded problems.
* (mainly TypeScript) - Insufficient reflection capabilities
* Rigid (non-configurable) node_modules resolution algorithm accepted as standard limits flexibility when organizing projects
Mythical weaknesses that don't matter that much:
* Implicit conversions - largely irrelevant since TypeScript
* DOM/Browser related weirdness - often attributed to the language but actually problems with browser APIs
Citation needed, please. I disagree with this. I recently was able to achieve a massive speedup in a Node application through writing a native C++ module... and implementing Garbage Collection is required for N-API.
You can always use the compiler api to extract type information. Sure, a bit tricky but doable.
The compiler api exposes a lot of awesome things, I'm suprised there aren't that many tools that use it.
https://levelup.gitconnected.com/aws-lambda-cold-start-langu...
These days, I’m mostly paid to write web applications. So, I default to JavaScript. That said, there are plenty of problems where JavaScript is such a poor fit that I’ll reach for something else.
With npm, there are lots of options... generally if one package doesn't provide an interface I like, or performs poorly, or just has odd dependencies it shouldn't need, there's another that's probably closer to what I want. Worst case, if there's a smaller change, I fork the project on github, update to a scoped name, and publish my fork.
It's not always pretty. That said, I tend to be considerably more productive with it.
I've also worked a lot with C#, and am recently learning Rust... I feel the first version of most things should be done in a scripted language, and JS/Node is just as valid as any other option in the space.
- async-everything, not a blocking language where anything async relegates you to a subecosystem like you have it in basically every other language from Java to Rust to Python.
- simple stdlib Promise that everything uses. no fragmentation between competing byob futures and byob abstractions.
- async/await.
- single-threaded making it ideal for i/o workloads, a crawler being the perfect example.
For these reasons I think it's one of the best languages. Certainly didn't used to be this way.
Edit: to respond to the GP, I think sharing a language between front end and back end can enable people on either side go full stack with more ease. That's a benefit I guess, but not one I considered of particular value.
I would love to see JavaScript turn into a less verbose, more consistent and less golf-oriented language.
Sometimes I can remove dependencies and code because they are replaced by the new feature of the runtime, thus the maintenance becomes easier.
My application (https://operatr.io/) is Clojure (JVM / Back-end), Clojurescript (Browser / Front-end), Clojurescript (AWS Lambda) - there's enormous leverage is using one language in all cases.
I have at least one function that exists in all three environments, but more than that I have one common language for delivery.
Node is not a web scripting framework, though the fact that JS is used as the main language for web front end is a big part of the attraction; as it lets frontend and backend share code and be served by the same language competency.
This all seems to be pretty useless indirection to me.
If you have one or two lambda functions, then definitely this may be overkill, like you said just call a few functions. But as your system matures and grows, these few functions become a few modules, then your few modules become libraries, so on and so forth. You might want to consider this pattern before it's unclear what exactly is interacting with your requests and responses and in what order.
I think it is far enough for my needs, it is nice to use no framework other than the one provided by AWS.