Migrate Cloud Functions to newer Node.js runtimes

This document describes the differences between Node.js runtime versions, to help you in migrating your Cloud Functions code.

Migrating to a newer runtime

To migrate to a newer runtime:

  1. Read about your target runtime in this document to understand the differences it introduces, and make any necessary changes to your code. In particular, be aware of the environment variable changes introduced in the Node.js 10 runtime.
  2. Deploy your function, specifying your target Node.js runtime:

    gcloud functions deploy FUNCTION_NAME --runtime NODE_RUNTIME...

Differences in the Node.js 14 runtime

Node.js 14 introduces some new features and concepts. Highlights:

  • Optional chaining. Optional chaining looks like this: {"hello": null}?.hello?.neat. It allows safe access to deep keys on objects that may not exist.
  • Nullish coalescing. This introduces ?? which is safer than using || for assignment (as it only evaluates to false for null or undefined).

You can learn more about Node.js 14 features here.

Differences in the Node.js 12 runtime

Node.js 12 uses npm ci, which always runs the prepare script in package.json.

The main differences between using npm install and npm ci are:

  • The project must have an existing package-lock.json or npm-shrinkwrap.json.
  • If dependencies in the package lock do not match those in package.json, npm ci will exit with an error, instead of updating the package lock.
  • If a node_modules is already present, it will be automatically removed before npm ci begins its install.

To upgrade from Node.js 10 to Node.js 12, move the dependencies used in prepare from devDependencies to dependencies.

For Node.js 12 and above, functions with memory limits greater than 2GiB require users to configure NODE_OPTIONS to have max_old_space_size. For example:

gcloud functions deploy envVarMemory \
--runtime nodejs20 \
--set-env-vars NODE_OPTIONS="--max_old_space_size=8192" \
--memory 8Gi \
--trigger-http

Differences in the Node.js 10 runtime

The Node.js 10 runtime introduced changes that might require you to modify your function's source code to use the newer runtimes.

For the majority of applications, upgrading from Node 8 to Node 10 will involve no code changes (the major difference being changes in environment variables on GCF).

Node 10 introduces a variety of exciting new features, such as async iterators and a promise-based file API, along with performance improvements and security patches.

Logging

If you did not use JSON.stringify when logging objects and/or collections in Node.js 8, you may see increased log volumes upon upgrading to Node.js 10. This may result in additional costs. We recommend using JSON.stringify to group log statements together, as shown in Writing, Viewing, and Responding to Logs.

Environment variable changes

The Node.js 10 runtime introduced changes to the environment variables that are predefined by the runtime. See Environment variables set automatically for a full description of the differences between environment variables set by the Node.js 10 runtime versus previous runtimes.

To run your older Node.js functions in the Node.js 10 runtime (and higher), you might need to make changes to any predefined environment variables you are using. Update your code to use the replacement variables where possible or set them yourself when deploying your function. As a best practice, we recommend that you do not depend on environment variables that you have not set explicitly.

The following environment variables are no longer set by the Node.js 10 runtime:

Environment variable Migration
CODE_LOCATION Set it when deploying your function. Your code location is /srv.
ENTRY_POINT Use the FUNCTION_TARGET environment variable instead.
GOOGLE_CLOUD_PROJECT Set it when deploying your function.
GCP_PROJECT Set it when deploying your function.
GCLOUD_PROJECT Set it when deploying your function.
GOOGLE_CLOUD_REGION Set it when deploying your function.
FUNCTION_REGION Set it when deploying your function.
FUNCTION_NAME Use the K_SERVICE environment variable instead.
FUNCTION_IDENTITY Set it when deploying your function.
FUNCTION_MEMORY_MB Set it when deploying your function.
FUNCTION_TIMEOUT_SEC Set it when deploying your function.
FUNCTION_TRIGGER_TYPE Use the FUNCTION_SIGNATURE_TYPE environment variable instead. See Using environment variables for usage details.
OLDPWD No longer available.
SHLVL No longer available.

Differences in the Node.js 8 runtime

The signature for background functions changed between the Node.js 6 and the Node.js 8 runtimes, continuing into Node.js 10.

An example Node.js 6 background function might look as follows:

exports.nodejs6BackgroundFunction = (event, callback) => {
  let data = event.data;
  let context = event.context;
  // ... the rest of your function
};

Note that the event argument contains data and context properties. In the Node.js 10 runtime, the data and context properties have been extracted from the event object and are now included as part of the function signature:

exports.nodejs8AndAboveBackgroundFunction = (data, context, callback) => {
  // ... the rest of your function is unchanged
};

This change simplifies references to the data and context objects previously contained within the event argument. For more information, see Background function parameters.

If you are using the Node.js 6 background function signature, make the following changes to run your function in a newer Node.js runtime:

  1. Change the function signature from (event, callback) to (data, context, callback).

  2. Change references to event.data and event.context to data and context, respectively.

Deprecations: Node.js 6 and Node.js 8

The Node.js 6 and Node.js 8 runtimes have been deprecated. To ensure that your functions are on a supported version of Node.js, migrate them to Node.js 10 or higher.

After 2020-08-05, function deployments that use Node.js 6 will be blocked. Cloud Functions that continue to use Node.js 6 after this time may be disabled.