Express.js Deploying Apps to Heroku

Deploying an Express.js application to Heroku is one of the most efficient ways to move your project from your local development environment to a live URL. Heroku is a Platform as a Service (PaaS) that handles the underlying infrastructure, allowing you to focus on writing code rather than managing server hardware or OS updates.

Developer Tip: While Heroku is famous for simplicity, it uses an ephemeral file system. This means any files uploaded to the server (like user profile pictures) will be deleted whenever the app restarts. Use a service like AWS S3 or Cloudinary for permanent file storage.

 

Key Features of Deploying Express.js to Heroku

  • Streamlined Deployment: Transition from code to production using a simple Git-based workflow.
  • Managed Environment: Heroku handles security patches for the OS and provides a managed runtime for Node.js.
  • Scalability: As your traffic grows, you can easily increase the number of "dynos" (containers) running your app with a single click or command.
  • Add-on Ecosystem: Instantly integrate databases (PostgreSQL, Redis), logging tools, and monitoring services without manual installation.

 

Steps to Deploy Express.js Apps to Heroku

1. Install Heroku CLI

The Heroku Command Line Interface (CLI) is the primary tool for managing your apps. It allows you to create apps, view logs, and manage configuration variables directly from your terminal.

  • Download the installer from the official Heroku CLI page.
  • After installation, verify it works by typing heroku --version in your terminal.

2. Create a Heroku Account

If you haven’t already, sign up at Heroku. Please note that while Heroku previously offered a free tier, they now use "Eco" and "Basic" plans for low-cost hosting.

3. Prepare Your Express.js App

Before pushing code to Heroku, your application needs three specific adjustments to run correctly in a cloud environment:

  • Dynamic Port Binding: Heroku assigns a port to your app dynamically via an environment variable. You cannot hardcode port 3000.
// Use the port Heroku provides, or default to 3000 for local development
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server is running on port ${PORT}`);
});
Common Mistake: Hardcoding app.listen(3000). If you do this, your app will work locally but will crash with a "R10 Boot Timeout" error on Heroku.
  • The Procfile: Create a file named Procfile (capital 'P', no file extension) in your root directory. This tells Heroku exactly how to start your web server.
web: node index.js
Best Practice: Use web: npm start in your Procfile instead of calling node directly. This ensures that any pre-start logic you've defined in your package.json scripts is executed.

4. Login to Heroku

Authenticate your machine with your Heroku account by running:

heroku login

This will open a browser window to complete the login process.

5. Initialize a Git Repository

Heroku uses Git for deployment. If your project isn't already a Git repo, initialize it now:

git init
git add .
git commit -m "Initial commit for Heroku"
Watch Out: Ensure you have a .gitignore file that includes node_modules. You should never push your dependencies to Heroku; the platform will install them automatically based on your package.json.

6. Create a Heroku App

This command creates a new application instance on Heroku and adds a new "remote" to your Git configuration.

heroku create your-unique-app-name

If you leave out the name, Heroku will generate a creative random name like serene-waters-12345.

7. Deploy to Heroku

To deploy, push your code from your local machine to the Heroku remote:

git push heroku master

Note: If your local branch is named main, use git push heroku main.

8. View the App

Once the build process finishes, your app is live! You can open it instantly with:

heroku open

9. View Logs

In a production environment, you can't see the terminal where the app is running. To see your console.log outputs and debug errors, use the tail command:

heroku logs --tail

10. Set Up a Database (Optional)

Most real-world apps need a database. Heroku makes this easy with Add-ons. To add a managed PostgreSQL database, run:

heroku addons:create heroku-postgresql:mini

Heroku will automatically add a DATABASE_URL environment variable to your app. In your Express code, you can access it via process.env.DATABASE_URL.

 

Example of package.json for Heroku

Heroku looks at your package.json to determine which version of Node to install and which command to run.

{
  "name": "express-heroku-demo",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "engines": {
    "node": "18.x"
  }
}
Best Practice: Always include the engines field in your package.json. This prevents "it works on my machine" bugs by forcing Heroku to use the same Node.js version you used during development.

 

Summary

By following this workflow, you've moved your Express.js app from a local environment to a robust cloud infrastructure. The combination of the Heroku CLI and Git integration makes deployments predictable and repeatable. Remember to keep your environment variables in "Config Vars" on the Heroku dashboard rather than hardcoding them, and use logs frequently to monitor your application's health.