- Node's package manager npm is fantastic, and (imo) gets package management more right than 90% of other package managers
- There are 1000s of high quality actively maintained modules on npm to get you started on things (and 1000s of garbage ones, so you have to be careful)
- The "holy grail" web app architecture (server rendering of frontend JS components coupled with client side rendering in a SPA) is only possible by running some JS on the server
- Sharing JS UI components between the backend and frontend is a huge DX and productivity win
- Another huge maintenance win is using the same language across the whole stack (frontend, backend and devops/automation)
- With ES6, JS is slowly turning into a pretty cute language, check it out :)
- A nice level of cross-pollination between JS and those geniuses in the ClojureScript community is bringing some really nice functional programming approaches and projects to Node/JS
- You can use Node and JS to compile to both native desktop apps and native mobile apps. Having a centralised UI library of JS components that you can leverage for your desktop app, mobile app, frontend SPA and backend static rendering sounds pretty good to me!
The quality of node package is very bad in general. Like the most part are totally garbage. I don't know from where you come and what you used before, I worked only with java, php and ruby for the backend and in those i found:
- far higher Documentation quality... like, node modules documentation is not even REMOTELY comparable: it is often extremely outdated, with very poor examples, the most of the times these example are not even working or are using functions deprecated since 3-4 versions of the module itself.
- a infinite amount of bugs and undocumented behaviors rarely already reported and, when reported, just ignored for months. I usually would find infinite workarounds instead of solutions
- extreme use of "I can do it better, so here my fork". I passed the big part of the time running from bug report to bug report and reading in the comments discussions about "The main maintainer of this package does not want to solve this problem of mine... so i made this other module, totally identical to this one but I just added this little hack, which totally broke the standard way of doinf things of this module, some functionalities I needed and never implemented the last 8-9 months of commits here." and chain this. Like this happened a dozen time each months when someone suggested "Why we don't try this module that says it solve our needs?"
- No standards anywhere.
It's true, you have to be careful ... there are so many npm modules that there are many garbage ones too. But there are many very high quality ones too. Be more careful about how you choose one, and if you can't find a good one for your needs, then don't settle for a bad one - roll the feature yourself, or adjust the functionality of your app. But in my experience there are high quality modules available for the major components of apps.
Doesn't mean there are any 'high-quality' ones appropriate for the specific task.
> Be more careful about how you choose one, and if you can't find a good one for your needs, then don't settle for a bad one - roll the feature yourself, or adjust the functionality of your app.
So now you're just contributing to the problem of yet another package in the ecosystem?
Yes, which is why I said if you can't find one then roll the feature yourself.
> So now you're just contributing to the problem of yet another package in the ecosystem?
Nope, I didn't say write and publish a npm module. I said "roll the feature yourself", meaning just write it privately for your app. Having lots of packages isn't bad for the ecosystem, it makes Node and npm unique and amazing. But picking bad npm modules, which is entirely avoidable, is bad for your project - that's all I meant.
Having an ecosystem where, say, 70% of the choices I make can be 'bad' is probably not a great ecosystem. I hope it shakes out in the next year or so and there's less choice. There's enough choices I have to make in my own application layer - having to make X more choices about code I didn't write and how all those pieces fit together (and how they'll be maintained going forward) just doesn't feel like a good long-term platform. But... people have the 'choice' to use it if they want ;)
Bundler and hex, for example, are faaaar better--just consider how long it took them to figure out shrinkwrapping, or flat structure to support Windows.
All of my recent projects have been isomorphic react apps. I build my app like it were a fully client-side single page web app, but I get server rendering when there's a new http request. Once the page has rendered, the web app takes over and uses history pushState. There are very few pieces of code that aren't used in both places. Once you get the hang of it, you very naturally create mockable interfaces that can be swapped depending on environment.
In my opinion, this is pretty much the only category that makes JavaScript "Best-in-class"; It's the easiest language to build isomorphic web apps.
* Babel - ESNext - JSX * Gulp * Browserify - Incremental * Express * React router * Rolled my own flux - This was interesting because I didn't truly understand flux when I started - I _get it_ now
The routes on the server are the same routes on the client. When the server renders, React/ReactRouter take over on the client and use history pushState.
And that's actually about it. There aren't any other major libs that change the nature of the project.
One thing I'm looking to do next is get hot reloading working and to somehow cut down on the initial compile times.
JavaScript is becoming the web darling (or it already is?), whether we like it or not. And with some nice syntactic improvements ES6 brings, I don't mind.
Dart, ClojureScript, TS (technically JS superset but still a considerable improvement) are just the ones I've used.
And I'd rather use both of them on server (Dart/Clojure) than JS.
There are other languages as well.
ES6 is a pain in the ass - no browser supports it and using transpilers + polyfills and the JS build/package tools to set that up is a PITA that only grows as you add dependencies and it bloats your code size to be comparable or larger than the compile-to-JS languages without making the language significantly better.
It just seems like everybody except me hates dynamism sometimes.
The Coffeescript converts have moved on from the 'one true language' now that ES6 cherry-picked most of the good parts and people started realizing that CS source maps are buggy/inconsistent.
Standards are for 'plebs' so they've moved on to the new shiney. By new shiney, I mean mimicing FP in Javascript and looking down on people who can't ELI5 monads and functors. Despite not being able to ELI5 monads and functors.
Typescript, is really geared toward OOP devs who live in an IDE and compulsively twitch an invisible set of CTRL-SPACE keys when they get nervous.
It's a well-known fact that Google is a OOP- heavy Java/C++ shop who have been developing algos in Java/C++ since their last CS course where they developed algos using Java/C++.
It's within their best interest to get all of there desktop devs to convert to writing desktop apps on the web before all that penis pills/local singles ad money runs out.
It's only a matter of time before we see the first JS AbstractFactoryFactoryServiceProvider class in the wild. Angular2 has made considerable progress on this front so far.
/satire
Honestly, I really enjoy ES6. The JS dev communities favorite past time is ragging on how ridiculously bad JS is. ES6 isn't bad so it's not worth talking about.
The new features introduced in ES6 are pretty conservative. They consist of good concepts poached directly from popular superset languages or sensible additions that fit in nicely with the usual JS style.
The really interesting additions are still in the specification phase. Additions, such as the new ES6 module and loader standard, decorators, native HTTP fetch, etc...
As long as new standards are being introduced, transpiling will continue to be a requirement. I think it's cool that people can create and use new supersets of JS. It beats having to listen to them whine about how 'Javascript isn't exactly like some other language that I really like to use.'
In a way it's the first democratic programming language. Instead of dictating what people should and shouldn't use, people are free to migrate around to different communities until they find one that more closely matches their worldview. Everybody follows the same baseline standard but there's a lot of legroom for differentiation.
Why axegrind over our differences when we can celebrate them and start working together.
I just don't see the utility in trying to translate pure FP concepts directly to JS. Same goes for the Typescript folks with OOP abstractions and design patterns. It's like watching a pissed off New Yorker rant about how the pizza shops in LA suck. Live a little and try a California burrito. It might change your life.
The point being, neither approach has provides measurable benefit to runtime performance/stability. They're nothing but really complicated abstractions whose sole intent is to protect devs from themselves. Why don't we build better tools to assist devs instead of inventing yet-another-feature-specific-language?
I think FP abstractions translated to JS could work as amazingly useful design patterns. Hopefully, decorators will make it a lot less painful to define higher order functions in JS.
Likewise, static type alike languages are very useful as a bridge to traditional OOP devs. I think gradual typing is a better long term approach.
And yeah, I don't think that monads are that useful JS. And OO is different in JS. Deal with it.
Also, if you use Strategy, Iterator, or Visitor patterns in JS by writing classes for said things, you deserve to be punched in the face really hard. Repeatedly.
Don't get me wrong I think all those experiments (if I may) are nice, but if I were to develop an interface in Dart/CS/TS today, I'd have serious problems hiring people that know one of those tomorrow.
It doesn't eliminate the need to transpile, but it looks like transpiling may not be necessary forever.
You still need to include core.js to polyfil basically everything from standard library. And then you need to make sure Babel works with your framework (like Polymer or what not), and that's just the start of the interop hell that is using different JS libraries together. Rule of thumb - anything you add to your JS build system = increase in the likelihood of hair pulling when things break - and babel and core.js are two such things.
The value I get from ES6 compared to the CLJS change how much I'm willing to tolerate the PITA factor of the build system.
In dart I don't have to do any of that, just add few lines to pubspec.yaml with dependencies and transform directives and off I go. And every other library uses the same build system and the same package manager and the same standard library !
I have also had no real problems interopping with other big libraries. I think the biggest point of discontinuity would be the class keyword vs other class-like libraries (like coffeescript's implementation). Even that's not too bad, I'm able to extend those using es6 class syntax, I just need to be careful about calling super and setting up the constructor properly.
I don't see how using Dart, TS, etc. make it any asier, and with the setup I just described, you're using Javascript top to bottom. I have an Angular project set up this way, and that allows me to run the unit tests in Node on the command line.
And why would you write ClojureScript to use on the server, when you could just use Clojure?
Plus you've somehow managed to state that JS developers are not decent enough.
Meteor excels at this.
I wonder, will it be still as popular if WebAssembly let us use any programming language on the client? I mean post MVP WebAssembly with support of GC, DOM, and so forth.
1) Bad concurrency model -- callbacks, promises and futures are in general inferior abstraction model compared to green threads, actors, regular threads. Performance-wise it might do well in some scenarios but you are forced to use a more complicated abstraction to get that performance It is not worth it. In general it is appealing because it looks simple in small demos, as applications grow it becomes a mess.
2) npm modules are easy to use and that's great. Good model (well maybe except for deep nesting which breaks based on max path in say Windows, but I hear they are fixing that). The problems I found was that a lot of modules were of low quality. Code half-finished, buggy, developer moved on to something else, etc. Somehow it seems more so than say in the Python community.
3) Javascript is not the best language. There is a reason there is a "Javascript: The Good Parts" book. Because there are lot of crazy decisions made in it originally and a lot of bad "parts". If there was a choice between FORTRAN, Cobol and Javascript. I would pick Javascript hands down, but there are other languages out there today.
However. If all you know is Javascript and you want to write a small demo, then go for it. It will be the least friction.
So with all this complaining and whining, how about some constructive stuff. What language / frameworks might be more interesting / better.
1) Go : good concurrency model, supported by a large community, good performance. Lots of big companies use it.
2) Elixir : new kid on the block, fun, one of the friendliest communities. Probably best concurrency model -- actors. It uses Erlang's VM, so that part is rock solid, battle tested for many years. But not as many libraries. But can use existing Erlang libraries from it. Also best for reliability and fault-tolerance.
3) Python : easy to learn, lots of libraries, lots of material how to use it. This is my go-to language to get stuff done quickly. Try Python 3 if you start from scratch.
4) Clojure, Scala, Java: run on JVM. Battle tested, probably lots of libraries. Personally not as familiar with it, most enterprise and big sites out there run on the JVM currently.
It's great you like Python. Use a Python framework. You can point out Javascript's warts and we can laugh at the Python 3 migration. (And really, both of these criticisms are out of date. Javascript is _fine_ these days and Python 3 is moving towards backwards compatibility; sure Javascript has warts, but that's because it's backwards-compatible. You know, like... never mind.)
I don't like many things and like other things. All in various degrees. So I shared my experience.
But you seem to be interested in what I like, so I'll share more. I would say, in general I am not really a "$X language" developer. A lot of people say "Oh, I am a Java developer" or "A Node developers". I am not a Python developer, or Erlang developer. I am a developer who solves problems. And languages are tools ( so far I used Javascript in the past, as well as Erlang, Java, C++, C#, and yes, even FORTRAN ).
The point about Python was that currently, most tasks I had to do, were made quicker and easier by using Python. Some are solved better by Erlang, some by C#.
Javascript and Node I found had enough negatives so it seemed helpful to share that too.
> Obviously, if you don't like javascript, move on.
I didn't know this was Javascript land and I wasn't allowed to come in without proper credentials. (See note about "friendly community" regarding Elixir in my original post, that wasn't by accident. I didn't want to say anything more about Node community, but I will now -- yeah it is not the friendliest, lost of insecurity and angst in it, which was another turnoff to me personally).
On the flip side, I can see why developers in other languages may feel a bit defensive too. They see this language that they have a poor opinion of start to eat into everything, including server side, and potentially threaten livelihoods. Its an emotionally charged area. JavaScript: The Good Parts is getting on for a decade old, things have changed so much. With ES2015 and beyond JS is becoming a pretty cute language, it's slowly starting to enable a really nice functional style, try and write a project or two in it sometime, see what you think :)
The reason why JS + node is popular is becasue it's pretty good at each of the metrics you mentioned. Even though it's not best in class at any one of those, it is well balanced for many tasks. Many other technologies are either too slow, too low level, too hard to scale, or too cumbersome to work with.
But if you go back to the origin story of Node, it's all about libev (though it now uses libuv for the same purpose) and that pervasively-asynchronous mindset. JavaScript was chosen as the developer interface because it met the need to support that asynchronous philosophy. The result is that everything in the Node world is asynchronous and asynchronous is the path of least resistance for the developer. Other platforms that weren't conceived with this mindset often force developers to fight to be asynchronous.
> It seems like whether you're aiming for ease/speed of prototyping, pure performance, a good concurrency model...
It's a mistake to look at JavaScript as a fit for all of this. Instead, you should consider how the Node platform fills the need. For easy of prototyping, it's not JavaScript that makes Node excel, it's npm. The only package management system I've found that I prefer to npm is Rust's Cargo. And npm is still well ahead of Cargo in the richness of the package ecosystem. For pure performance, you can always write a native Node addon [2]. And, as mentioned, while JavaScript isn't concurrent at all, the Node platform provides the concurrency model in a way that has proven to be scalable but without most of the pain that comes with writing concurrent code. Writing concurrent code is hard...that's not news. The Node framework make writing concurrent code significantly easier by creating abstractions that hide the the fact that code is concurrent.
I know it's bizarre to look at it this way, since you would be writing most of your application logic in JavaScript, but try to look at it as an implementation detail and consider the advantages of the Node platform and the ecosystem that surrounds it. When you take this perspective, Node becomes a lot more attractive than the JavaScript language is on its own.
Lately rails got their socket support, and python3 has been getting better support through async, but in both those languages, I've long felt its been pretty experimental, and there simply hasnt been a performant option available that has a good opinionated framework.
Nodejs has performance going for it at least if you look at the language benchmarks, and now with ES6, it feels like the language is finally starting to shape up.
(It will. I just want to make sure I do integrated socket support right. I don't want to chase realtime frameworks because that's not Nodal's value prop, but I do want it to be easy to create socket connections when they're needed.)
For me, the jury is still out on whether I will be able to model my domain well in a language like Elixir.. I love Haskell, but I sometimes wonder if its a healthy attitude to be so stubbornly against OO. That said, I understand the arguments against essentially `this` and mutability. Any pointers on how to model your domain model in FP would be really welcome!
One major advantage I can see is if you're a full stack dev. You don't have a switch languages when you're building the backend and the front end. Some people may not see this as an advantage, but personally it takes some time for my brain to switch to javascript for the front end when I've been using either java, python, or ruby for the backend.
The right tool depends on the requirements. If there's no special requirements then I don't see why javascript can't be a substitute for ruby, python, php, or perl on the backend.
> you would use something like couchdb instead of a relational db
I'm not sure this is a good analogy since javascript (as well as the backend languages that it seeks to substitute for) is more of a general purpose tool, and not a super specialized datastore.
out of curiosity, which language + library/framework pairs do you think is a better tool than javascript + nodejs when evaluated along each of your 3 metrics?
I moved from python + flask to nodejs a while ago, I still thing nodejs is better than python + flask, but I'm trying to move away from javascript on the backend.
I should do some real world benchmarks on Elixir vs Go for my own purposes.
But I'd imagine if you really care about microseconds, you should use a language without GC.
Rust would seem a good choice.
ease/speed of prototyping: Ruby (or Python, even), Go, [Crystal]
pure performance: Go, Rust, C++, C, Scala, [Crystal]
a good concurrency model: Erlang, Go, [Crystal (similar to Go)]
A small note about why Crystal is in brackets: The language is very young compared to the rest, and it's currently very volatile in terms of syntax/API stability, or even compiler semantics, but it looks very promising and it's quite easy to get started with it or to become a contributor because the compiler is written in itself. http://crystal-lang.org/ (Sadly, /docs is a bit outdated and misses some crucial parts, but /api is very comprehensive).
I think that this is specially appealing for people that are building offline enabled clients, which end up having to handle more business logic than usual for client-side code.
If you structure your ops to be reorderable and composable you can get nice stuff like multi user editing, arbitrary undo, multi data centre synchronization, etc.
See the google docs papers for more details.
For example I'm taking some front end javascript I've been working on and putting it on the server (using another new node framework based on Laravel that so far I really like: http://adonisjs.com ) and it would definitely perform better if I rewrote it in Go or Elixir - but even if I could figure out how to do that if the thing takes off I could never find anyone to help me with it.
With JS though it should perform reasonably well (node is supposedly pretty fast where it counts, nonblocking and all that) and I could hire a danged high school kid to give me a hand with it if it somehow succeeds. I imagine a company like Walmart was thinking along those same lines when it chose Node.