642

This may be a very basic question but I simply don't get it. What is the difference between creating an app using Express.js and starting the app listening on port 1234, for example:

var express = require('express');
var app = express();

//app.configure, app.use etc

app.listen(1234);

and adding an http server:

var express = require('express');
var http = require('http');

var app = express();
var server = http.createServer(app);

//app.configure, app.use etc

server.listen(1234);

What's the difference?
If I navigate to http://localhost:1234, thus I get the same output.

Mike
  • 14,010
  • 29
  • 101
  • 161
Tamas
  • 10,953
  • 13
  • 47
  • 77
  • 7
    I realize this question is old but I want to note, createServer has been depreciated. – Philip Kirkbride Dec 12 '16 at 13:06
  • 2
    @PhilipKirkbride can You, please, provide proof? – yanot Dec 25 '17 at 02:19
  • 31
    @PhilipKirkbride I believe that's a somewhat misleading statement. ExpressJS's createServer() method has been deprecated, but the Node.js HTTP module still uses createServer() and that is *not* deprecated. – Tamas Dec 27 '17 at 09:27

6 Answers6

765

The second form (creating an HTTP server yourself, instead of having Express create one for you) is useful if you want to reuse the HTTP server, for example to run socket.io within the same HTTP server instance:

var express = require('express');
var app     = express();
var server  = require('http').createServer(app);
var io      = require('socket.io').listen(server);
...
server.listen(1234);

However, app.listen() also returns the HTTP server instance, so with a bit of rewriting you can achieve something similar without creating an HTTP server yourself:

var express   = require('express');
var app       = express();

// app.use/routes/etc...

var server    = app.listen(3033);
var io        = require('socket.io').listen(server);

io.sockets.on('connection', function (socket) {
  ...
});
robertklep
  • 198,204
  • 35
  • 394
  • 381
  • 4
    so require('http").createServer(require("express")).listen(80) is === require("express")().listen(80)? – user2167582 Aug 06 '14 at 04:46
  • 14
    @user2167582 the effect is the same, yes, but of course a literal `===` comparison would fail ;) If you don't believe me, [there is always the source](https://github.com/strongloop/express/blob/3e4158bcbda7017dbe7226fb76d974bd95c29ce9/lib/application.js#L540). – robertklep Aug 06 '14 at 12:47
  • 10
    Question wasn't about sockets but that's totally why I came here – anthonygore Aug 22 '16 at 22:59
  • 1
    is `var socketio = require('socket.io')` on the third line necessary in your rewrite? – davidx1 Oct 14 '16 at 06:07
  • 1
    when i want use `https`,what i should to do? –  Oct 23 '16 at 08:41
  • @AlirezaValizade that's documented [here](http://expressjs.com/en/api.html#app.listen). – robertklep Oct 23 '16 at 09:03
  • 1
    pro and cons of each? – Tanner Summers Dec 29 '16 at 07:48
  • 5
    @TannerSummers I practically always use `app.listen()` because it requires less code. Since it's only a very thin layer on top of `server.listen()`, and it returns the server instance, there's generally no reason to create a separate HTTP server instance manually. – robertklep Dec 29 '16 at 08:51
  • 1
    @robertklep - I came to this thread because I was using websockets with Apollo server. In this case it's necessary. I actually wish this didn't exist in express since it's such an easy thing to understand if pointed out. – Zach Smith Apr 14 '20 at 06:10
  • @robertklep, do you need to use createServer for deployment on ec2? Or will app.listen work as well? I find that using createServer yields a much slower response for some reason. – Reine_Ran_ Jan 25 '21 at 15:19
  • 1
    @Reine_Ran_ I assume that Express calls `createServer` under the hood, so I can't explain why `app.listen()` would be faster than creating a server instance manually. I always use `app.listen()` anyway because it's shorter ;D – robertklep Jan 25 '21 at 15:23
  • @robertklep like app.listen instead of server.listen? – Reine_Ran_ Jan 25 '21 at 15:25
  • @Reine_Ran_ yes, sorry about the confusion. Edited my comment. – robertklep Jan 25 '21 at 15:26
  • wait sorry @robertklep is it correct to say that createServer is mainly used for accessing the https module of node.js? Like var httpsServer = https.createServer(credentials, app); then httpsServer.listen(portNum)? Otherwise server.listen() and app.listen() makes no difference? – Reine_Ran_ Jan 25 '21 at 15:40
  • 2
    @Reine_Ran_ basically, yes. `app.listen()` (Express) will create a regular HTTP server (by using `http.createServer()`); if you want to run Express over HTTPS, you need to use `https.createServer()` separately and "attach" Express to it (or use a separate HTTPS server like nginx as an HTTPS terminator). – robertklep Jan 25 '21 at 15:57
86

There is one more difference of using the app and listening to http server is when you want to setup for https server

To setup for https, you need the code below:

var https = require('https');
var server = https.createServer(app).listen(config.port, function() {
    console.log('Https App started');
});

The app from express will return http server only, you cannot set it in express, so you will need to use the https server command

var express = require('express');
var app = express();
app.listen(1234);
Tim
  • 3,755
  • 3
  • 36
  • 57
64

Just for punctuality purpose and extend a bit Tim answer.
From official documentation:

The app returned by express() is in fact a JavaScript Function, DESIGNED TO BE PASSED to Node’s HTTP servers as a callback to handle requests.

This makes it easy to provide both HTTP and HTTPS versions of your app with the same code base, as the app does not inherit from these (it is simply a callback):

var https =require('https');
var http = require('http');
http.createServer(app).listen(80);
https.createServer(options, app).listen(443);

The app.listen() method returns an http.Server object and (for HTTP) is a convenience method for the following:

app.listen = function() {
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};
Shalabyer
  • 555
  • 7
  • 23
Ivan Talalaev
  • 6,014
  • 9
  • 40
  • 49
  • 5
    Please explain a little bit more on the second piece of code.What exactly do you mean by a convenience method here? – Aakash Verma Jul 12 '17 at 11:42
  • 2
    @AakashVerma this is just a piece of exress's source code which can be found in `express/lib/appplication.js` and nothing more than shortcut to create node's http server. – Ivan Talalaev Jul 12 '17 at 12:47
  • So you mean to say that when we use app by express() as a callback, it receives the request from the outer HTTP server (through either 80 or 443) and then creates another virtual server http.Server within itself and uses it to listen to the requests forwarded to it? – Aakash Verma Jul 13 '17 at 06:36
  • `var https = require('https'); var http = require('http');` – Shalabyer Sep 19 '21 at 19:46
16

I came with same question but after google, I found there is no big difference :)

From Github

If you wish to create both an HTTP and HTTPS server you may do so with the "http" and "https" modules as shown here.

/**
 * Listen for connections.
 *
 * A node `http.Server` is returned, with this
 * application (which is a `Function`) as its
 * callback. If you wish to create both an HTTP
 * and HTTPS server you may do so with the "http"
 * and "https" modules as shown here:
 *
 *    var http = require('http')
 *      , https = require('https')
 *      , express = require('express')
 *      , app = express();
 *
 *    http.createServer(app).listen(80);
 *    https.createServer({ ... }, app).listen(443);
 *
 * @return {http.Server}
 * @api public
 */

app.listen = function(){
  var server = http.createServer(this);
  return server.listen.apply(server, arguments);
};

Also if you want to work with socket.io see their example

See this

I prefer app.listen() :)

Muhammad Shahzad
  • 9,340
  • 21
  • 86
  • 130
13

Express is basically a wrapper of http module that is created for the ease of the developers in such a way that..

  1. They can set up middlewares to respond to HTTP Requests (easily) using express.
  2. They can dynamically render HTML Pages based on passing arguments to templates using express.
  3. They can also define routing easily using express.
Sarim Javaid Khan
  • 810
  • 15
  • 30
-1

The http module is no longer needed, unless you need to directly work with it (socket.io/SPDY/HTTPS). The app can be started by using the app.listen() function.

expressjs.com

Tyler2P
  • 2,324
  • 26
  • 22
  • 31
Lan
  • 1
  • 2
  • https://meta.stackoverflow.com/a/285557/11107541, [/help/formatting](/help/formatting), [/help/referencing](/help/referencing). – starball Jul 07 '23 at 08:26