|||

Video Transcript

X

Using pnpm on Heroku

Intro

The Heroku Node.js buildpack now supports pnpm, an alternative dependency manager. Early Node.js application owners who've taken advantage of pnpm support have seen 10-40% faster install times compared to NPM on Heroku deployments. It’s an excellent choice for managing packages in the Node.js ecosystem because it:

This post will introduce you to some of the benefits of the pnpm package manager and walk you through creating and deploying a sample application.

Prerequisites

Prerequisites for this include:

  • A Heroku account (signup).
  • A development environment with the following installed:
    • Git
    • Node.js (v18 or higher)
    • Heroku CLI

If you don’t have these already, you can follow the Getting Started with Node.js - Setup for installation steps.

Initialize a new pnpm project

Let’s start by creating the project folder:

mkdir pnpm-demo
cd pnpm-demo

Since v16.13, Node.js has been shipping Corepack for managing package managers and is a preferred method for installing either pnpm or Yarn. This is an experimental Node.js feature, so you need to enable it by running:

corepack enable
Note: If the corepack command was not found, you may need to install it manually.

Now that Corepack is enabled, we can use it to download pnpm and initialize a basic package.json file by running:

corepack pnpm@9 init

This will cause Corepack to download the latest 9.x version of pnpm and execute pnpm init. Next, we should pin the version of pnpm in package.json with:

corepack use pnpm@9

This will add a field in package.json that looks similar to the following:

"packageManager": 
"pnpm@9.0.5+sha256.61bd66913b52012107ec25a6ee4d6a161021ab99e04f6acee3aa50d0e34b4af9"

We can see the packageManager field contains:

  • The package manager to use (pnpm).
  • The version of the package manager (9.0.5).
  • An integrity signature that indicates an algorithm (sha256) and digest (61bd66913b52012107ec25a6ee4d6a161021ab99e04f6acee3aa50d0e34b4af9) that will be used to verify the downloaded package manager.

Pinning the package manager to an exact version is always recommended for deterministic builds.

Note: If you don’t want to use Corepack, we also support declaring a pnpm version in the engines field of package.json in the same way we already do with npm and Yarn. See Node.js Support - Specifying a Package Manager for more details.

Create the demo application

We’ll create a simple Express application using the express package. We can use the pnpm add command to do this:

pnpm add express

Running the above command will add the following to your package.json file:

"dependencies": {
  "express": "^4.19.2"
}

It will also install the dependency into the node_modules folder in your project directory and create a lockfile (pnpm-lock.yaml).

The pnpm-lock.yaml file is important for several reasons:

  • Our Node.js Buildpack requires pnpm-lock.yaml to enable pnpm support.
  • It enforces consistent installations and packages resolution between different environments.
  • Package resolution can be skipped which enables faster builds.

Now, create an app.js file in your project directory with the following code:

const express = require('express')

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

app.get('/', (req, res) => {
  res.send('Hello pnpm!')
})

app.listen(port, () => {
  console.log(`pnpm demo app listening on port ${port}`)
})

When this file executes, it will start a web server that responds to an HTTP GET request and responds with the message Hello pnpm!.

You can verify this works by running node app.js and then opening http://localhost:3000/ in a browser.

So Heroku knows how to start our application, we also need to create a Procfile that contains:

web: node app.js

Now we have an application we can deploy to Heroku.

Deploy to Heroku

Let’s initialize Git in our project directory by running:

git init

Create a .gitignore file that contains:

node_modules

If we run git status at this point we should see:

On branch main

No commits yet

Untracked files:
 (use "git add <file>..." to include in what will be committed)
   .gitignore
   Procfile
   app.js
   package.json
   pnpm-lock.yaml

nothing added to commit but untracked files present (use "git add" to track)

Add and commit these files to git:

git add .
git commit -m "pnpm demo application"

Then create an application on Heroku:

heroku create

Not only will this create a new, empty application on Heroku, it also adds the heroku remote to your Git configuration (for more information see Deploying with Git - Create a Heroku Remote).

Finally, we can deploy by pushing our changes to Heroku:

git push heroku main

Conclusion

Integrating pnpm with your Node.js projects on Heroku can lead to more efficient builds and streamlined dependency management, saving time and reducing disk space usage. By following the steps outlined in this post, you can easily set up and start using pnpm to enhance your development workflow. Try upgrading your application to pnpm and deploy it to Heroku today.

Originally published: July 18, 2024

Browse the archives for engineering or all blogs Subscribe to the RSS feed for engineering or all blogs.