The UpgradeJS Blog

The Basics of the Node.js Version Upgrade Process

In this article, we’ll cover essential steps, from backing up data to performing the upgrade of your servers, to ensure a successful upgrade of Node.js. These steps can be applied to any version, whether you’re moving between older versions or upgrading to the latest stable release.

By following these steps, you can avoid potential issues, such as data loss or compatibility problems, and ensure a smooth process.

Use checkpoints

Before making any significant changes to your application, such as an upgrade, it’s crucial to have a complete backup. This approach enables you to return to a functional state in case any problem emerges throughout the update procedure.

An effective and commonly used way to back up your application is by using version control systems, such as Git opens a new window . Git is not only a robust system for version control but also an excellent tool for backing up your application.

Git provides a powerful framework for backup and recovery during an upgrade process. It’s good practice to create a new branch before making changes, ensuring the stability of the main codebase.

As you work on the upgrade, it’s important to commit changes incrementally to keep a clear record of your progress. Regularly pushing these changes to a remote repository like GitHub or GitLab not only backs up your work externally but also facilitates collaboration.

A tag might be created prior to the upgrade, serving as a reference point to the pre-upgrade state of the code. If issues arise, Git allows reversion of changes or even switching back to the original branch.

Once the upgrade is tested and ready, the changes can be merged back into the main branch, often through a pull request for final review.

Understand your challenges

The Node.js project is open source, and its entire development history, including discussions around issues and pull requests, is freely available on its official GitHub repository opens a new window .

Here’s how you can use this resource:

  • Review the version-specific issues and pull requests: Navigate to the Issues opens a new window and Pull requests opens a new window sections of the Node.js GitHub repository. Use the search and filter functionality to find discussions related to the version you’re interested in. This can give you a sense of the potential problems, bug fixes, and improvements associated with that version.

  • Check out the code changes: If you’re comfortable reading code, you can dig into the actual changes made in the version upgrade. The Commits opens a new window section provides a detailed history of all the code changes.

  • Participate in discussions: The Discussions opens a new window section on the repository is a place where developers share their experiences, ask questions, and provide support. You can ask questions about the upgrade process, share your concerns, or offer your insights.

  • Watch for Releases: The Releases opens a new window section provides detailed notes about each version, including breaking changes, new features, and bug fixes. Make sure you review these notes carefully before you start your upgrade process.

Perform self-analysis

In the process of upgrading your Node.js application, a crucial step involves conducting a thorough project inspection. This helps understand the complexity, maintainability, and potential issues within your codebase. A tool that can significantly aid this process is es6-plato opens a new window (We’ll explain more about how we use this tool in a future article).

es6-plato is an invaluable tool that creates a detailed HTML report showcasing various metrics and insightful information about your project. It delivers data on aspects such as the total lines of code, complexity, maintainability index, estimated errors, difficulty level, and ESLint errors. The visually appealing and comprehensive representation of these metrics simplifies data interpretation and aids in evaluating the overall health of your project.

Additionally, our fork of es6-plato opens a new window supports churn and churn vs complexity metrics. The “churn” metric offers insight into the frequency of your code changes, which can be particularly useful when planning an upgrade or refactoring.

Build a defense

Prior to the upgrade, a critical element to pay attention to is test coverage. Ensuring your application is well-covered by at least integration tests, especially focusing on your application’s key parts and workflows, is of great importance. This will prove incredibly beneficial during the upgrade process.

In addition, we also advise establishing comprehensive unit test coverage for your application. This practice can aid in detecting bugs within your individual modules and functions and prove advantageous when implementing the gradual upgrade approach.

Also, remember to run your test suite after each important change. This will help catch any issues or breaking changes introduced by the updates early in the process.

Be brave

Dive into the upgrade process with confidence by updating your Node.js dependencies:

Development on multiple Node.js versions

Initially, you might use a Node Version Manager tool (like nvm opens a new window (Node.js Version Manager) or asdf opens a new window ) to be able to install and switch between multiple versions of Node.js with ease.

Check for new dependency versions

Another valuable tool to consider is npm-check opens a new window . This command-line utility helps you manage your project’s dependencies more efficiently, offering insights into outdated, incorrect, and unused dependencies within your application.

Running npm-check -u launches an interactive session that not only flags outdated dependencies but also provides links to the packages’ official documentation. This feature allows you to make an informed decision about whether to upgrade a particular package based on the changes and improvements in the newer versions.

By ensuring your dependencies are up-to-date, used correctly, and still necessary, npm-check helps you simplify the upgrade.

Check for dependency compatibility

After working on different upgrades, we created depngn opens a new window , a useful command-line tool that evaluates the compatibility of your project’s dependencies with a specific Node.js version.

Depngn scans your application’s dependencies and provides a report indicating whether each dependency will work with the intended Node.js version or not. This crucial step allows you to identify potential issues in advance and informs you about the necessary upgrades or modifications.

The tool is straightforward to use opens a new window : just install or run it via npx opens a new window , specifying the Node.js version you’re targeting, e.g., npx depngn 18.13.0. With this information you can detect dependencies that might require an upgrade or even a replacement.

Check indirect dependencies

In some cases, a dependency may be compatible with a future Node.js version but one of its dependencies might require an update. Instead of adding the indirect dependency as a hard dependency, you can use the resolutions opens a new window field in the package.json if you’re using the yarn package manager, or the overrides opens a new window field if you’re using npm.

Gradual upgrade

The process of updating your application’s dependencies is an integral part of upgrading your Node.js application. However, updating all dependencies at once can often lead to unexpected issues, making it difficult to isolate the cause of a problem. Thus, it’s generally recommended to perform a gradual, step-by-step upgrade of your dependencies.

Once you’ve prioritized your dependencies based on previous steps, begin by upgrading one at a time. This systematic approach will help you isolate any issues that arise during the upgrade process. If a problem occurs after upgrading a specific dependency, it’s easier to identify the cause and apply a solution.

After upgrading each dependency, run your test suite to ensure that your application is still functioning as expected. Pay close attention to areas of your application that heavily utilize the recently upgraded dependency.

Fix any introduced issues before proceeding with other dependencies. This will help you keep the upgrade process manageable and prevent issues from compounding.

Keep a record of all upgrades and any issues encountered during the process. This documentation can be helpful for future reference and can provide valuable insights for managing upgrades more effectively in the future.

Update your servers

Once everything is working locally, you can update Node.js on your servers. When updating your servers, the process can vary depending on whether your application was previously built or not.

Here’s a breakdown:

If the application was previously built

A built application has already transformed the source code into a production-ready state, meaning all dependencies have been installed and compiled as necessary.

In this case, after upgrading Node.js on your server, you won’t typically need to run npm install again because your built application should include all the necessary modules.

You simply need to deploy the updated, built application to your server. However, if there are any server-specific configurations or dependencies, make sure these are properly updated to match your new Node.js environment.

If the application was not previously built

In this scenario, your server runs the raw source code of your application, and dependencies are installed directly on the server. After upgrading Node.js on your server, you would need to run npm install again to ensure all dependencies are properly installed under the new Node.js version.

Remember, the upgrade process on your server should be done with caution. Always test the upgraded application thoroughly in a staging or development environment before moving to production. This way, you can catch and resolve any issues before they affect your users.

Lastly, consider using a continuous integration/continuous delivery (CI/CD) pipeline opens a new window to automate these processes. This can help ensure consistency and reliability across different environments, as well as facilitate the handling of upgrades and deployments.

Conclusion

Upgrading Node.js to the next version often offers the opportunity to leverage a multitude of exciting new features and enhancements. But as with any major upgrade, it’s a process that requires careful planning, a strategic approach, and the right tools.

Remember, the key to a successful upgrade lies in meticulous preparation, diligent testing, and a gradual, controlled implementation. By following the steps outlined in this post, you can ensure a smoother transition to the next Node.js version, allowing you to harness its full potential while minimizing disruptions.

If you get stuck feel free to reach out to us for help with your node.js upgrade opens a new window .