I hate Node.js

Node.js is cool, so they say. Everybody’s doing it, so I hear.

I hate it. Node.js has wasted so much of my time, I don’t think I will ever forgive it. But take that with a grain of salt. I don’t use Node.js for its intended purpose, which is server-side Javascript.

What I want is a scripting environment for automation on the local machine. In this particular case, I want to script an FTP session from my bash prompt, I want to script a directory sync. I know I can do this with bash scripting, but I already know Javascript syntax and semantics, so I’d like to use what I know. It’s FTP in this case, but in general I want to be able to script arbitrary things on the local machine.

By the way: I can do this on Windows. I can run Javascript programs from the CMD shell, to script an FTP session, automate filesystem operations, launch applications, and a bunch of other things. It’s really nice. There’s a whole catalog of COM objects that can be scripted, including obscure stuff like the fax system in Windows, or more mainstream things like IE settings (like proxies), or IIS administration. Tons of things.

Of course I could do similar things with Node.js on MacOS, too. The problem is, the Node.js model is designed for server use. Everything is asynchronous. When I retrieve a set of files from an FTP server, and I want to iterate and retrieve each file, I have to do that asynchronously. But I don’t want it to be asynchronous. Writing asynchronous code lets me get really good throughput on a server. Writing asynchronous code for my purpose just obscures the goal of the code. I want to do this:

    fileList.forEach(function(item) {
        var modTime = ftp.getModTime(item);
        if (modTime > lastUpdate) {

But I can’t do that. No sir. No I cannot. I’m using Node.js. And because of that, I need this:

    var c = 0, L = flist.length, 
        checkIfDone = function() {
            if (c == L) { next(); }

    fileList.forEach(function(item, ix) {
        var localPath = (dir == '.') ? item : Path.join(dir, item),
            stat, localMtime = ...,
            remoteMtime = 0;

        // get modification time of the remote file
        sync.ftp.raw.mdtm(localPath, function (e, res) {
            var d, tm;
            if (e) { }
            else {
                remoteMtime = new Date(res);
                if (localMtime == 0 || (remoteMtime > localMtime)) {
                    // Retrieve the file using async streams
                    sync.ftp.getGetSocket(localPath, function(e, sock) {
                        if (e) return console.error(e);
                        var fd = fs.openSync(localPath, "w+");

                        // `sock` is a stream. attach events to it.
                        sock.on("data", function(p) {
                            fs.writeSync(fd, p, 0, p.length, null);
                        sock.on("close", function(e) {
                            if (e) return console.error(new Error("error"));

                        // The sock stream is paused. Call
                        // resume() on it to start reading.
                else {

Can anyone ELSE see why I’d rather not use an asynchronous-optimized, server-oriented programming environment to script my desktop?

It’s not Javascript that’s the problem here. I can grab the v8 Javascript engine and use it to run JS code. That works. The problem is that there are no JS libraries for v8. There’s no FTP library. There’s no “any” library. The only FTP libraries I’ve found are Node-compliant. To use it, I have to do Node.js things. Likewise for all the other purposes. There’s no package manager for JS libraries, except for Node.js.

I think the solution here is for me to learn to use Bash scripting and use CURL. But that’s a lame solution. It would be nice if MacOS supported Javascript for client-side use, as nicely as Windows does. Because I hate Node.js.

31 thoughts on “I hate Node.js

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.