DEV Community

WonderfulSoap
WonderfulSoap

Posted on

How to Extract AWS Lambda Runtime Source Code: Using Node.js as an Example

AWS Lambda supports runtimes for a wide variety of languages, but under the hood, its mechanism is language-agnostic — it is built on the Lambda Runtime API.
The official runtimes for each language are implemented on top of the Runtime API, including the handler-loading mechanism.

So the question is: if we want to see how each language's runtime is implemented and how the handler is loaded, what should we do?

This article will discuss this topic using the extraction of the Node.js Runtime as an example.

Attempting to Extract the Runtime Files Directly from Lambda

We know that when Lambda starts, it loads /var/runtime/bootstrap, so it's natural to wonder: what files are actually in the /var/runtime directory?

We can try creating a Node.js Lambda function that lists the files in the /var/runtime directory and outputs them to the logs.

After creating the Lambda function, we write the following handler code:

import fs from "node:fs/promises";

export const handler = async () => {
  console.log("== /var/runtime ==");
  try {
    console.log(await fs.readdir("/var/runtime"));
  } catch (e) {
    console.log("fail /var/runtime:", e.message);
  }

  return "ok";
};

Enter fullscreen mode Exit fullscreen mode

After invoking this Lambda function, the logs show the following result:

Function Logs:
2026-02-17T15:08:34.735Z    441910a6-5f21-4d67-b972-ef2a90133c0b    INFO    == /var/runtime ==
2026-02-17T15:08:34.754Z    441910a6-5f21-4d67-b972-ef2a90133c0b    INFO    [
  'THIRD-PARTY-LICENSES.txt',
  'bootstrap',
  'ca-cert.pem',
  'index.mjs',
  'node_modules',
  'rapid-client.node',
  'runtime-release'
]
Enter fullscreen mode Exit fullscreen mode

We can see that the /var/runtime directory contains not only the bootstrap file, but also index.mjs, node_modules, and other files. We have good reason to believe that these files make up the Node.js runtime implementation.

We can try zipping the /var/runtime directory and returning it to the caller as a binary response, so we can extract the files locally.

Zipping the /var/runtime Directory

To accomplish the above, we need to make the following preparations:

  1. Since the zipping process may take some time and the default Lambda function timeout is only 3 seconds, we need to increase the Lambda function's timeout to a longer duration (e.g., 1 minute).
  2. To prevent running out of memory, we increase the memory to 512 MB.
  3. Then, in the Lambda function's settings, enable Function URL and set Auth to NONE, so that we can use curl to directly invoke the Lambda function and download the zipped file.

Next, we create a local directory and implement the corresponding Lambda function:

mkdir dump-nodejs-runtime
cd dump-nodejs-runtime
npm init -y
npm i archiver
touch index.mjs
Enter fullscreen mode Exit fullscreen mode

Note that since the Lambda execution environment does not include the zip command, we need to install the archiver package via npm i archiver to implement zip creation.

The handler code is as follows:

import archiver from "archiver";
import fs from "node:fs";
import fsp from "node:fs/promises";

export const handler = async () => {
  const outPath = "/tmp/var-runtime.zip";

  const out = fs.createWriteStream(outPath);
  const zip = archiver("zip", { zlib: { level: 9 } });

  zip.on("error", (e) => { throw e; });
  out.on("error", (e) => { throw e; });

  zip.pipe(out);
  zip.glob("**/*", { cwd: "/var/runtime", dot: true, ignore: ["node_modules/**"] });
  await zip.finalize();
  await new Promise((r) => out.on("close", r));

  const st = await fsp.stat(outPath);
  console.log("zip size bytes:", st.size);


  const b64 = (await fsp.readFile(outPath)).toString("base64");
  return {
    statusCode: 200,
    isBase64Encoded: true,
    headers: {
      "content-type": "application/zip",
      "content-disposition": 'attachment; filename="var-runtime.zip"',
      "cache-control": "no-store",
    },
    body: b64,
  };
};
Enter fullscreen mode Exit fullscreen mode

The handler above zips all files in the /var/runtime directory (excluding the node_modules directory) and returns the zip file to the caller. This way, we can download the Runtime archive via Function URL.

Then zip the Lambda function files, upload the package to Lambda, and open the corresponding Function URL to download the Runtime archive:

zip -r ../dump-nodejs-runtime.zip .
# Upload this zip package to Lambda
# Then open the corresponding Function URL to download the Runtime archive
Enter fullscreen mode Exit fullscreen mode

After downloading and extracting the zip file var-runtime.zip, we get the following files:

bootstrap
index.mjs
rapid-client.node
THIRD-PARTY-LICENSES.txt
ca-cert.pem
node_modules
runtime-release
Enter fullscreen mode Exit fullscreen mode

To extract the Runtime for other languages, simply follow the same approach.

Extracting the Runtime Directly from Docker Images

Although the approach above can extract the Runtime files from an official Lambda environment, it is still rather cumbersome.

There is actually a much simpler way to extract the Runtime files.

AWS provides Docker images that contain the official Lambda runtimes, and we can extract the files directly from these images:

https://gallery.ecr.aws/lambda

These images contain the official Lambda runtime files, and we can extract them directly.

For Node.js, we can extract the corresponding files from the public.ecr.aws/lambda/nodejs:24 image. Simply run the following command to enter the container:

docker run -it --rm --entrypoint /bin/sh public.ecr.aws/lambda/nodejs:24
Enter fullscreen mode Exit fullscreen mode

Inside the container, we can list the files in the /var/runtime directory and confirm they match what we saw in the Lambda environment:


sh-5.2# ls -al /var/runtime
total 696
drwxr-xr-x 1 root root   4096 Feb 17 14:26 .
drwxr-xr-x 1 root root   4096 Feb 17 15:29 ..
-rwxr-xr-x 1 root root   4033 Feb  3 16:44 bootstrap
-rw-r--r-- 1 root root 181066 Feb  3 16:49 ca-cert.pem
-rw-r--r-- 1 root root  54889 Feb  3 16:49 index.mjs
drwxr-xr-x 3 root root   4096 Feb 17 14:26 node_modules
-rwxr-xr-x 1 root root 343376 Feb  3 16:49 rapid-client.node
-rw-r--r-- 1 root root     63 Feb  3 16:49 runtime-release
-rw-r--r-- 1 root root 104462 Feb  3 16:44 THIRD-PARTY-LICENSES.txt
Enter fullscreen mode Exit fullscreen mode

So we can simply copy the /var/runtime directory out of the container:

docker create --platform=linux/amd64 --name lambda24 public.ecr.aws/lambda/nodejs:24
docker cp lambda24:/var/runtime ./var-runtime
docker rm lambda24
Enter fullscreen mode Exit fullscreen mode

After execution, the local ./var-runtime directory will contain the Node.js 24 runtime files.

I uploaded the files extracted from the Docker image to here

Top comments (0)