Working with layers for Node.js Lambda functions
Use Lambda layers to package code and dependencies that you want to reuse across multiple functions. Layers usually contain library dependencies, a custom runtime, or configuration files. Creating a layer involves three general steps:
-
Package your layer content. This means creating a .zip file archive that contains the dependencies you want to use in your functions.
-
Create the layer in Lambda.
-
Add the layer to your functions.
Package your layer content
To create a layer, bundle your packages into a .zip file archive that meets the following requirements:
-
Build the layer using the same Node.js version that you plan to use for the Lambda function. For example, if you build your layer using Node.js 22, use the Node.js 22 runtime for your function.
-
Your layer's .zip file must use one of these directory structures:
-
nodejs/node_modules
-
nodejs/node
(whereX
/node_modulesX
is your Node.js version, for examplenode22
)
For more information, see Layer paths for each Lambda runtime.
-
-
The packages in your layer must be compatible with Linux. Lambda functions run on Amazon Linux.
-
If your layer includes native binaries or executable files, they must target the same architecture (x86_64 or arm64) as your function.
You can create layers that contain either third-party Node.js libraries installed with npm
(such as axios
or lodash
) or your own JavaScript modules.
To create a layer using npm packages
-
Create the required directory structure and install packages directly into it:
mkdir -p nodejs npm install --prefix nodejs lodash axios
This command installs the packages directly into the
nodejs/node_modules
directory, which is the structure that Lambda requires.Note
For packages with native dependencies or binary components (such as sharp
or bcrypt), ensure that they're compatible with the Lambda Linux environment and your function's architecture. You might need to use the --platform
flag:npm install --prefix nodejs --platform=linux --arch=x64 sharp
For more complex native dependencies, you might need to compile them in a Linux environment that matches the Lambda runtime. You can use Docker for this purpose.
-
Zip the layer content:
The directory structure of your .zip file should look like this:
nodejs/ └── node_modules/ ├── lodash/ ├── axios/ └── (dependencies of the other packages)
Note
Make sure your .zip file includes the
nodejs
directory at the root level withnode_modules
inside it. This structure ensures that Lambda can locate and import your packages.
To create a layer using your own code
-
Create the required directory structure for your layer:
mkdir -p nodejs/node_modules/validator
-
Create a
package.json
file for your custom module to define how it should be imported:Example package.json
{ "name": "validator", "version": "1.0.0", "type": "module", "main": "index.mjs" }
-
Create your JavaScript module file:
Example nodejs/node_modules/validator/index.mjs
export function validateOrder(orderData) { // Validates an order and returns formatted data const requiredFields = ['productId', 'quantity']; // Check required fields const missingFields = requiredFields.filter(field => !(field in orderData)); if (missingFields.length > 0) { throw new Error(`Missing required fields: ${missingFields.join(', ')}`); } // Validate quantity const quantity = orderData.quantity; if (!Number.isInteger(quantity) || quantity < 1) { throw new Error('Quantity must be a positive integer'); } // Format and return the validated data return { productId: String(orderData.productId), quantity: quantity, shippingPriority: orderData.priority || 'standard' }; } export function formatResponse(statusCode, body) { // Formats the API response return { statusCode: statusCode, body: JSON.stringify(body) }; }
-
Zip the layer content:
The directory structure of your .zip file should look like this:
nodejs/ └── node_modules/ └── validator/ ├── package.json └── index.mjs
-
In your function, import and use the modules. Example:
import { validateOrder, formatResponse } from 'validator'; export const handler = async (event) => { try { // Parse the order data from the event body const orderData = JSON.parse(event.body || '{}'); // Validate and format the order const validatedOrder = validateOrder(orderData); return formatResponse(200, { message: 'Order validated successfully', order: validatedOrder }); } catch (error) { if (error instanceof Error && error.message.includes('Missing required fields')) { return formatResponse(400, { error: error.message }); } return formatResponse(500, { error: 'Internal server error' }); } };
You can use the following test event to invoke the function:
{ "body": "{\"productId\": \"ABC123\", \"quantity\": 2, \"priority\": \"express\"}" }
Expected response:
{ "statusCode": 200, "body": "{\"message\":\"Order validated successfully\",\"order\":{\"productId\":\"ABC123\",\"quantity\":2,\"shippingPriority\":\"express\"}}" }
Create the layer in Lambda
You can publish your layer using either the Amazon CLI or the Lambda console.
Add the layer to your function
Sample app
For more examples of how to use Lambda layers, see the layer-nodejs