Build functions with JavaScript

To add a serverless function to your project, create a JavaScript file in your functions directory. The default functions directory is YOUR_BASE_DIRECTORY/netlify/functions. Netlify will access the functions directory during every build, preparing and deploying each supported code file as a function.

You can store your function file directly under the functions directory or in a subdirectory dedicated to the function. The function endpoint is determined by its filename or the name of its dedicated parent directory.

For example, with a target function endpoint name of hello, you could save the function file in one of the following ways:

  • netlify/functions/hello.js
  • netlify/functions/hello/hello.js
  • netlify/functions/hello/index.js

Any of the above formats would deploy a synchronous function that can be called on the following endpoint, relative to the base URL of your site: /.netlify/functions/hello.

For a background function, the function file name must end with -background, or the sub-directory that contains the background function file must end with -background.

With an example target function endpoint name of hello-background, you could save a background function file in one of these ways:

  • netlify/functions/hello-background.js
  • netlify/functions/hello-background/hello-background.js
  • netlify/functions/hello-background/index.js

These formats would deploy a background function that can be called on the following endpoint, relative to the base URL of your site: /.netlify/functions/hello-background.

Reserved names for event-driven functions

Certain function names are reserved as triggers initiated by various built-in events on your Netlify site. You can find a list of these function names and how they work on the page about event-driven functions.

# Synchronous function format

Each JavaScript file to be deployed as a synchronous function must export a handler method with the following general syntax:

exports.handler = async function(event, context) {
    // your server-side functionality
}

Netlify provides the event and context parameters when the function is invoked. When you call a function’s endpoint, the handler receives an event object similar to the following:

{
  "path": "Path parameter (original URL encoding)",
  "httpMethod": "Incoming request’s method name",
  "headers": {Incoming request headers},
  "queryStringParameters": {Query string parameters},
  "body": "A JSON string of the request payload",
  "isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encoded"
}

The context parameter includes information about the context in which the function was called, like certain Identity user information, for example.

Although Netlify Functions still support callback syntax, async is more versatile. Because async functions return a promise, we recommend returning a response with at least an HTTP status code instead of allowing the function to time out. Using async in your function code doesn’t automatically designate a function as a background function.

Here’s a simple example function, hello.js:

exports.handler = async function (event, context) {
  return {
    statusCode: 200,
    body: JSON.stringify({ message: "Hello World" }),
  };
}

This function would be called from your site at /.netlify/functions/hello, and on success, would return the 200 status code and the message, “Hello, World”.

Synchronous functions can return a response object that includes the following information:

{
  "isBase64Encoded": true|false,
  "statusCode": httpStatusCode,
  "headers": { "headerName": "headerValue", ... },
  "multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
  "body": "..."
}

# Background function format

This feature is in BETA and may not be available on all plans.

Background function syntax is similar to synchronous function syntax, but you will generally pass the function result to a destination other than the originating client. Each JavaScript file to be deployed as a background function must export a handler method. Like the synchronous function format, Netlify provides the event and context parameters for background function execution. Although background functions rely on asynchronous invocation, they don’t require the use of async JavaScript syntax.

Here’s an example of a background function, send-pdf-background.js:

const { jsPDF } = require("jspdf");
const nodemailer = require("nodemailer");
const mg = require("nodemailer-mailgun-transport");

const transporter = nodemailer.createTransport(
  mg({
    auth: {
      api_key: process.env.MAILGUN_API_KEY,
      domain: process.env.MAILGUN_DOMAIN,
    },
  })
);

exports.handler = async function (event) {
  const { content, destination } = JSON.parse(event.body);
  console.log(`Sending PDF report to ${destination}`);

  const report = Buffer.from(
    new jsPDF().text(content, 10, 10).output("arraybuffer")
  );
  const info = await transporter.sendMail({
    from: process.env.MAILGUN_SENDER,
    to: destination,
    subject: "Your report is ready!",
    text: "See attached report PDF",
    attachments: [
      {
        filename: `report-${new Date().toDateString()}.pdf`,
        content: report,
        contentType: "application/pdf",
      },
    ],
  });

  console.log(`PDF report sent: ${info.messageId}`);
};

This background function would be called from your site at /.netlify/functions/send-pdf-background. When invoked, the function returns an initial 202 success response. When successfully executed, a PDF report is generated and emailed as an attachment.

# Environment variables

You can access Netlify build environment variables to inject their values into your function files before your functions are deployed. A common use case is modifying function behavior depending on deploy context, for example fetching data from a staging vs. production third-party API endpoint.

You can also create deploy environment variables on Netlify and access their values in your functions at execution time. A common use case is injecting information you don’t want to store in your repository such as API keys. Because Netlify Functions are powered by AWS Lambda, AWS’s environment property limits apply to deploy environment variables used with Netlify Functions.

# Manage dependencies

With continuous deployment, Netlify’s buildbot installs your dependencies and automatically zips them with your functions for deployment.

# package.json

To optimize build performance, we recommend specifying function dependencies in the top-level package.json file in the site’s base directory. Here’s an example of a recommended layout:

my-base-directory/
├─ package.json
├─ node_modules
└─ netlify/
   └─ functions/
        ├─ hello.js
        └─ send-pdf-background.js

# Automated dependency bundling

With continuous deployment, Netlify parses each function file to note its dependencies. For each function, Netlify then pulls the required dependencies from the associated node_modules folder and zips them with the function file for deployment. For more details about how this bundling functionality works, visit the repository for the underlying module: @netlify/zip-it-and-ship-it.

# Tools

We’ve made a few tools to help with writing and testing your JavaScript functions on Netlify:

  • Netlify Dev – Netlify CLI includes tools for local function development through a simulated Netlify production environment. The netlify dev command starts a framework server if a framework is detected and handles redirects, proxy rules, Netlify Functions, and add-ons.
  • Netlify CLI Functions debugging – The netlify functions:serve command (currently in beta) enables you to simulate Netlify Functions in a standalone server without the full overhead of Netlify Dev. You can inspect the functions server process to debug functions.
  • netlify-lambda – We provide an optional build tool for Netlify Functions that is no longer recommended for new projects or common use cases. The repository README includes a comparison between Netlify Dev and netlify-lambda.

If you need to parse a multipart/form-data-encoded event.body, we recommend using busboy. To learn more, visit our blog article on processing multipart form data with Netlify Functions.

# TypeScript support

Netlify also supports functions built with TypeScript. Read our docs on building with TypeScript to learn more about setting them up.

Optional configuration: Node.js version for runtime