AWS Lambda
ES6
JavaScript
Cloud Computing
Serverless

Can we use the ES6 class syntax in AWS Lambda?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Yes, you can use ES6 class syntax in AWS Lambda as long as you deploy to a Node.js runtime that supports modern JavaScript. The important detail is that Lambda still needs an exported handler function, so classes are usually used to organize your code behind that handler rather than replace it entirely.

Use a class behind the Lambda handler

The most common pattern is to define a class for your business logic and keep a thin handler that delegates to it.

CommonJS example:

javascript
1class OrderService {
2  async handle(event) {
3    const orderId = event.pathParameters?.id;
4    return {
5      statusCode: 200,
6      body: JSON.stringify({ orderId, status: "ok" }),
7    };
8  }
9}
10
11const service = new OrderService();
12
13exports.handler = async (event) => {
14  return service.handle(event);
15};

This works well because the exported Lambda entry point is still a plain function, but the class keeps related logic together.

Instantiating the class outside the handler can also help you reuse expensive setup between warm invocations, such as SDK clients or configuration loading.

ES modules work too

If your Lambda package uses ES modules, the pattern is the same even though the export syntax changes:

javascript
1class UserService {
2  async handle(event) {
3    return {
4      statusCode: 200,
5      body: JSON.stringify({ message: "Hello from Lambda", input: event }),
6    };
7  }
8}
9
10const service = new UserService();
11
12export const handler = async (event) => {
13  return service.handle(event);
14};

The class syntax itself is not the issue. The only requirement is that the deployed file exports the handler name that Lambda is configured to call.

When classes are useful in Lambda

Classes are especially helpful when your function has:

  • injected dependencies such as repositories or API clients
  • shared validation or mapping logic
  • a growing set of helper methods that belong together

For example:

javascript
1class InvoiceService {
2  constructor(db) {
3    this.db = db;
4  }
5
6  async getInvoice(id) {
7    return this.db.findById(id);
8  }
9
10  async handle(event) {
11    const id = event.pathParameters?.id;
12    const invoice = await this.getInvoice(id);
13    return {
14      statusCode: 200,
15      body: JSON.stringify(invoice),
16    };
17  }
18}

That is easier to test than one large handler function full of inline logic.

What not to do

A common mistake is exporting an unbound instance method directly:

javascript
1class BadHandler {
2  async handle(event) {
3    return { statusCode: 200, body: JSON.stringify({ ok: true }) };
4  }
5}
6
7const bad = new BadHandler();
8exports.handler = bad.handle;

This can fail because this is no longer bound the way you expect when Lambda invokes the function.

A safer version binds the method explicitly:

javascript
exports.handler = bad.handle.bind(bad);

In practice, the wrapper function pattern is usually clearer:

javascript
exports.handler = async (event) => bad.handle(event);

Keep the Lambda model in mind

Using classes does not change how Lambda scales or executes. Each invocation still calls the configured handler. Cold starts still exist. Stateless design is still preferred for request-specific data.

What you can safely keep across invocations are reusable objects such as:

  • database clients
  • AWS SDK clients
  • configuration objects
  • cached reference data that is safe to reuse

Classes can help structure those dependencies, but they are not a requirement. If a small handler is simple enough without a class, a class may add ceremony without much benefit.

Common Pitfalls

The biggest mistake is assuming Lambda can invoke a class directly as the handler. Lambda invokes an exported function, not a class constructor.

Another common issue is losing this by exporting a method reference without binding or wrapping it.

People also overdesign small Lambdas. If the function is tiny, a class may not improve anything.

Finally, make sure your module format, handler path, and runtime configuration all agree. ES6 syntax support does not fix a mismatched handler export.

Summary

  • Yes, ES6 classes are fully usable inside AWS Lambda Node.js functions.
  • Keep an exported handler function as the Lambda entry point.
  • Use classes to organize business logic, dependencies, and helper methods.
  • Wrap or bind instance methods instead of exporting them blindly.
  • Instantiate reusable dependencies outside the handler when warm-start reuse is beneficial.

Course illustration
Course illustration

All Rights Reserved.