All the cool kids love Node.js. I’ve used it a little, and it’s fine; I was able to do what I wanted to do, and it wasn’t particularly painful. It’s fun to use something new, and it’s relatively straight-forward to get started so it’s an emotionally satisfying experience.
There are several reasons you might want to use Node.js, and I’ll ignore many of them, but I want to talk about one in particular:
Javascript on the client and the server!
Is this such a great feature? I think not…
You only need to know one language!
Sure. Yay ignorance! But really, this is fine but unlikely to be relevant to any current potential audience for Node.js. If you are shooting for an very-easy-to-learn client-server programming system, Node.js isn’t it. Maybe Couch or something similar has that potential? But I digress.
It’s not easy to have expertise at multiple languages. But it’s not that hard. It’s considerably harder to have expertise at multiple platforms. Node.js gives you one language across client and server, but not one platform. Node.js programming doesn’t feel like the browser environment. They do adopt many conventions when it’s reasonable, but even then it’s not always the case — in particular because many browser APIs are the awkward product of C++ programmers exposing things to Javascript, and you don’t want to reproduce those same APIs if you don’t have to (and Node.js doesn’t have to!) — an example is the event pattern in Node, which is similar to a browser but less obtuse.
You can work fluidly across client and server!
If anything I think this is dangerous rather than useful. The client and the server are different places, with different expectations. Any vagueness about that boundary is wrong.
It’s wrong from a security perspective, as the security assumptions are nearly opposite on the two platforms. The client trusts itself, and the server trusts itself, and both should hold the other in suspicion (though the client can be more trusting because the browser doesn’t trust the client code).
But it’s also the wrong way to treat HTTP. HTTP is pretty simple until you try to make it simpler. Efforts to make it simpler mostly make it more complicated. HTTP lets you send serialized data back and forth to a server, with a bunch of metadata and other do-dads. And that’s all neat, but you should always be thinking about sending information. And never sharing information. It’s not a fluid boundary, and code that touches HTTP needs to be explicit about it and not pretend it is equivalent to any other non-network operation.
Certainly you don’t need two implementation languages to keep your mind clear. But it doesn’t hurt.
You can do validation the same way on the client and server!
One of the things people frequently bring up is that you can validate data on the client and server using the same code. And of course, what web developer hasn’t been a little frustrated that they have to implement validation twice?
Validation on the client is primarily a user experience concern, where you focus on bringing attention to problems with a form, and helping the user resolve those problems. You may be able to avoid errors entirely with an input method that avoids the problem (e.g., if a you have a slider for a numeric input, you don’t have to worry about the user inputing a non-numeric value).
Once the form is submitted, if you’ve done thorough client-side validation you can also avoid friendly server-side validation. Of course all your client-side validation could be avoided through a malicious client, but you don’t need to give a friendly error message in that case, you can simply bail out with a simple 400 Bad Request error.
At that point there’s not much in common between these two kinds of validation — the client is all user experience, and the server is all data integrity.
You can do server-side Javascript as a fallback for the client!
Writing for clients without Javascript is becoming increasingly less relevant, and if we aren’t there yet, then we’ll certainly get there soon. It’s only a matter of time, the writing is on the wall. Depending on the project you might have to put in workarounds, but we should keep those concerns out of architecture decisions. Maintaining crazy hacks is not worth it. There’s so many terrible hacks that have turned into frameworks, and frameworks that have justified themselves because of the problems they solved that no longer matter… Node.js deserves better than to be one of those.
In Conclusion Or Whatever
I’m not saying Node.js is bad. There are other arguments for it, and you don’t need to make any argument for it if you just feel like using it. It’s fun to do something new. And I’m as optimistic about Javascript as anyone. But this one argument, I do not think it is very good.
Automatically generated list of related posts:
- Javascript Status Message Display In a little wiki I’ve been playing with I’ve been...
- The Web Server Benchmarking We Need Another WSGI web server benchmark was published. It’s a decent...
- Weave: valuable client-side data I’ve been looking at Weave some lately. The large-print summary...
- Atompub & OpenID One of the thinmgs I would like to do is...
Finally, a voice of sanity.
y’know, I always thought it would be a good idea to share JS code both client and server in theory but I never tried to do it and never really thought it through. I must admit you have some good points here.
I guess it’s only appealing if you’re coming from a language like Java. Otherwise, if you didn’t have to why would you choose to use Javascript… (It’s not a bad language at its core, just too many insanities along with it.)
What do you guys do everything in visual studio or what? Javascript is a fantastic language, having nothing to do with Java.
@Joe whoa there! Michael is just saying that JavaScript (which he well knows is not Java) isn’t as attractive to someone already using a language like, say, Ruby or Python. I am pretty sure the Django programmers I know aren’t about to start using JavaScript for their server-side work any time soon, but many of them know enough about JavaScript to be able to maintain asset catalogs and deliver just the necessary JS code to the client with each page, say. Same goes for the Rails people, I would guess.
JavaScript is an OK language with sensible developers behind it who are trying to make it better. And of course the connection with Java is simply that Java was so hot in 1993/4 that Netscape couldn’t resist trying to tar their new language with the same brush despite obvious dissimilarities.
“the client is all user experience, and the server is all data integrity.” I don’t think about it this way. In both cases, you need to validate the data the same way, you just respond to invalid data differently. Sliders or not, at the end of the day a lot (probably most) of the data from the end user ends up typed into text fields and it needs the same validation in both places. True this is not an enormous benefit, but it’s still a good benefit.
Honestly, node.js does have a lot of buzz, but I don’t think anyone in the community is arguing that the sharing across client/server is a primary cause of the hype. I think folks are excited by the async mindset, high concurrency, general cleverness that is happening around node, with sharing code as a nifty bonus.
But thanks overall, Ian, for a well-written post.
You know, I’ve had a sneaking suspicion that this was the case. I’ve been anxious that it was not, that JS on the client and JS on the server was going to be a killer advantage of Node and make Twisted gradually irrelevant, because Javascript is so damn popular, because deployment is king, and it’s deployed everywhere. Your post has settled my nerves a bit :).
You see, one of the big advantages of Twisted is that you can use Python on the client and Python on the server. I’ve worked on thick client, client-server applications with Twisted, and boy, do I miss it. It’s a really pleasant experience. It dramatically decreases the amount of testing you have to do. It decreases the amount of data modeling you have to do and the proliferation of a million different almost-but-not-quite-the-same data structures. It doesn’t have most of the issues that you’re talking about, because you really can use the same libraries in both places, and you can trivially write new libraries that work in both (because it’s the same Python VM everywhere). I sincerely hope that one day I can replicate that experience with a web browser, by treating the browser as a dumb deployment target and just sending it a bunch of Python code, in the form of x86 code for NaCl, or javascript emitted from PyPy’s not-really-currently-working JS backend, or something like that. Because the browser is what you get to work with in this sad, modern world.
I thought that Node might have beaten us to the punch, and that I’d be fated one day to work on applications in some half-assed server-side JavaScript IDE instead of a nice Twisted environment with all of its attendant features and bells and whistles. This is a very straightforward progression of the worse-is-better phenomenon and it was starting to bum me out a little bit.
But the ray of hope you’ve given me is this: JavaScript is really, really terrible. Like, literally unusably bad; i.e. there are many problems for which you simply cannot use it. In the original worse-is-better scenario, C had all kinds of flaws compared to lisp; its compilers, debuggers, and profilers weren’t as good; there were barely any GUIs by the time all Lisp development was being done on bitmapped displays, and so on. But C (and UNIX) had one killer feature: it got libraries right. You could just smash some C files into a directory, and then re-use them. To quote RPG:
“In the worse-is-better world, integration is linking your .o files together, freely intercalling functions, and using the same basic data representations. You don’t have a foreign loader, you don’t coerce types across function-call boundaries, you don’t make one language dominant, and you don’t make the woes of your implementation technology impact the entire system.”
However, if there’s one key design criterion for browsers, it is making the woes of your implementation technology impact the entire system as much as possible. We’re getting close to 20 years into JavaScript, and still it has no standard - or even widely recognized – notion of a “library” – or even a “main program” beyond “stuff some crud into your DOM, oh and by the way I hope you’re using HTML”. As you’re outlining the practical issues with re-using libraries from the browser, like for example the fact that you can’t actually implement many standard JavaScript features in standard JavaScript (still!), I realize that these concerns are not snobbish aesthetic affectations that I have in my insulated Python mindset, but real issues that affect people trying to use these technologies every day.
I’m sure that this situation can get better (and I hope it does, because I’m sure I’ll have to write browser javascript again at some point in my career), but the fact that it is still this bad after this long is an indication that there’s still a strong livelihood to be had for Python on the internet. Anywhere where the problem is hard enough to actually need a re-usable library that does something more logically challenging than an expando-tab GUI pseudo-widget.
And also, as you point out, it’s not that bad to have to duplicate a little logic for the client. This is also heartening because I would definitely like to be able to leverage the browser platform (at the very least, for the Twisted web site!) and not have maintaining that logic be a total nightmare.
(As long as your client is fairly simple, of course. There are limits. It’s probably possible to compute synchronized 3-dimensional physical simulations, including using dead reckoning to predict the movement of actors across a network boundary, in a library with synchronized implementations in Python and JavaScript, but gee whiz I’m sure glad that’s not my job.)
So thanks for the ray of sunshine; although I guess it will probably look a lot more like doom and gloom for javascript programmers from other vantage points :).
I think the big win for Node.js is that it’s the first non-blocking server to get widespread interest. Obviously Twisted and Tornado have similar advantages, and you can do clever stuff with gevent and gunicorn and similar greenlet-based stuff and not even have to know that it’s non-blocking, but none of them have had the levels of popular interest that they deserve. Perhaps Django’s (well-deserved) dominance of the Python web space holds them back?
Node.js, on the other hand, perhaps because it’s interesting to all of the JS people who aren’t willing to learn other languages, and is the only popular JS server, is exposing non-blocking server IO to many more people. On the other hand, given the “not willing to learn other languages” thing, perhaps that’s not a plus.
It’s not my impression that people using Node are adverse to learning other languages. Many are comfortable with async callback-based programming from the browser (which works the same way). I think there’s actually a lot of positive work in the Node community to make Javascript programming more reasonable, and it shows the maturity of work done by people familiar with many other environments (while still trying to be aesthetically true to Javascript’s nature).
Sorry, I was unclear. A lot of people who don’t want to learn languages other than JavaScript have been drawn to server programming because of the existence of Node.js, so there are a lot of monoglots among its users. But that’s not to say that all Node.js users are monoglot. It’s a unidirectional implication.
“so there are a lot of monoglots among its users”
Do you have any evidence to back up that statement?
Anecdotally, that has been untrue in my experience. In fact, it’s more the opposite. The people I’ve met who use Node.js are some of the most versatile and well-rounded developers I know. Most of them are trying out Node.js, because they are interested in how it compares to another solution they’re currently using. I see mostly people from the Python community but also devs from Ruby and JVM (Scala/Clojure).
I’m not saying you’re wrong, but the monoglot statement does not fit with my experience — admittedly with a small sample.
Interesting. I first heard about Node.js from people who regarded themselves as “JavaScript guys” and liked the idea of it because they’d not need to learn another programming language to do server programming. (BTW when I say “monoglot” I mean just that they only know one language fluently, they doubtless learned other languages when kids/at school/uni — just as I’m monoglot in human languages despite having learned French and German at school.)
But perhaps when I said “a lot” I was overgeneralising from my own experience.
“You can do server-side Javascript as a fallback for the client!” “Writing for clients without Javascript is becoming increasingly less relevant” Really? Are you serious? How many mobile devices out there have a crap experience? Most of them. IE6? Forget about it. Yeah they have js, but only just, using node.js to serve up static resources is an awesome option for those cases, and the more devices that get online, the more feature rich websites get, the more compelling this becomes
Good points in the article but one note;
ECMA proxies are definitely not an
unimplementable
api in Node.In fact Node was designed to be extensible in just this way. isaacs has created Node extension that implements most of the Harmony proxies API: https://github.com/isaacs/node-proxy
I think this is a very well written albeit severely misguided post.
Re: You Only Need To Know One Language:
Like it or not this is less cognitive load, no matter how good a programmer you think you are.
Re: You Get to Share Libraries
You conveniently miss the reality that there are already hundreds of high quality and useful libraries that work on both the client and the server. To name a few: jQuery, YUI, Underscore.js, Require.js, Processing.js….
The argument that browser APIs are different is irrelevant. The vast majority of browser API landscape is available on the server-side e.g. JSDom (full Dom on the server), node-canvas (full canvas tag API on the server).
Re: You can work fluidly across client and server
If you require a language barrier to make you think about implementing security constraints between the client and the server then you have far greater things to worry about when it comes to security: i.e. incompetence.
Re: You can do validation the same way on the client and server!
Yes validation on the client is a user experience concern. Its great to be able to fully inform the user of any issues before having to wait for requests to the server-side. This allows real-time validation for free. I really don’t get your point here. What the problem?
Re: You can do server-side Javascript as a fallback for the client!
Two things immediately come to mind: 1. SEO e.g. Google indexing an RAI 2. blind people (no ARIA etc is not always adequate).
I don’t think anyones trying to dismiss Ruby, Python, Scala, Erlang, Haskell, LOLcode… whatever… as irrelevant on the server because of JavaScript. All the best to those communities, if it works for you – great =D.
Many people however do find full stack JavaScript to be an awesome environment to work in. Including many new developers who come from other walks of life and don’t want the overhead of learning multiple languages straight away. Spreading FUD, or simply misguided non-factual unfounded opinion, helps nobody.
Well, I won’t reply because I’ve made my statement and people can judge on their own. But your snide conclusion is unnecessary, and is no small part of why I will refrain from further engaging with your arguments.
Agreed the LOLcode was in bad taste. My sincere apologies for that. April fools sillyness gone wrong.
Regardless my remaining points are factual as far as I am aware.
No ones trying to attack existing server-side languages and say you should only use JavaScript. Yet for some reason you feel you must attack JavaScript and as I outlined above I don’t believe any of your points, albeit well said, are an actual reflection of reality.
While @JSNinjaTrainer is technically correct that Ian’s post is not at all accurate the negativity is unnecessary. The comment unfortunately is a disservice to an otherwise sound argument and those who would stand beside it.
JSNinjaTrainer, some of your counterpoints are valid, but some are kind of contradictory. Here are two points you made:
Re: You Only Need To Know One Language: “Like it or not this is less cognitive load….” Re: You can work fluidly across client and server: “If you require a language barrier … i.e. incompetence.”
So it’s okay and desirable in the first case to seek less cognitive load, but the desire for less cognitive load in the second case is a mark of incompetence? Couldn’t you just as easily say that a client/server language barrier is less cognitive load? Or (if you want to be negative) that only knowing one language is a mark of incompetence?
@Will, first thank you for a constructive reply to a somewhat non-constructive comment!
I think “You Only Need To Know One Language” would be better labelled “You Only Need To Program Your Application In One Language”, excluding HTML & CSS which are domain specific of course. This is less cognitive load as I find it easier to focus on solutions rather than “context switching” between two quite different languages on the client and server.
> Couldn’t you just as easily say that a client/server language barrier is less cognitive load?
Yes good point. I think my point on client-server separation for security was not well made.
If your using a language barrier to implement security your possibly thinking (in the context of security) about two things: the security AND the different language. Whereas with a single language stack you only need to focus on one thing: security.
Simply ignoring security because there is no language barrier, or alternatively relying solely on a language barrier for security, would be incompetence.
Having a language barrier yet still thinking about security concerns would, I concede, be a matter of personal preference, and not a sign of any incompetence.
> that only knowing one language is a mark of incompetence?
Yes it would at least big a strong warning sign. Personally I know enough C, PHP, Ruby, Java and JS to not be limited by the language when writing any program in any of those, as well as a whole range of DSLs. Yet I still prefer a single language stack and knowing those other languages most definitely improves my JS code.
It may not always be possible for a beginner to learn so many languages, which I believe is one case that can benefit greatly from single language stacks e.g. teaching web programming courses that include both the client and server-sides.
Again thanks for the constructive points! I regret getting annoyed by the rampant inaccuracy of the post and not starting a more constructive debate.
I wonder if these same points would be made if people had the ability to do in all the browsers and started using full python stacks ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
opps filter stripped out my script tags, last sentence of last post should have read:
I wonder if these same points would be made if people had the ability to do script type=text/python in all the browsers and started using full python stacks ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
For some reason my comment earlier disappeared so re-posting…
While @JSNinjaTrainer is technically correct that Ian’s post is far from accurate the negative tone is unnecessary. The comment is unfortunately a disservice to an otherwise sound argument and those who would stand beside it.
It’s almost off-topic. Nobody talks about other scripting language in the browser that’s a big question imo. Most people learned javascript but still – who won’t agree – it’s an hard language to start with, and further doing complex thing is still hard. Just like PHP for the server side, it’s good at some point then people have to move on to increase their possibilities/productivity/maintenability. I’m not monoglot, so don’t. Is is that hard to get python in the browser for real ?
It’s another extended discussion, but I don’t expect to ever see Python on the browser, nor do I think it would be a useful idea to pursue. Maybe someday there will be a place for another language in the browser besides Javascript, but I expect it to be a language designed for that purpose rather than a language ported into the browser. CoffeeScript at least hints at what that might look like, though it’s hard to really see CoffeeScript as more than a light syntax remodeling for Javascript. But maybe it’s a step on the way to a viable spectrum of browser-based languages.
I think .NET and the CLR is a good piece of evidence for this generally: it supports multiple languages, and great effort has been put into this, but ultimately all the successful languages have been new languages designed to fit the environment; ported languages (e.g., IronPython) haven’t been very successful and I don’t have any faith in their long-term viability.
(My opinion is also based on a bunch of very concrete issues with Python in the browser, but that’s where the discussion becomes extended ;)
Indeed, Node and browser-land are different platforms, and this, to me, is the only real concrete argument for why javascript everywhere isnt a huge win v. the existing joint different language and different platform combo existing setups present. However there are numerous shims/polyfills out there to bridge these differences. env-js, crosscheck, and jsdom are three various efforts to get the DOM usable as ssjs. browser-shim, gemini exist to bring the node platform into browser space. JS is a flexible enough language that these or most any inherent platform differences can be paved over. No, it’s not easy to cleanly harness these different pieces, to cobble together a well working Frankenstein dual-platform, but SSJS is still at its inception… well, LiveWire, circa `96, aside. What’s hard now will only get easier and more natural. The tooling is being birthed as we speak here.
I’d really like elaboration on what you’re attempting to refute in “You can work fluidly across client and server!”. Can you name some existing projects which purport to do this, or cite any cases where you feel the distribution boundaries between client and server have been made too thin? I’m trying to wrap my head around what is being refuted here; it’s not clear what arguments and examples you are writing in reply to.
What about other non-JS server stacks, which of them go too far in mixing server and client state into one undecypherable intractable ball (in violation of the primary directive of distributed computing)? Was ASP.NET a bridge too far? Rails’ JS integration? And does the mere presence of JS on both sides imply this muddling has already happen, that work is being done too fluidly, code or state shared in some insecure or ill conceived manner?
I’d throw the following into the “pro” side of using JS everywhere: extensions/polyfills like underscore or kaffeine, solved native ser/deser (JavaScript Object Notation), being able to leverage the same documentation frameworks (JSDoc, Doxygen), code style policies, and code quality checks (JSLint). javascript everywhere can be a huge advantage.
From a writing perspective, the conclusion could be a lot more effective, IMO. “But this one argument, I do not think it is very good,” is a weakly linked to the topic, mentioned only at the top (“Javascript on the client and the server!”) and doesnt really draw together what the goal of client and the server both would be and how your arguments against work out.
Mostly, I think this is a result of insufficient exploration of the problem space; what “Javascript on the client and server” is purported to provide isnt linked or discussed anywhere. Instead the conclusion is left to refute a wide focus of things never defined in the first place. Over half the time I’m under the impression this article is an argument against “dual sided” templating/ajax, but the conclusion wanders back to node as webapp framework, which in many cases is altogether very different.
I’m disappointed in what I perceive as your over-reaction to JSNinjaTrainer, Ian. In spite of his flippant uncalled for ending, the majority of his post was a well reckoned technical rebuttal, one I agree with in quite a few places, and think deserves more discussion. Cutting it short on account of injury is a disservice to the discussion you welcomed in by creating this post. I’d encourage you to move past the injurious LOLCode, which has been apologized for.
Things like server-side DOM are largely for this purpose, except insofar as they are intended to support testing (though testing seems like the majority of uses in what I’ve seen). Well… there are entirely distinct ways to use the DOM as well (e.g., spidering) which don’t rely on client-server integration. Ironically Javascript has generally had really terrible HTML handling (no freakin’ parser!) so at this point it’s still playing catch-up. (But unlike in other languages communities I think the audience will be more inclined to make full use of what it has once it does catch up.)
But you are right that I am refuting a vaguely stated argument — I don’t think I’m imagining the argument, but it’s the feeling I get from a lot of people I personally know who become excited about Node. This excitement is vague because it’s usually not about what they are concretely making, but about their excitement about what they could make with Node. So it’s not like people are making studious arguments about the benefits of Node, nor am I claiming all their enthusiasm is misguided (and it’s fine to be enthusiastic without any justification whatsoever!), but at least on this count I am skeptical.
And in these personal discussions the idea of Javascript on the server and client is clearly a feature of people’s excitement.
Yes, and I abhor this cleverness in other languages even more than in Javascript ;)
IMHO good sharing across systems is done with documents (JSON being a perfectly good document syntax). Frequently the documents are shared over HTTP… but even in Javascript the IPC I’ve seen has been mostly text-based (typically with JSON layered on top, much like HTTP). Once you are doing this level of abstraction it’s pretty much as easy to communicate with other languages as with Javascript, all the dynamic languages handle JSON well.
I found his entire post snide, and his argument style is one that I find if I engage with only leaves me pointlessly frustrated. But I’ve considered revisiting it with an answer.
Like many parts of the Javascript community that are forming, the tone of the Javascript community is still to be defined. Now is a time when it would be good to be conscious of that tone.
Every application has a common set of code needed to be run on the server and the client. All apps I wrote needed this, I can hardly imagine other apps don’t. Therefore, there’s always a shared library between client and server. At least for the data definitions.
Your article does have a point, but I would have to disagree with the conclusion.
I’m a hardcore C++ desktop apps programmer and have been for the last 15 years – web development is not my primary occupation, but I’ve done it a lot and I like it. And from everything I’ve tried so far on the server-side (Visual Basic .exe CGI’s in the 90′s, ASP, JSP, Perl, PHP, FastCGI modules), nodejs experience is very refreshing and productive.
In the case of nodejs, it is not necessarily the Javascript everywhere that is the attractor for me. It is the speed of that thing, code re-use between the browser/server and no context-switching between languages. The async API of nodejs makes it a bit unpleasant — all those callbacks and callbacks within callbacks are at some point quite horrible.
But I spent 2 days and learned CoffeeScript and node.js experience (as well as browser js experience) has improved dramatically. With CoffeeScript you get the clean syntax of Python/Ruby, the flexibility of Javascript and the speed of nodejs.
So instead of Javascript everywhere, I would vote for CoffeeScript everywhere :).
that’s why I use vbScript on the client and vbScript on the server! Dead serious, it’s totally worth it!