Use NodeJS v16 as runtime for JavaScript actions
Tags: githubactions, github, javascript, typescript
Published: 2021-12-29 08:49:24

 ---
title: Use NodeJS v16 as runtime for JavaScript actions
published: true
description: An article regarding how to use NodeJS v16 as runtime for JavaScript actions
tags: githubactions, github, javascript, typescript
//cover_image: https://direct_url_to_image.jpg
---

This month [GitHub supported NodeJS v16 as runtime for JavaScript actions](https://github.com/actions/runner/issues/772). It is also [supported by GitHub Enterprise Servers (GHES) 3.0](https://docs.github.com/en/enterprise-server@3.0/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-javascript-actions) and later.

## Motivation to use NodeJS v16

[The end-of-life of NodeJS v12 is the end of next April](https://nodejs.org/about/releases/). So, if you maintain your own JavaScript actions, it is suggested to migrate their runtime to NodeJS v16.

## How to update the project

We can complete the minimal migration by [updating `run.using` in the `actions.yml` file](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-javascript-actions). We may need several additional updates like below:

### Update `engines.node` in `package.json`

If you have specified the version of NodeJS to use in `package.json`, you will need to update it.
`16.13.1` is the current latest version, so the preferred configuration would be as follows:

```json
  "engines": {
    "node": "^16.13.1"
  }
```

### Update `tsconfig.json`

NodeJS v16 lets us use ES2021. Based on the [official TSConfig settings recommendation for NodeJS v16](https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping#node-16), update the `compilerOptions` as follows:

```json
  "compilerOptions": {
    "lib": ["ES2021"],
    "module": "commonjs",
    "target": "ES2021"
  }
```

### Update TypeScript

If your TypeScript is too old to use ES2021, it is suggested to update.

Note that TypeScript v4.4 [changed the type of caught error from `any` to `unknown` by default](https://devblogs.microsoft.com/typescript/announcing-typescript-4-4/#use-unknown-catch-variables).
So if your action catches error to invoke `core.setFailed()` method, you need to check the type of caught object in runtime:

```patch
-     core.setFailed(error)
+     if (error instanceof Error) {
+       core.setFailed(error)
+     } else {
+       core.setFailed(JSON.stringify(error))
+     }
```

### Update ESLint

If you've updated your TypeScript, it is necessary to update ESLint too. If you've created projects based on the [official template project](https://github.com/actions/typescript-action), you can run the following command to upgrade ESLint and its plugins in batch:

```shell
$ npm add -D eslint@^8.5.0 @typescript-eslint/parser@^5.8.0 eslint-plugin-github@^4.3.5 eslint-plugin-jest@^25.3.0 
```

If you found lint failure caused by changes on the ESLint side, copy the [default `.eslintrc.json` from the template project](https://github.com/actions/typescript-action/blob/56d91620d7eacab6e7d3498bb7c114285476688e/.eslintrc.json), or follow ESLint's migration guide documented in its [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases).

### Update GitHub Actions Workflow to use NodeJS v16

If you use the default NodeJS on the PATH, you need no action because [GitHub hosted runners use NodeJS v16 by default since this Dec/10th](https://github.blog/changelog/2021-12-10-github-actions-github-hosted-runners-now-run-node-js-16-by-default/).

If you use `actions/setup-node` to specify the version of NodeJS, you need to update the `node-version` config in the workflow definitions.  
Or if you have a configuration file like `.node-version` and `.nvmrc`, you can use the [`node-version-file` config supported from `v2.5.0`](https://github.com/actions/setup-node/releases/tag/v2.5.0).

## Wrap up

NodeJS v12 will reach its end-of-life soon. All system running on NodeJS needs to be migrated, and GitHub JavaScript Actions are also in the target.

The migration process is quite simple, just update metadata and run the build with NodeJS v16. You may refer to [my PR for gradle/wrapper-validation-action](https://github.com/gradle/wrapper-validation-action/pull/53) as example. Enjoy!