← Back to expressjs/express

How to Deploy & Use expressjs/express

Express.js Deployment & Usage Guide

Prerequisites

  • Node.js: Version 18.x LTS or higher (required for node: prefixed core modules)
  • npm: Version 8.x or higher (included with Node.js)
  • Git: For cloning repositories (if developing Express or using version control)

Installation

For Application Development

Create a new project and install Express as a dependency:

mkdir myapp
cd myapp
npm init -y
npm install express

For Framework Development (Contributing)

Clone the repository and install dependencies:

git clone https://github.com/expressjs/express.git
cd express
npm install

Configuration

Environment Variables

VariableDescriptionDefault
NODE_ENVApplication environment (development, production, test)development
DEBUGEnable debug logging (e.g., express:* or express:application)unset

Application Settings

Configure via app.set() or app.enable():

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

// Core settings (from lib/application.js)
app.set('env', process.env.NODE_ENV || 'development');
app.enable('x-powered-by');        // Adds X-Powered-By: Express header
app.enable('case sensitive routing'); // URL case sensitivity
app.enable('strict routing');      // Trailing slash sensitivity

// Trust proxy configuration (from lib/utils.js compileTrust)
app.set('trust proxy', true);      // Trust X-Forwarded-* headers
app.set('trust proxy', 'loopback'); // Trust specific IP ranges

View Engine Configuration (lib/view.js)

// Configure template engines
app.set('views', './views');           // Templates directory
app.set('view engine', 'pug');         // Default engine

// Register custom engines
app.engine('html', require('ejs').renderFile);

Router Configuration

// Router options (from lib/application.js)
app.set('case sensitive routing', true);  // Default: false
app.set('strict routing', true);          // Default: false

Build & Run

Development Mode

# Start with debugging enabled
DEBUG=express:* node app.js

# Or using npm scripts (add to package.json)
npm start

Basic Application Structure (app.js):

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Routes
app.get('/', (req, res) => {
  res.status(200).send('Hello World');
});

// Error handling (uses finalhandler as seen in lib/application.js)
app.listen(port, () => {
  console.log(`Server running on port ${port} in ${app.get('env')} mode`);
});

Production Mode

# Set environment and start
NODE_ENV=production node app.js

Production Best Practices:

  • Disable x-powered-by to obscure framework identity: app.disable('x-powered-by')
  • Enable trust proxy if behind a load balancer: app.set('trust proxy', true)
  • Use req.ip and req.ips (populated via proxyaddr from lib/request.js) for client IP detection

Deployment

Platform: Node.js Hosting (Heroku, Railway, Render)

# Ensure package.json has start script
"scripts": {
  "start": "node app.js"
}

# Deploy via Git
git push heroku main

Platform: Docker

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]

Build and run:

docker build -t my-express-app .
docker run -p 3000:3000 -e NODE_ENV=production my-express-app

Platform: VPS/Server (PM2)

Install PM2 for process management:

npm install -g pm2
pm2 start app.js --name "api" -i max
pm2 save
pm2 startup

Platform: Serverless (AWS Lambda)

Use serverless-http wrapper:

const serverless = require('serverless-http');
module.exports.handler = serverless(app);

Troubleshooting

Status Code Errors (lib/response.js)

Error: TypeError: Invalid status code: "200". Status code must be an integer.

Solution: Ensure status codes are integers, not strings:

// Wrong
res.status("200").send();

// Correct
res.status(200).send();

Error: RangeError: Invalid status code: 1000

Solution: Use valid HTTP status codes between 100-999 inclusive (enforced by Node.js HTTP module).

View Engine Errors (lib/view.js)

Error: No default engine was specified and no extension was provided.

Solution: Set default engine or provide file extension:

app.set('view engine', 'ejs');
// OR
res.render('index.ejs');

Error: Module "pug" does not provide a view engine.

Solution: Install the template engine package:

npm install pug

Routing Issues

Issue: Routes not matching case-sensitive paths

Solution: Enable case-sensitive routing before defining routes:

app.enable('case sensitive routing');
// Must be set before route definitions

Debug Logging

Enable internal Express debugging:

# All Express debug logs
DEBUG=express:* node app.js

# Specific components (application, router, view)
DEBUG=express:application,express:view node app.js

Port Already in Use

# Find and kill process using port 3000
lsof -i :3000
kill -9 <PID>

# Or use different port
PORT=3001 node app.js