Skip to content
Docs

Using the Node.js Runtime with Vercel Functions

Use the Node.js runtime to run Vercel Functions written in JavaScript or TypeScript.

Node.js-powered functions are suited to computationally intense or large functions and provide benefits like:

  • More RAM and CPU power: For computationally intense workloads, or functions that need the Node.js bundle size limits, this runtime is ideal
  • Complete Node.js compatibility: The Node.js runtime offers access to all Node.js APIs, making it a powerful tool for many applications

Vercel creates a separate function for each supported source file in the root api/ directory. Avoid creating a separate function for each API endpoint. Keep related routes in a shared function so Fluid compute can reuse instances across routes and Vercel builds fewer functions.

You can use a framework with routing support, such as Hono, or define a single fetch handler that receives requests for all HTTP methods and routes them by URL pathname. Keep shared utilities and route modules outside api/ and import them from your function entry point.

Create a shared API entry point in the root api/ directory using the fetch Web Standard export. As your API grows, add routing logic to this handler and configure rewrites to send related API paths to the same function:

api/index.ts
export default {
  fetch(request: Request) {
    return new Response('Hello from Vercel!');
  },
};

Alternatively, you can export each HTTP method as a separate export instead of using the fetch Web Standard export:

api/index.ts
export function GET(request: Request) {
  return new Response('Hello from Vercel!');
}

To use native ES modules in JavaScript handlers, use .mjs (for example, api/index.mjs) or set "type": "module" in the nearest package.json. Otherwise, Vercel compiles ES module syntax in .js files to CommonJS.

To learn more about creating Vercel Functions, see the Functions API Reference. If you need more advanced behavior, such as a custom build step or private npm modules, see the advanced Node.js usage page.

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

To learn more about the supported Node.js versions on Vercel, see Supported Node.js Versions.

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

  • If bun.lock or bun.lockb is present, bun install is executed
  • If yarn.lock is present yarn install is executed
  • If pnpm-lock.yaml is present, pnpm install is executed
  • If package-lock.json is present, npm install is executed
  • If vlt-lock.json is present, vlt install is executed
  • Otherwise, npm install is executed

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

The Node.js runtime supports TypeScript files inside the /api directory.

An example TypeScript file that exports a Web signature handler is as follows:

api/hello.ts
export default {
  async fetch(request: Request) {
    const url = new URL(request.url);
    const name = url.searchParams.get('name') || 'World';
 
    return Response.json({ message: `Hello ${name}!` });
  },
};

You can 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 Vercel 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 Vercel 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 undefined if the request has no Content-Type header or an unsupported one.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 Vercel Function example showcases the use of request.query, request.cookies and request.body helpers:

api/hello.ts
import { VercelRequest, VercelResponse } from "@vercel/node";
 
module.exports = (request: VercelRequest, response: VercelResponse) => {
  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 Vercel Function using the request.query, request.cookies, and request.body helpers. It returns greetings for the user specified using response.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 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.ts
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.

Request cancellation must be enabled on a per-route basis. See Functions API Reference for more information.

You can listen for the error event on the request object to detect request cancellation:

api/cancel.ts
import { VercelRequest, VercelResponse } from '@vercel/node';
 
export default async (request: VercelRequest, response: VercelResponse) => {
  let cancelled = false;
  request.on('error', (error) => {
    if (error.message === 'aborted') {
      console.log('request aborted');
    }
    cancelled = true;
  });
 
  response.writeHead(200);
 
  for (let i = 1; i < 5; i++) {
    if (cancelled) {
      // the response must be explicitly ended
      response.end();
      return;
    }
 
    response.write(`Count: ${i}\n`);
 
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }
 
  response.end('All done!');
};

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 August 11, 2026

Was this helpful?

supported.