Last updated October 27, 2025
Heroku’s Node.js buildpacks have different build behavior depending on whether an app uses classic or Cloud Native Buildpacks (CNB).
This article describes the build behavior for apps using Heroku’s Node.js Cloud Native Buildpack and how to customize the build process. Node.js applications follow the same build process when using npm, pnpm, or Yarn package managers.
This article is only applicable to apps use the Cloud Native Buildpack. For classic Node.js apps, see Node.js Classic Buildpack Builds.
Package Installation
By default, Heroku installs all dependencies listed in package.json under dependencies and devDependencies.
Heroku uses the lockfiles (package-lock.json, pnpm-lock.yaml, or yarn.lock) to install the expected dependency tree. Check those files into Git to ensure the same dependency versions across environments. If you use npm, Heroku uses npm ci to set up the build environment.
Build Failures
If a build fails, the Node.js buildpack identifies common issues in Node applications and provides warnings with best practice recommendations.
Environment Variables
An app’s config vars are unavailable during builds, but you can set environment variables for use during the build. Keep in mind that since these environment variables are in project.toml, they get committed to the repository.
Never set sensitive data or secrets via project.toml.
[_]
schema-version = "0.2"
[[io.buildpacks.build.env]]
name = "NODE_ENV"
value = "production"
If you need to make config vars available during builds, you can enable the Build Time Config Vars lab
Customizing the Build Process for Cloud Native Buildpack Apps
To allow for customization of the build process for your CNB application, the following scripts get executed by the chosen package manager in the order listed if they are defined in package.json:
heroku-prebuildheroku-buildorbuildheroku-postbuild
If heroku-build and build are present, only heroku-build executes.
These scripts run after all installing dependencies.