How to use ES modules in Netlify functions

How to use ES modules in Netlify functions

Perttu Lähteenlahti
4 min read
netlify-functionses-modulestypescriptnetlifyserverless
Share:

Why ES modules matter when working with Netlify functions

If you are building on Netlify today, you are probably already using modern JavaScript or TypeScript. That usually means import and export, not require and module.exports.

However, many older Netlify function examples still use the CommonJS style. This can be confusing, especially for beginner developers who are learning from newer JavaScript tutorials.

Using ES modules in Netlify functions makes your code easier to read, more consistent with frontend code, and closer to modern JavaScript standards.

The setup is simple once you know what to change.

The default CommonJS style in Netlify functions

By default, many Netlify functions are written like this:

exports.handler = async (event, context, callback) => {
  callback(null, {
    statusCode: 200,
    body: "Hello from Netlify"
  })
}

This works, but it has a few downsides:

  • It uses exports instead of export
  • It relies on a callback instead of returning a value
  • It feels outdated if you are used to ES modules

Luckily, Netlify fully supports ES modules.

Step 1: Enable ES modules in your Netlify project

To tell Node.js that your project uses ES modules, you need to update your root package.json.

Add this field at the top level:

{
  "type": "module"
}

This single line tells Netlify and Node.js to treat .js and .ts files as ES modules.

Once this is in place, you can use import and export syntax in your Netlify functions.

Step 2: Use the ES module handler syntax

With ES modules enabled, you no longer use exports.handler.

Instead, you export a function directly.

Here is the ES module version of a Netlify function written in TypeScript:

import { Handler } from "@netlify/functions"

export const handler: Handler = async (event, context) => {
  return {
    statusCode: 200,
    body: "Hello from an ES module Netlify function"
  }
}

This style is cleaner and easier to follow, especially if you are already using TypeScript elsewhere in your project.

No more callbacks in Netlify functions

When using ES modules, you should also stop using the callback pattern.

If you previously had code like this:

callback(null, {
  statusCode: 200,
  body: html
})

You should replace it with a return statement:

return {
  statusCode: 200,
  body: html
}

Returning the response directly is simpler and avoids unnecessary complexity.

Netlify fully supports this async return style.

Why this approach works better on Netlify

Netlify functions are designed to work well with async code. Returning a response object is more readable and less error prone than managing callbacks.

Using ES modules also gives you:

  • Cleaner imports
  • Better compatibility with modern tooling
  • Easier sharing of code between frontend and backend
  • A more consistent developer experience

For new Netlify projects, this should be your default setup.

Common issues to watch out for

When switching to ES modules in Netlify functions, keep these points in mind:

  • The type: "module" field must be in the root package.json
  • Use export instead of exports
  • Do not mix callbacks with return statements
  • Make sure your build setup supports TypeScript if you are using it

Once everything is aligned, Netlify functions work smoothly with ES modules.

Conclusion

Using ES modules in Netlify functions is a small change that makes a big difference. It brings your serverless code in line with modern JavaScript and TypeScript practices.

To recap:

  • Add "type": "module" to your root package.json
  • Export your handler using export
  • Return responses instead of using callbacks

With this setup, your Netlify functions will feel cleaner, more modern, and easier to maintain as your project grows.

Manage Netlify on the go

Download Netli.fyi and monitor your sites, check deploys, and manage your projects from anywhere.

Related articles