Hosting express node.js applications in IIS using iisnode

Hero Image

In my last two posts I introduced the iisnode project which allows hosting node.js applications in IIS on Windows, as well as shown how it integrates with the URL rewrite module. In this post I demonstrate how to run node.js applications that use the popular express framework in IIS.

Installing express on Windows

Node.js modules, including express, are typically installed using NPM. The bad news is that as of this writing NPM is not yet supported on Windows. The good news is that for simple cases one can use the script. Assuming you have Python installed, you can call: install express

which will create the node_modules folder with the downloaded express library. You can check out the resulting layout here.

The code

A simple express application we will host in IIS looks like this:

 var express = require('express');

 var app = express.createServer();

 app.get('/node/express/hello/foo', function (req, res) {
     res.send('Hello from foo! [express sample]');

 app.get('/node/express/hello/bar', function (req, res) {
     res.send('Hello from bar! [express sample]');


Two key aspects to call out that may be different from your bread & butter express app are:

  1. The path specified in app.get calls must be the full path of the request (lines 5 and 9). When your app is hosted in IIS, depending on the configuration you may not necessarily own the entire namespace over port 80. Like in the example above, your IIS hosted express application may reside in the ‘express’ folder of  the ‘node’ virtual directory, and only own the subordinate URL namespace.
  2. Similarly to a non-express node.js app hosted in iisnode, the listen port is provided by IIS through the PORT environment variable. When you start your listener (line 13), this is the port you should specify.

The web.config

I talked about using the URL rewrite module for regular node.js applications before, and URL rewriting is perhaps even more relevant in case of URL-conscious express apps. The web.config below allows the express application saved in hello.js to receive HTTP requests directed at all URL paths subordinate to the ‘hello’ path component, as configured in lines 20-27:


     <!-- indicates that the hello.js file is a node.js application 
     to be handled by the iisnode module -->

       <add name="iisnode" path="hello.js" verb="*" modules="iisnode" />

     <!-- use URL rewriting to redirect the entire branch of the URL namespace
     to hello.js node.js application; for example, the following URLs will 
     all be handled by hello.js:

         <rule name="hello">
           <match url="hello/*" />
           <action type="Rewrite" url="hello.js" />

     <!-- exclude node_modules directory and subdirectories from serving
     by IIS since these are implementation details of node.js applications -->
           <add segment="node_modules" />

One other aspect worth pointing out is request filtering. Remember the express application relies on the express library installed in the node_modules directory? You probably don’t want the contents of this directory to be served by IIS in any shape or form, and you can express (sic!) that desire by adding it to hidden segments list (lines 32-38).


Your IIS-hosted express node.js application behaves like expected:



So where can I get iisnode again?

Everything you need to get started is at Make sure to check out the express sample. Feedback welcome!


Related Content

2 February 2022
fetch() In Node.js Core: Why You Should Care

Node 17.5 introduces support for the fetch() HTTP client, a new way to send requests to HTTP APIs.

23 February 2022
Node.js Adds Support for Direct Registry-less HTTPS Imports

Node is planning to introduce support for HTTPS imports in Node 18 - a feature that enables you to use urls to directly import modules over HTTPS into your project.

15 February 2022
Run Every Node.js Version in AWS Lambda

Run any version of Node.js in AWS Lambda within hours after release using custom AWS Lambda runtimes from Fusebit