How to Host Nodejs on Heroku

How to Host Node.js on Heroku Hosting a Node.js application on Heroku is one of the most efficient and developer-friendly ways to deploy web applications to the cloud. Heroku, a platform-as-a-service (PaaS) owned by Salesforce, abstracts away the complexities of server management, allowing developers to focus entirely on writing code. Whether you're building a REST API, a real-time chat applicatio

Nov 10, 2025 - 12:44
Nov 10, 2025 - 12:44
 4

How to Host Node.js on Heroku

Hosting a Node.js application on Heroku is one of the most efficient and developer-friendly ways to deploy web applications to the cloud. Heroku, a platform-as-a-service (PaaS) owned by Salesforce, abstracts away the complexities of server management, allowing developers to focus entirely on writing code. Whether you're building a REST API, a real-time chat application, or a full-stack web app, Heroku provides a seamless environment to deploy, scale, and monitor your Node.js applications with minimal configuration.

Node.js, with its event-driven, non-blocking I/O model, is ideal for building scalable network applications. When paired with Herokus automated deployment pipelines, version control integration, and built-in logging, developers can go from local development to a live, publicly accessible application in minutes. This tutorial will walk you through every step required to host a Node.js application on Herokufrom initial setup to production optimizationensuring you understand not just how to deploy, but why each step matters.

By the end of this guide, youll have a fully operational Node.js application running on Heroku, along with the knowledge to troubleshoot common issues, optimize performance, and maintain your app with best practices. This is not just a quick deployment guideits a comprehensive resource designed for developers who want to build robust, production-ready applications on the cloud.

Step-by-Step Guide

Prerequisites

Before you begin hosting your Node.js application on Heroku, ensure you have the following tools installed and configured:

  • Node.js (v18 or higher recommended)
  • npm or yarn (package manager)
  • Git (version control system)
  • Heroku CLI (command-line interface)
  • A Heroku account (free tier available)

You can download Node.js and Git from their official websites. For the Heroku CLI, visit Herokus CLI documentation and follow the installation instructions for your operating system. Once installed, verify the Heroku CLI by opening your terminal and typing:

heroku --version

If the version number displays, youre ready to proceed. If not, revisit the installation steps.

Step 1: Create a Node.js Application

If you dont already have a Node.js application, create one now. Open your terminal and run the following commands:

mkdir my-node-app

cd my-node-app

npm init -y

This creates a new directory and initializes a Node.js project with a default package.json file. Next, create a file named server.js in the root directory:

touch server.js

Open server.js in your preferred code editor and paste the following minimal Express.js server:

const express = require('express');

const app = express();

const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {

res.send('Hello, Heroku! Your Node.js app is running.');

});

app.listen(PORT, () => {

console.log(Server is running on port ${PORT});

});

This server listens on the port defined by Herokus environment variable PORTa critical requirement for Heroku deployments. If PORT is not set (as in local development), it defaults to 3000.

Step 2: Install Express.js

Since were using Express.js, install it as a dependency:

npm install express

This adds Express to your package.json under dependencies. Always ensure your dependencies are properly listed hereHeroku uses this file to install required packages during deployment.

Step 3: Create a Procfile

Heroku requires a Procfile to determine how to start your application. This is a text file named exactly Procfile (no extension) placed in the root directory of your project.

Create it with:

touch Procfile

Open the file and add the following line:

web: node server.js

The web process type tells Heroku this is a web application that should be exposed to HTTP traffic. The command node server.js instructs Heroku to start your application using Node.js. Note: If youre using a different entry file (e.g., index.js or app.js), adjust the command accordingly.

?? Important: The Procfile must be in the root directory and must not have a file extension. Heroku will ignore it if named incorrectly.

Step 4: Configure package.json

Ensure your package.json includes a start script. This is optional but highly recommended for consistency. Add or update the scripts section:

"scripts": {

"start": "node server.js",

"dev": "nodemon server.js"

}

The start script is what Heroku runs by default if no Procfile is present. Including it ensures your app will launch even if the Procfile is accidentally misconfigured.

Also, make sure your engines field specifies a compatible Node.js version. Heroku supports multiple versions, but specifying one prevents unexpected behavior during deployment:

"engines": {

"node": "18.x"

}

Replace 18.x with the version youre using locally. You can check your version with:

node --version

Step 5: Initialize a Git Repository

Heroku deploys applications via Git. If you havent already initialized a Git repository, do so now:

git init

git add .

git commit -m "Initial commit"

These commands initialize a Git repo, stage all files, and commit them with a descriptive message. Heroku will pull your code from this repository during deployment.

Step 6: Create a Heroku App

Log in to your Heroku account via the CLI:

heroku login

Follow the prompts to authenticate. Once logged in, create a new Heroku app:

heroku create your-app-name

Replace your-app-name with a unique name of your choice. If you omit the name, Heroku will generate one automatically (e.g., quiet-beyond-12345).

After running this command, Heroku will add a remote called heroku to your Git repository. You can verify this by running:

git remote -v

You should see an output similar to:

heroku  https://git.heroku.com/your-app-name.git (fetch)

heroku https://git.heroku.com/your-app-name.git (push)

Step 7: Deploy to Heroku

Deploying your application is as simple as pushing to the Heroku remote:

git push heroku main

?? Note: If your default branch is named master instead of main, use:

git push heroku master

Heroku will automatically detect that this is a Node.js application, install dependencies listed in package.json, and start your app using the Procfile. Youll see logs in your terminal as the build progresses:

  • Installing Node.js and npm
  • Installing dependencies
  • Building the application
  • Starting the web process

Once the build completes successfully, youll see a message like:

Deployed:

https://your-app-name.herokuapp.com/

Step 8: Open Your App

To open your live application in the browser, run:

heroku open

This command launches your app in your default browser. You should see the message: Hello, Heroku! Your Node.js app is running.

Step 9: View Logs and Debug

If your app fails to start or throws an error, check the logs:

heroku logs --tail

This streams real-time logs from your application. Common errors include:

  • Missing Procfile
  • Incorrect start script
  • Port not set to process.env.PORT
  • Node.js version mismatch

Use these logs to diagnose and fix issues before proceeding.

Best Practices

Use Environment Variables for Configuration

Never hardcode sensitive information like API keys, database URLs, or JWT secrets in your source code. Instead, use environment variables. Heroku allows you to set these via the CLI or dashboard:

heroku config:set API_KEY=your-secret-key

In your Node.js code, access them with:

const apiKey = process.env.API_KEY;

This keeps your code secure and allows you to use different configurations across environments (development, staging, production).

Set a Specific Node.js Version

As mentioned earlier, always define the Node.js version in your package.json under engines. Heroku uses the latest LTS version by default, but relying on this can cause issues if your app depends on features or behaviors specific to a certain version.

Use node --version locally to determine your current version, then lock it in:

"engines": {

"node": "18.17.0"

}

Optimize Dependencies

Heroku installs all dependencies listed in package.json, including development dependencies. To reduce build time and app size, move development-only packages (like nodemon, eslint, jest) to devDependencies:

npm install nodemon --save-dev

Heroku ignores devDependencies during production builds, making deployments faster and more efficient.

Use .gitignore to Exclude Unnecessary Files

Create a .gitignore file in your project root to prevent unnecessary files from being pushed to Heroku:

node_modules/

.env

.DS_Store

npm-debug.log*

This ensures your local node_modules folder (which can be huge) and environment files (which may contain secrets) are never uploaded.

Enable HTTP Keep-Alive for Better Performance

Node.js applications on Heroku benefit from enabling HTTP keep-alive to reduce connection overhead. Add this to your server:

const http = require('http');

const express = require('express');

const app = express();

const server = http.createServer(app);

server.keepAliveTimeout = 65000; // 65 seconds

server.headersTimeout = 66000; // 66 seconds

app.get('/', (req, res) => {

res.send('Hello, Heroku!');

});

server.listen(process.env.PORT || 3000, () => {

console.log(Server running on port ${server.address().port});

});

This improves connection reuse, especially under high traffic.

Use a Reverse Proxy for Static Assets (Optional)

While Heroku supports serving static files via Express, its not optimized for high-volume static asset delivery. For production apps with images, CSS, or JavaScript bundles, consider using a CDN like Cloudflare or AWS S3. Serve static files from your app only during development.

Monitor App Performance

Heroku provides basic metrics via the dashboard, but for deeper insights, integrate a monitoring tool like New Relic or Datadog. These tools track response times, error rates, memory usage, and database performancecritical for scaling.

Scale Appropriately

Herokus free tier provides 550 free dyno hours per month. A single web dyno runs 24/7, consuming 744 hours/monthso your app will sleep after 550 hours unless you upgrade. For production apps, use at least one Standard dyno (paid tier) and enable Auto Scale if traffic is unpredictable.

To scale:

heroku ps:scale web=2

This runs two web dynos. Use a load balancer (provided by Heroku) to distribute traffic between them.

Use Heroku Scheduler for Background Tasks

For cron jobs, data syncs, or cleanup scripts, use Heroku Scheduler (free add-on). It runs tasks on a schedule without requiring a persistent dyno. For example, you can schedule a script to clear expired tokens every hour.

Tools and Resources

Heroku Dashboard

The Heroku Dashboard is your central hub for managing applications. Here you can:

  • View app logs and metrics
  • Manage add-ons (databases, monitoring, caching)
  • Configure environment variables
  • Access deployment history
  • Set up automatic deployments from GitHub

Heroku Postgres

For persistent data storage, Heroku offers Heroku Postgres, a fully managed PostgreSQL database. It integrates seamlessly with Node.js using the pg library. Add it to your app with:

heroku addons:create heroku-postgresql:hobby-dev

Then access the database URL via process.env.DATABASE_URL in your code.

Loggly and Papertrail

For advanced log management, consider third-party add-ons like Loggly or Papertrail. They offer log search, alerting, and retention beyond Herokus 1,500-line limit.

GitHub Integration

Enable automatic deployments from GitHub by connecting your repository in the Heroku Dashboard under the Deploy tab. Once connected, Heroku will automatically deploy new commits to the main branch. This is ideal for CI/CD workflows.

Heroku CLI Plugins

Extend Herokus functionality with plugins:

  • heroku-repo Clean or reset your repo
  • heroku-config Export/import environment variables
  • heroku-pg-extras Monitor PostgreSQL performance

Install with:

heroku plugins:install heroku-repo

Node.js Performance Monitoring Libraries

Use libraries like node-clinic or clinic.js to profile your app locally before deploying:

npm install -g clinic

clinic doctor -- node server.js

This helps identify memory leaks, CPU bottlenecks, and async issues before they affect production.

Heroku Dev Center

Herokus official Dev Center is an indispensable resource. It contains in-depth guides on:

  • Deployment strategies
  • Buildpacks
  • Scaling and performance tuning
  • Security best practices

Always refer here for authoritative documentation.

Real Examples

Example 1: REST API with Express and MongoDB

Consider a simple user management API:

  • Endpoint: GET /api/users returns all users
  • Endpoint: POST /api/users creates a new user

Install MongoDB driver:

npm install mongoose

Connect to MongoDB Atlas (cloud-hosted MongoDB) using the connection string:

const mongoose = require('mongoose');

mongoose.connect(process.env.MONGODB_URI)

.then(() => console.log('Connected to MongoDB'))

.catch(err => console.error('Connection error', err));

Define a User schema and route:

const userSchema = new mongoose.Schema({

name: String,

email: String

});

const User = mongoose.model('User', userSchema);

app.get('/api/users', async (req, res) => {

const users = await User.find();

res.json(users);

});

app.post('/api/users', async (req, res) => {

const user = new User(req.body);

await user.save();

res.status(201).json(user);

});

Set the MongoDB URI as an environment variable:

heroku config:set MONGODB_URI=mongodb+srv://username:password@cluster.mongodb.net/myapp

Deploy as usual. This app now runs on Heroku with a scalable, cloud-hosted database.

Example 2: Real-Time Chat App with Socket.IO

Real-time applications require WebSocket support. Heroku supports WebSockets out of the box.

Install Socket.IO:

npm install socket.io

Update your server:

const http = require('http');

const express = require('express');

const socketIo = require('socket.io');

const app = express();

const server = http.createServer(app);

const io = socketIo(server);

app.use(express.static('public')); // Serve static HTML file

io.on('connection', (socket) => {

console.log('User connected');

socket.on('chat message', (msg) => {

io.emit('chat message', msg);

});

socket.on('disconnect', () => {

console.log('User disconnected');

});

});

const PORT = process.env.PORT || 3000;

server.listen(PORT, () => {

console.log(Server running on port ${PORT});

});

Create a public/index.html file with a basic chat UI using Socket.IO client:

<!DOCTYPE html>

<html>

<head><title>Chat App</title></head>

<body>

<ul id="messages"></ul>

<input id="message" placeholder="Type a message" />

<button onclick="sendMessage()">Send</button>

<script src="/socket.io/socket.io.js"></script>

<script>

const socket = io();

socket.on('chat message', (msg) => {

const li = document.createElement('li');

li.textContent = msg;

document.getElementById('messages').appendChild(li);

});

function sendMessage() {

const input = document.getElementById('message');

socket.emit('chat message', input.value);

input.value = '';

}

</script>

</body>

</html>

Deploy to Heroku. Now you have a real-time chat app running on the cloud with zero server configuration.

Example 3: E-commerce Product API with Redis Caching

Improve API response times using Redis for caching:

npm install redis

Use Redis to cache product data:

const redis = require('redis');

const client = redis.createClient({

url: process.env.REDIS_URL

});

client.on('error', (err) => console.log('Redis error: ', err));

app.get('/api/products/:id', async (req, res) => {

const productId = req.params.id;

const cached = await client.get(product:${productId});

if (cached) {

return res.json(JSON.parse(cached));

}

const product = await Product.findById(productId); // DB call

await client.setex(product:${productId}, 3600, JSON.stringify(product)); // Cache for 1 hour

res.json(product);

});

Add Redis as an add-on:

heroku addons:create heroku-redis:hobby-dev

Heroku automatically sets REDIS_URL, so your code works without modification across environments.

FAQs

Can I host a Node.js app on Heroku for free?

Yes. Heroku offers a free tier with 550 dyno hours per month. A single web dyno runs 24/7, consuming 744 hoursso your app will sleep after 550 hours unless you upgrade. Free apps also have limited logging and no custom domains. For production use, consider upgrading to a paid dyno.

Why is my Heroku app showing Application Error?

This usually means your app crashed on startup. Check logs with heroku logs --tail. Common causes include:

  • Missing or incorrect Procfile
  • Port not set to process.env.PORT
  • Uninstalled dependencies
  • Node.js version mismatch
  • Database connection failure

Does Heroku support HTTPS?

Yes. All Heroku apps are automatically served over HTTPS via a wildcard SSL certificate. You dont need to configure anything. Access your app via https://your-app-name.herokuapp.com.

How do I use a custom domain with Heroku?

First, add your domain in the Heroku Dashboard under Settings ? Domains. Then, configure your DNS provider (e.g., Cloudflare, GoDaddy) to point to Herokus DNS target (e.g., your-app-name.herokuapp.com). Heroku will automatically provision an SSL certificate for your custom domain.

Can I use MongoDB with Heroku?

Yes. While Heroku doesnt host MongoDB directly, you can use cloud providers like MongoDB Atlas, AWS DocumentDB, or Compose. Connect via the connection string and store it in an environment variable. Heroku supports any external database accessible via the internet.

How do I restart my Heroku app?

Run:

heroku restart

This restarts all dynos. Use this after changing environment variables or deploying updates.

Is Heroku suitable for production?

Absolutely. Many startups and enterprises use Heroku for production applications. Its reliable, scalable, and integrates with enterprise tools. While it may cost more than raw VPS hosting, the time saved in deployment, monitoring, and maintenance often justifies the price.

What happens if my app exceeds free dyno hours?

Your app will sleep and become unreachable until the next billing cycle or until you upgrade to a paid plan. Youll receive email notifications before this happens.

Can I deploy multiple Node.js apps on one Heroku account?

Yes. Each app is independent and has its own Git remote, environment variables, and add-ons. You can create as many apps as needed under a single account.

How do I rollback to a previous version?

Use:

heroku releases

to view deployment history, then:

heroku rollback v12

to revert to release number 12.

Conclusion

Hosting a Node.js application on Heroku is not just a deployment tacticits a strategic decision that accelerates development, reduces operational overhead, and ensures reliability. By following the steps outlined in this guide, youve not only deployed an appyouve learned how to structure it for production, secure it with environment variables, optimize its performance, and troubleshoot common issues.

Herokus simplicity doesnt mean its limited. With support for custom domains, databases, monitoring tools, and scaling options, its a full-featured platform capable of handling enterprise-grade applications. Whether youre a solo developer building a side project or part of a team shipping a SaaS product, Heroku provides the infrastructure to move fast and stay focused on what matters: your code.

As you continue to build, remember to:

  • Always specify your Node.js version
  • Use environment variables for secrets
  • Monitor logs and performance
  • Upgrade to paid dynos when traffic grows
  • Integrate with CI/CD tools like GitHub Actions

Node.js and Heroku form a powerful combination that empowers developers to create, deploy, and iterate faster than ever before. Now that you know how to host Node.js on Heroku, the only limit is your imagination.