Using the Node.js Runtime with Serverless Functions

Learn how to use the Node.js runtime to compile Node.js Serverless Functions on Vercel.
Table of Contents

The Node.js runtime, by default, builds and serves Serverless Functions within the /api directory of a project, providing the files have a file extension of .js, .mjs, or .ts.

To declare a Node.js function you must either use the Web signature or export a default function handler, for example:

api/hello.js
export default function handler(request, response) {
  const { name = 'World' } = request.query;
  return response.send(`Hello ${name}!`);
}

If you need more advanced behavior, such as a custom build step or private npm modules, see the Advanced Node.js Usage section.

Serverless Functions using the Node.js runtime support all Node.js APIs, including standard Web APIs such as the Request and Response Objects.

To override the default and set a different Node.js version for all new projects:

  1. From your dashboard, select your project
  2. Select the Settings tab
  3. On the General page, navigate to the Node.js Version section
First, select your Node.js version in Project Settings.First, select your Node.js version in Project Settings.
First, select your Node.js version in Project Settings.

By default, a new project uses the latest Node.js LTS version available on Vercel.

Current available versions are:

  • 20.x (default)

    This version currently does not support Python, Ruby, or Go. To learn more, see Build Image.

  • 18.x (retiring early 2025)
  • 16.x (deprecated, retiring June 15th, 2024)

Node.js 20.x runtime is currently not available for Vercel Secure Compute.

Only major versions are available. Vercel automatically rolls out minor and patch updates when needed such as for a security issue fix.

You can define the major Node.js version in the engines#node section of the package.json to override the one you have selected in the Project Settings:

package.json
{
  "engines": {
    "node": "20.x"
  }
}

For instance, when you set the Node.js version to 18.x in the Project Settings and you specify a valid semver range for Node.js 20 (e.g. 20.x) in package.json, your project will be deployed with the latest 20.x version of Node.js.

The following table lists some example version ranges and the available Node.js version they map to:

Version in package.jsonVersion deployed
20.x
^20.0.0
>=20.0.0
>=18.0.0
>=16.0.0
latest 20.x version
18.x
^18.0.0
latest 18.x version
16.x
^16.0.0
latest 16.x version

To verify the Node.js version your Deployment is using, either run node -v in the Build Command or log process.version.

For dependencies listed in a package.json file at the root of a project, the following behavior is used:

  • If pnpm-lock.yaml is present, pnpm install is executed
    • If "lockfileVersion": 5.4 is present in the lock file, pnpm 7 is used
    • Otherwise, pnpm 6 is used
  • If package-lock.json is present, npm install is executed
    • If "lockfileVersion": 2 is present in the lock file, npm 8 is used
    • Otherwise npm 6 is used
  • If bun.lockb is present, the Install Command is bun install
    • Bun 1 is used
  • Otherwise, yarn install is executed

If you need to select a specific version of a package manager, see corepack.

The Node.js runtime supports files ending with .ts inside of the /api directory as TypeScript files to compile and serve when deploying.

An example TypeScript file that exports a default Node.js function and takes in the standard Node.js Request and Response objects is as follows:

api/hello.ts
import type { VercelRequest, VercelResponse } from '@vercel/node';
 
export default function (request: VercelRequest, response: VercelResponse) {
  const { name = 'World' } = request.query;
  response.send(`Hello ${name}!`);
}

An example serverless Node.js function written in TypeScript, using types from the @vercel/node module for the helper methods.

The VercelRequest and VercelResponse imports in the above example are types that we provide for the Request and Response objects, including the helper methods with Vercel. These types can be installed from npm with the following command:

npm install @vercel/node --save-dev

Installing @vercel/node for types when using Node.js on Vercel.

You can also use a tsconfig.json file at the root of your project to configure the TypeScript compiler. Most options are supported aside from "Path Mappings" and "Project References".

Each request to a Node.js Serverless Function gives access to Request and Response objects. These objects are the standard HTTP Request and Response objects from Node.js.

Vercel additionally provides helper methods inside of the Request and Response objects passed to Node.js Serverless Functions. These methods are:

methoddescriptionobject
request.queryAn object containing the request's query string, or {} if the request does not have a query string.Request
request.cookiesAn object containing the cookies sent by the request, or {} if the request contains no cookies.Request
request.bodyAn object containing the body sent by the request, or null if no body is sent.Request
response.status(code)A function to set the status code sent with the response where code must be a valid HTTP status code. Returns response for chaining.Response
response.send(body)A function to set the content of the response where body can be a string, an object or a Buffer.Response
response.json(obj)A function to send a JSON response where obj is the JSON object to send.Response
response.redirect(url)A function to redirect to the URL derived from the specified path with status code "307 Temporary Redirect".Response
response.redirect(statusCode, url)A function to redirect to the URL derived from the specified path, with specified HTTP status code.Response

The following Node.js Serverless Function example showcases the use of request.query, request.cookies and request.body helpers:

api/hello.js
module.exports = (request, response) => {
  let who = 'anonymous';
 
  if (request.body && request.body.who) {
    who = request.body.who;
  } else if (request.query.who) {
    who = request.query.who;
  } else if (request.cookies.who) {
    who = request.cookies.who;
  }
 
  response.status(200).send(`Hello ${who}!`);
};

Example Node.js Serverless Function using the request.query, request.cookies, and request.body helpers. It returns greetings for the user specified using request.send().

If needed, you can opt-out of Vercel providing helpers using advanced configuration .

We populate the request.body property with a parsed version of the content sent with the request when possible.

We follow a set of rules on the Content-type header sent by the request to do so:

Content-Type headerValue of request.body
No headerundefined
application/jsonAn object representing the parsed JSON sent by the request.
application/x-www-form-urlencodedAn object representing the parsed data sent by with the request.
text/plainA string containing the text sent by the request.
application/octet-streamA Buffer containing the data sent by the request.

With the request.body helper, you can build applications without extra dependencies or having to parse the content of the request manually.

The request.body helper is set using a JavaScript getter . In turn, it is only computed when it is accessed.

When the request body contains malformed JSON, accessing request.body will throw an error. You can catch that error by wrapping request.body with try...catch:

api/hello.js
try {
  request.body;
} catch (error) {
  return response.status(400).json({ error: 'My custom 400 error' });
}

Catching the error thrown by request.body with try...catch .

In order to use this runtime, no configuration is needed. You only need to create a file inside the api directory.

The entry point for src must be a glob matching .js, .mjs, or .ts files that export a default function.

Add an Environment Variable with name NODEJS_HELPERS and value 0 to disable helpers.

To install private npm modules, define NPM_TOKEN as an Environment Variable in your Project.

Alternatively, define NPM_RC as an Environment Variable with the contents of ~/.npmrc.

In some cases, you may wish to include build outputs inside your Serverless Function. You can run a build task by adding a vercel-build script within your package.json file, in the same directory as your Serverless Function or any parent directory. The package.json nearest to the Serverless Function will be preferred and used for both Installing and Building.

For example:

package.json
{
  "scripts": {
    "vercel-build": "node ./build.js"
  }
}

An example package.json file with a vercel-build script to execute in the build step.

Along with build script named build.js:

build.js
const fs = require('fs');
fs.writeFile('built-time.js', `module.exports = '${new Date()}'`, (err) => {
  if (err) throw err;
  console.log('Build time file created successfully!');
});

An example Node.js file, executed by the above package.json build script.

And a .js file for the built Serverless Functions, index.js inside the /api directory:

api/index.js
const BuiltTime = require('./built-time');
module.exports = (request, response) => {
  response.setHeader('content-type', 'text/plain');
  response.send(`
    This Serverless Function was built at ${new Date(BuiltTime)}.
    The current time is ${new Date()}
  `);
};

An example Node.js Serverless Function, using information from the created file from the build script.

Express.js is a popular framework used with Node.js. For information on how to use Express with Vercel, see the guide: Using Express.js with Vercel.

Last updated on March 28, 2024