Solution 1:

phantomjs-node isn't an official supported npm package for phantomjs. Instead, it implements a "nauseously clever bridge" between node and phantom by creating a web server that uses websockets to serve as an IPC channel between node and phantom. I'm not making this up:

So we communicate with PhantomJS by spinning up an instance of ExpressJS, opening Phantom in a subprocess, and pointing it at a special webpage that turns socket.io messages into alert() calls. Those alert() calls are picked up by Phantom and there you go!

So I wouldn't be surprised if phantomjs-node works, doesn't work, fails silently, or fails spectacularly. Nor would I expect anyone other than the author of phantomjs-node to be able to troubleshoot phantomjs-node.

The answer to your original question is the answer from the phantomjs faq: No. Phantom and node have irreconcilable differences. Both expect to have complete control over fundamental low-level functionality like the event loop, the network stack, and JS execution so they can't cooperate within the same process.

Solution 2:

You could also give phridge a try. Your example would've been written like this:

var phantom;

// spawn a new PhantomJS process
phridge.spawn()
    .then(function (ph) {
        phantom = ph;
        return phantom.openPage("http://www.google.com");
    })
    .then(function (page) {
        return page.run(function () {
            // this function runs inside PhantomJS with this bound to a webpage instance
            return this.title;
        });
    })
    .then(function (title) {
        console.log('Page title is ' + title);
        // terminates the process cleanly
        phantom.dispose();
    });

Solution 3:

I am now the new maintainer for phantom-node package. It doesn't use coffeescript anymore. You can do something like

var phantom = require('phantom');

phantom.create().then(function(ph) {
  ph.createPage().then(function(page) {
    page.open('https://stackoverflow.com/').then(function(status) {
      console.log(status);
      page.property('content').then(function(content) {
        console.log(content);
        page.close();
        ph.exit();
      });
    });
  });
});

The new version is much faster and resilient. It also doesn't use websockets anymore.