What does "./bin/www" do in Express 4.x?

In Express 3.0, you normally would use app.configure() (or app.use()) to set up the required middleware you need. Those middleware you specified are bundled together with Express 3.0.

Example:

var express = require('express');
var routes = require('./routes');
var user = require('./routes/user');
var http = require('http');
var path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.compress());
app.use(express.json());
app.use(express.urlencoded());
app.use(express.methodOverride());

In Express 4.0 however, all middleware have been removed so that they can be maintained and updated independently from the core Express (except the static middleware), thus they need to be called separately (what you see in app.js).

The bin/ directory serves as a location where you can define your various startup scripts. The www is an example to start the express app as a web server.

Ultimately, you could have different scripts like test, stop, or restart, etc. Having this structure allows you to have different startup configurations, without cramming everything into app.js.

The correct way to start your Express app is:

npm start

To deploy an Express 4.x app to Heroku, add this to your Procfile:

web: npm start

Or if you can just use the start script in your package.json, heroku will automatically uses that, read more here

"scripts": {
    "start": "node ./bin/www",
}

Node apps like the Express 3.x use non-standard startup files app.js, but it's the wrong file to run.

package.json has

   "scripts": {
     "start": "node ./bin/www"
   }

which states the startup command line. It’s non-trivial because that potentially contains a full command line, and not just a path to the starter file.