bg-tutorials

How to Install an SSL Certificate on Node.js

In this tutorial, you will learn how to install an SSL certificate on Node.js using the built-in https module. Unlike a web server such as Apache or Nginx, Node.js loads your certificate, private key, and CA chain directly in JavaScript, so the “installation” happens inside your application code.

Generate a CSR code in Node.js

If you haven’t applied for an SSL certificate yet, you first need to generate a CSR (Certificate Signing Request). The CSR is a small encoded text block that contains your contact details and public key, and you submit it to the Certificate Authority when you order. You have two options:

Submit the CSR to the Certificate Authority during your order. After the CA validates it and issues your SSL certificate, continue with the installation below.

Install an SSL certificate on Node.js

Step 1: Prepare your certificate files

After validation, the Certificate Authority emails you the certificate files. Extract the archive. You should have:

  • yourdomain.crt, your primary domain certificate.
  • yourdomain.ca-bundle, the intermediate (and root) certificates that make up the CA bundle.
  • yourdomain.key, the private key you generated along with the CSR.

Browsers must receive the intermediate chain, not just your domain certificate, or some clients will reject the connection. The cleanest way to serve the chain in Node.js is to combine your certificate and CA bundle into a single full-chain file:

cat yourdomain.crt yourdomain.ca-bundle > fullchain.crt

Place the fullchain.crt and yourdomain.key files somewhere your app can read them, and keep the private key readable only by the user that runs Node.js.

Step 2: Create an HTTPS server in Node.js

Create a server file. For this demonstration we name it https_server.js, but you can use any filename. The example below uses CommonJS (require), which works in every supported Node.js version. Replace the paths in bold with your own:

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('/path/to/private.key'),
  cert: fs.readFileSync('/path/to/fullchain.crt'),
  // Recommended TLS hardening (2026): never negotiate below TLS 1.2
  minVersion: 'TLSv1.2'
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('Welcome to a Node.js HTTPS server\n');
}).listen(443);

You need to replace the parts in bold with your own information:

  • /path/to/private.key: the full path to your private key file.
  • /path/to/fullchain.crt: the full path to the full-chain file you created in Step 1.

Note on the port: HTTPS uses port 443 by default. Binding to it requires elevated privileges, so behind a reverse proxy or in development you may prefer a high port such as 8443. Just change the value passed to listen().

Prefer ES modules? If your project uses "type": "module" in package.json (or an .mjs file), use import syntax instead. The TLS options are identical:

import https from 'node:https';
import fs from 'node:fs';

const options = {
  key: fs.readFileSync('/path/to/private.key'),
  cert: fs.readFileSync('/path/to/fullchain.crt'),
  minVersion: 'TLSv1.2'
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('Welcome to a Node.js HTTPS server\n');
}).listen(443);

Alternative: pass the chain with the ca: option. If you would rather keep the files separate instead of building a full-chain file, leave cert pointing at your domain certificate and supply the intermediates through a ca array:

const options = {
  key: fs.readFileSync('/path/to/private.key'),
  cert: fs.readFileSync('/path/to/yourdomain.crt'),
  ca: [
    fs.readFileSync('/path/to/intermediate.crt'),
    fs.readFileSync('/path/to/ca_bundle.crt')
  ],
  minVersion: 'TLSv1.2'
};

Using Express? Pass your Express app as the request handler. The certificate options stay exactly the same:

const express = require('express');
const https = require('https');
const fs = require('fs');

const app = express();
app.get('/', (req, res) => res.send('Hello over HTTPS'));

const options = {
  key: fs.readFileSync('/path/to/private.key'),
  cert: fs.readFileSync('/path/to/fullchain.crt'),
  minVersion: 'TLSv1.2'
};

https.createServer(options, app).listen(443);

Step 3: Start your Node.js HTTPS server

Run the following command to launch the app:

node https_server.js

Your application now serves traffic over HTTPS. For a production deployment, run it under a process manager (for example PM2 or a systemd service) so it restarts automatically and survives reboots.

Step 4: Test your SSL installation

Test your SSL installation for potential errors or vulnerabilities using one of our SSL checker tools. You can also confirm the chain from the command line:

echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null | openssl x509 -noout -issuer -dates

This prints the certificate’s issuer and validity dates, confirming that your Node.js server is presenting the right certificate.

Where to buy an SSL certificate for Node.js?

SSL Dragon is your source for all your SSL needs. We offer some of the lowest prices on the market across our entire range of SSL products, and we’ve partnered with the best SSL brands in the industry for strong security and dedicated support. All our SSL certificates are fully compatible with Node.js applications.

Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and a 25-day money-back guarantee.

Frequently Asked Questions

How do I enable HTTPS in Node.js?

Use the built-in https module. Read your private key and full-chain certificate with fs.readFileSync(), pass them as the key and cert options to https.createServer(), and call .listen(443). Node.js handles the TLS handshake for you; there is no separate web server to configure.

Do I need the ca option in Node.js?

You need the intermediate chain to be served, but you do not necessarily need the ca option to do it. The simplest approach is to concatenate your domain certificate and CA bundle into one full-chain file and point cert at it. Use the ca array only if you prefer to keep the certificate and intermediates in separate files.

Why does my Node.js server fail to bind to port 443?

On Linux and macOS, ports below 1024 are privileged. Binding directly to port 443 requires elevated permissions, which is why many setups run Node.js on a high port such as 8443 behind a reverse proxy (Nginx or a load balancer) that terminates or forwards TLS. For development, simply change the value passed to listen().

Can I use import instead of require for the HTTPS server?

Yes. CommonJS (require) works in every supported Node.js version, but if your project is configured as an ES module (“type”: “module” in package.json or an .mjs file), you can use import https from ‘node:https’ instead. The TLS options are identical either way.

How do I check that the SSL certificate is working on Node.js?

Open your site in a browser and check for the padlock, run it through our SSL checker tools, or query it from the terminal with echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com to inspect the certificate the server presents.

Bottom line

Installing an SSL certificate on Node.js comes down to building a full-chain certificate, reading it and your private key with fs.readFileSync(), passing them to https.createServer() with minVersion: ‘TLSv1.2’, and starting the app with node https_server.js.

Need a certificate first? Browse our SSL certificates.

Save 10% on SSL Certificates when ordering from SSL Dragon today!

Fast issuance, strong encryption, 99.99% browser trust, dedicated support, and 25-day money-back guarantee. Coupon code: SAVE10

A detailed image of a dragon in flight
Written by

I've been building and managing websites for over 20 years, with a heavy focus on the technical side of the cybersecurity, VPN, and SaaS industries. I know how sites are built from the ground up, which means I know how to secure them. Here at SSL Dragon, I write about web architecture, encryption, and keeping your infrastructure safe.