Upgrading Node.js/npm in WordPress

Node.js and npm are tools used in the WordPress code base to manage JavaScriptJavaScript JavaScript or JS is an object-oriented computer programming language commonly used to create interactive effects within web browsers. WordPress makes extensive use of JS for a better user experience. While PHP is executed on the server, JS executes within a user’s browser. https://www.javascript.com dependencies and some developer tooling. This page breaks down how this works at a high level, how various code bases and systems interact with each other, what considerations need to be made prior to upgrading, and the tasks to complete in order to successfully upgrade.

Because the gutenberg repository is used to make changes to blockBlock Block is the abstract term used to describe units of markup that, composed together, form the content or layout of a webpage using the WordPress editor. The idea combines concepts of what in the past may have achieved with shortcodes, custom HTML, and embed discovery into a single consistent API and user experience. editor-related code with the goal of eventually being included in wordpress-develop, the policies and practices on this page should be followed in both repositories.

Note: If you’d like to jump right into getting your hands dirty, a checklist is available at the end of this page.

Contributing to wordpress-develop & gutenberg

In order to develop with or contribute to WordPress, a contributor must first run npm install and npm run build:dev (an alias of npm run grunt build --dev) within a checkout of the wordpress-develop. This installs all of the necessary dependencies and performs the steps required to compile and build the software into the src directory. 

There is also npm run build, which will perform the same steps and outputs a production-ready version of WordPress into the build directory.

npm install is still the first step when contributing to the gutenberg repository, but npm run dev is used for local development. npm run build is still used for a production build.

Commits to wordpress-develop

When a CoreCore Core is the set of software required to run WordPress. The Core Development Team builds WordPress. Committercommitter A developer with commit access. WordPress has five lead developers and four permanent core developers with commit access. Additionally, the project usually has a few guest or component committers – a developer receiving commit access, generally for a single release cycle (sometimes renewed) and/or for a specific component. makes a change to the canonical code base in SVNSVN Subversion, the popular version control system (VCS) by the Apache project, used by WordPress to manage changes to its codebase., the WordPress.org build server runs the npm install and npm run build commands to create a production-ready copy of WordPress with all of the most recent changes. The build server is managed by the WordPress.org Systems Team.

Configuring Versions

To ensure that the build scripts produce a consistent output, the preferred and required versions of Node.js/npm are specified and controlled in a few ways.

.nvmrc File

The .nvmrc file is recognized by Node Version Manager and other tools that recognize this file (such as Fast Node Manager) to install the version of Node.js that should be used when contributing to a project. It’s common for these tools to be configured to switch versions automatically when changing directories.

It’s worth noting that someone could use nvm use and satisfy the .nvmrc file in a way that does not meet the requirements defined in engines.node. For an example, see this conversation.

Only the major version number should be specified in this file.

These tools will attempt to resolve the most recent version based on the version specified. When a minor version is included (ie. X.Y), only the most recent bugfix release (X.Y.Z) will be considered. Including a minor version locks contributors to that minor releaseMinor Release A set of releases or versions having the same minor version number may be collectively referred to as .x , for example version 5.2.x to refer to versions 5.2, 5.2.1, 5.2.3, and all other versions in the 5.2 (five dot two) branch of that software. Minor Releases often make improvements to existing features and functionality., preventing newer minor versions (X.Y+1) from being picked up automatically.

This file is also used by any GitHubGitHub GitHub is a website that offers online implementation of git repositories that can easily be shared, copied and modified by other developers. Public repositories are free to host, private repositories require a paid subscription. GitHub introduced the concept of the ‘pull request’ where code changes done in branches by contributors can be reviewed and discussed before being merged by the repository owner. https://github.com/ Actions workflows that configures Node.js through the actions/setup-node action to avoid having to manually define the version in every workflow file. The version actually required is enforced by the engines property in the package.json file, so specifying only the major version is the most flexible and eliminates the added maintenance burden.

Engines Property

The package.json file supports an engines property that allows you to specify the versions of Node.js and npm required to run the application’s scripts.

These values should always at least contain a lower boundary.

The version specified in the engines property usually should be set to the minor release where the version transitioned to Active LTS status. This is not a hard rule, though. A newer version can be pinned to guarantee the presence of a specific feature, bugbug A bug is an error or unexpected result. Performance improvements, code optimization, and are considered enhancements, not defects. After feature freeze, only bugs are dealt with, with regressions (adverse changes from the previous version) being the highest priority. fix, or security patchpatch A special text file that describes changes to code, by identifying the files and lines which are added, removed, and altered. It may also be referred to as a diff. A patch can be applied to a codebase for testing.. Just make sure to check the build server first to avoid inconsistent behavior.

The version of npm specified in engines.npm should be the version bundled with the specified version of Node.js. To date there has not been a situation where this policy did not work.

Because WordPress can remain on a specific version of Node.js for a while, it’s preferable not to include upper bounds whenever possible. This allows contributors to contribute while using newer versions if they prefer, which can also help to test the code base for potential incompatibilities prior to attempting future updates.

However, there is occasionally a scenario where one is required to prevent inconsistencies or breaking changes that have not yet been addressed in the code base (see #56547 for an example).

Because the .npmrc file defines engines-strict=true, the user must be using versions of Node.js & npm that satisfies the specified boundaries.

The WordPress.org build server uses the engines.node property to determine which version of Node.js to use when processing a commit to wordpress-develop. However, version qualifiers are dropped before evaluating which version to use and values are not enforced as a hard requirement. For example, if >=20.20 is specified but not installed, the latest 20.Y version present will be used instead (20.10, 20.8, etc.).

Note: When the major version of Node.js specified does not exist on the build server the build will fail. Because the server must build commits in sequential order, this can only be resolved by reaching out to the Systems Team.

Upgrading Node.js

In order to upgrade the version of Node.js used, there is a list of tasks that must be performed in a specific order.

Choose a Version

Before doing detailed evaluation, open a TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. ticketticket Created for both bug reports and feature development on the bug tracker. and a corresponding gutenberg issue to track the proposed upgrade. These provide a place to document the rationale, link to relevant discussions, and build a compelling case for the upgrade beyond “run the latest version”. Both repositories should be referenced so contributors working in either code base can follow along.

Before an upgrade is requested, the most important step is to determine which version to target following a few guidelines:

  • Because odd numbered versions never receive LTS status, only even numbered versions are eligible to be pinned as preferred/required.
  • While it’s OK to remain on a version with Maintenance LTS status, only versions with Active LTS status should be targeted when upgrading. This helps ensure another update is not required short-term. 
  • Check the Node.js Release Schedule. If the targeted version is scheduled to transition from Active LTS to Maintenance LTS in the near future, it may be preferable to wait until that happens in order to target the newer version. This can result in a longer period of time before another upgrade must happen and can prevent scenarios where a version is used that reaches end-of-life.
  • Upgrades should happen as infrequently as possible. The fact that the version specified in the project has transitioned to Maintenance LTS, or that a new version is available, is not a reason in and of itself to upgrade. There should be compelling reasons, such as new features that clearly benefit contributors and the project overall.

It is also important to consider the timing of an upgrade relative to the WordPress and GutenbergGutenberg The Gutenberg project is the new Editor Interface for WordPress. The editor improves the process and experience of creating new content, making writing rich content much simpler. It uses ‘blocks’ to add richness rather than shortcodes, custom HTML etc. https://wordpress.org/gutenberg/ release cycles. Upgrades should be avoided late in a release cycle, and are not allowed during betaBeta A pre-release of software that is given out to a large group of users to trial under real conditions. Beta versions have gone through alpha testing in-house and are generally fairly close in look, feel and function to the final product; however, design changes often occur as part of the process. and release candidaterelease candidate One of the final stages in the version release cycle, this version signals the potential to be a final release to the public. Also see alpha (beta). phases. Changing the version of Node.js close to a release introduces risk that is difficult to justify, since any regressions in the build process or built files may not be caught in time. Upgrades are best landed early in a cycle, when there is sufficient runway to surface and address issues before release.

Check the Build Server

Before any other work begins, confirm that the desired version of Node.js is available on the build server. It may already be installed. To check, ask in #meta if someone with the appropriate access could confirm which versions are present. If the desired version is available, proceed to the next step.

File this request as early in the process as possible. It sometimes takes several weeks for the request to be addressed, and in some situations, it may not be possible to upgrade yet. Filing early ensures the request can be fulfilled in parallel with other preparation work and testing. Examples of previous requests can be found on the nodejs tag archive.

If the desired version is not installed, a new request should be created on the Make WordPress Systems P2. Make sure to include as many important details in the request as possible:

  • Which version of Node.js is being requested.
  • Why is it being requested?
  • Is anything blocked until this version is available?
  • Are there new features that the WordPress build processes would benefit from?
  • Link to any Trac tickets/GitHub issues/Make Blogblog (versus network, site) Posts discussing or planning for this upgrade.
  • Will trunk only be updated to make use of this version? Or will other branches also be updated? If so, which ones and why?

Create Pull Requests

The next step is to create a pull request for both the wordpress-develop and gutenberg repositories upgrading the version used. Each pull request should: 

  • Update the value in .nvmrc.
  • Update the values in package.json (engines.node and engines.npm).
  • Update any test matrices testing multiple versions of Node.js in GitHub Actions workflow files.

Required checks configured in GitHub related to GitHub Actions workflows may be defined by the workflow and job names. If the version of Node.js being tested is included in the job name, the required checks will need to be updated by someone with administration access to the respective repository.

Audit and Update Dependencies

Compatibility issues with the targeted version of Node.js often only surface once the version requirement has been updated and tested. As issues are uncovered:

  • Identify dependencies that do not yet support the targeted Node.js version.
  • Upgrade those dependencies to compatible versions where available.
  • For critical dependencies that lag behind in support, contribute fixes upstream. Be aware that upstream contributions can take significant time to be reviewed, merged, and released, which may delay the overall upgrade for critical dependencies.

Test Thoroughly

Testing is its own discrete phase of the upgrade process and should not be rushed. Make sure to verify that all the various scripts defined within the package.json file work as expected. Some are verified in GitHub Actions workflows, but not all.

It’s also good to compare the contents of the build directory after running npm run build with those of the most recent commit to the WordPress/WordPress repository (the public, read-only mirror of built WordPress code). This is the canonical reference of what end users actually receive, so any unexpected differences are worth investigating before proceeding.

After any dependency updates from the previous step, re-run these testing steps to confirm nothing has regressed.

Commit Changes

Once the changes are well tested and the new version is confirmed as available on the WordPress.org build server, it’s time to commit them.

Because the block editor code is pulled in from the gutenberg repository by the build script in the wordpress-develop repository, wordpress-develop must be updated first to avoid build failures. After the build succeeds and all tests pass, the pull request for the gutenberg repository can be merged.

If problems are discovered after committing, consider reverting the change until the issue can be better understood. The earlier a revert of a foundation tooling change happens, the easier it is to avoid downstream effects on subsequent commits and on builds produced from trunk.

Update Older Branches

It’s preferable for the tooling between all branches of WordPress eligible for security releases to be as consistent as possible within reason. This includes using the same versions of Node.js & npm.

Reasons to Backport an Upgrade

When trunk is upgraded, there are several reasons to consider applying the same change to older branches:

  • Consistency for contributors. Contributors who switch between branches (for example, when working on a backportbackport A port is when code from one branch (or trunk) is merged into another branch or trunk. Some changes in WordPress point releases are the result of backporting code from trunk to the release branch. or investigating a bug across versions) benefit from not having to switch Node.js versions as they move between checkouts.
  • Consistency for automation. GitHub Actions workflows, local development scripts, and other tooling behave more predictably when all supported branches use the same Node.js version. This also reduces the maintenance burden of keeping workflow files in sync across branches.
  • Build server alignment. Keeping branches aligned reduces the number of Node.js versions the WordPress.orgWordPress.org The community site where WordPress code is created and shared by the users. This is where you can download the source code for WordPress core, plugins and themes as well as the central location for community conversations and organization. https://wordpress.org/ build server must support simultaneously. This is particularly relevant when an older version of Node.js is approaching or has reached end-of-life.
  • Security and stability. Older versions of Node.js eventually stop receiving security updates. Keeping as many branches on maintained versions for as long as possible helps ensure the build process itself is running on secure software actively receiving patches.
  • Reducing future effort. If a branchbranch A directory in Subversion. WordPress uses branches to store the latest development code for each major release (3.9, 4.0, etc.). Branches are then updated with code for any minor releases of that branch. Sometimes, a major version of WordPress and its minor versions are collectively referred to as a “branch”, such as “the 4.0 branch”. falls significantly behind, future security releases for that branch may require additional effort to work around incompatibilities with newer dependencies or tooling.

Tradeoffs to Consider

Before backporting, evaluate the following:

  • Will the upgrade result in any changes to built files? If so, it’s better to leave the branch as-is unless absolutely necessary. More files changed translates to larger package sizes for updates. This results in an increased potential for a site to experience a failure during an upgrade, and more required resources from wordpress.org to build and serve those packages.
  • Will the upgrade require any dependencies to be upgraded? If newer versions of dependencies are needed to support the targeted Node.js version, those upgrades must also be backported. This frequently results in changes to built files, with the same concerns described above.
  • Will the upgrade require changes to scripts, build configuration, or workflow files? The more invasive the change, the more testing is required to gain confidence that nothing has regressed. For older branches, the cost of that testing should be weighed against the benefit of the upgrade.
  • How much active development is happening on the branch? Branches that only receive occasional security releases benefit less from tooling consistency than branches with ongoing contribution activity.
  • How close is the branch to the end of security support? If a branch is nearing the end of its support window, the effort of backporting may not be justified.

Other Considerations

Make sure to also update any related contributor documentation or handbook pages, including the Node.js/npm reference page.

If there is anything related to the change that other contributors need to be aware of, publish a post on the Make WordPress Core site to communicate the necessary information. If there is no direct action required by contributors, a simple /here pingPing The act of sending a very small amount of data to an end point. Ping is used in computer science to illicit a response from a target server to test it’s connection. Ping is also a term used by Slack users to @ someone or send them a direct message (DM). Users might say something along the lines of “Ping me when the meeting starts.” sharing the upgrade is sufficient.

Upgrade Checklist

Below is a helpful checklist if you are considering making the suggestion to change the version of Node.js/npm used in the Core code base:

  1. Choose a target version and create a ticket in Trac/issue in gutenberg on GitHub.
    1. Confirm the version is even-numbered.
    2. Confirm Active LTS status (not Maintenance LTS or current).
    3. Review the Node.js Release Schedule to confirm the version will not transition to Maintenance LTS in the near future.
    4. Begin to build a compelling case to upgrade past “run the latest version”.
    5. Confirm the timing is appropriate relative to the WordPress and Gutenberg release cycles (avoid late in a cycle, and never during beta or release candidate phases).
  2. Evaluate older branches for updates.
  3. Verify or request the version on the WordPress.org build server.
    1. Ask in #meta whether the desired version is installed on the wordpress.org build server. 
    2. If not, create a request on the Make WordPress Systems blog. Use past requests for examples, but including the following is helpful:
      1. The specific version being requested.
      2. The catalyst for the request.
      3. Any work blocked until the version is available.
      4. Build process benefits or new features being targeted.
      5. Links to relevant Trac tickets, GitHub issues, or Make Blog posts.
      6. Whether trunktrunk A directory in Subversion containing the latest development code in preparation for the next major release cycle. If you are running “trunk”, then you are on the latest revision. only will be updated, or if other branches will be updated to use this version as well.
  4. Create pull requests to both the wordpress-develop and gutenberg repositories. Make sure to:
    1. Update the .nvmrc file.
    2. Update the engines.node and engines.npm versions in package.json. Run npm install after to update the lock file.
  5. If necessary, create pull requests applying the change to older branches.
  6. Test thoroughly.
    1. Confirm that the respective build scripts work as expected.
    2. Compare the results of the build script in wordpress-develop with the build repository.
    3. Test all scripts defined in the package.json file and compare the results using the previous required versions.
  7. Audit and update dependencies for compatibility submitting pull requests upstream if necessary.
    1. Identify dependencies that do not yet support the targeted Node.js version.
    2. Upgrade those dependencies to compatible versions, when available.
    3. Contribute fixes upstream when support is lacking.
    4. Re-run the previous testing steps after updating dependencies.
  8. Confirm build server readiness.
  9. Commit changes in the correct order.
    1. Commit to wordpress-develop first to avoid build failures.
    2. Merge pull request in gutenberg after confirming a passing build in wordpress-develop.
  10. Backport the update to older branches.
  11. Update documentation.
  12. Communicate changes to contributors.
    1. If contributors will need to take direct action, publish a post on Make WordPress Core with details and specific steps.
    2. If no action is required, a simple /here ping in #core could be sufficient.

s
search
c
compose new post
r
reply
e
edit
t
go to top
j
go to the next post or comment
k
go to the previous post or comment
o
toggle comment visibility
esc
cancel edit post or comment