How to use Bun on AWS Lambda — A Step-By-Step Guide

Updated on
Bun sitting on a tortoise while a dog is holding an AWS Lambda placard

Wherever you go, Bun is popping up since it was first announced and released.

NodeJS is dead, Bun is the future. ~ LinkedIn Certified Devs

Bun has taken over the internet because of its features and performance. Should you make the switch from NodeJS to Bun on AWS Lambda? Bun is not just a runtime like NodeJS, Bun is a:

Today we will learn how to use Bun on AWS Lambda with an Amazon Linux runtime and a Bun Lambda layer.

Publish Bun Lambda layer

This is an optional step for those who want to publish Bun Lambda layer by themselves using our public Bun Lambda layer.

Make sure you have AWS CLI setup.

To setup AWS CLI, follow this 5 minute setup guide.

First, clone the repo and go into packages/bun-lambda.

git clone [email protected]:oven-sh/bun.git
cd bun/packages/bun-lambda

Now install packages and build the Lambda layer:

bun install
bun run build-layer

Now publish the layer

bun run publish-layer

Your Bun Lambda layer will be published in your default region with aarch64.

To customize these options follow the Bun README for AWS Lambda Layer.

Create a Lambda Function with Amazon Linux 2

  1. Go to AWS Lambda console and click on Create function or simply go to this link to create a new function.
  2. Select Author from scratch.
    1. Put your function name in Function name input. Eg. my-bun-func
  3. Select Provide your own bootstrap on Amazon Linux 2 from Custom runtime
  4. Select arm64 as Architecture

![](./images/Selecting Custom runtime as Provide your own bootstrap on Amazon Linux 2 during Create function - Bun AWS Lambda.webp)

Now click on Create function button. You’ll get to see the green banner with Successfully created the function.

![](./images/Green banner with message Successfully created the function - Bun AWS Lambda.webp)

Write code for Bun Lambda function

Go to the Code source and create a new file with index.ts

Paste the code below where we are just returning Hello from LearnAWS with status 200 and logging the function arn header:

export default {
  async fetch(request: Request): Promise<Response> {
    console.log(request.headers.get("x-amzn-function-arn"));
    // ...
    return new Response("Hello from LearnAWS!", {
      status: 200,
      headers: {
        "Content-Type": "text/plain",
      },
    });
  },
};

This is how your Bun Lambda code should look like:

![](./images/Source code for AWS Lambda handler function called fetch for deployment - Bun.webp)

Click on Deploy deploy the changes.

Update function handler

Scroll down to Runtime settings and click on Edit.

![](./images/Updating function handler name with function name that Bun will call by editing runtime settings.webp)

  • Update the Handler option with index.fetch
    • index is the name of our file.
    • fetch is the name of function we want Bun to call.
  • Click on Save.

You can name your handler whatever you want, just make sure you have the same function name in the file eg. index.main

![](./images/Edit runtime settings by choosing Custom runtime on Amazon Linux 2 - Bun AWS Lambda.webp)

Attach Bun Lambda layer to the Function

Scroll down to Layers and click on Add a layer.

![](./images/Add a AWS Lambda Layer to Lambda function - Bun.webp)

Use your own published Bun Lambda layer

If you have published the Bun Lambda layer on your own account, you can select it by going to Custom layers then select Bun from the Custom layers dropdown and version.

![](./images/Select Custom layers for Bun AWS Lambda from dropdown and version.webp)

Use public Bun Lambda layer

If you want to use our or any other public Lambda layer then go to Specify an ARN and paste Lambda layer ARN for Bun. Our Bun Lambda layer ARN is: arn:aws:lambda:us-east-1:205979422636:layer:bun:1

![](./images/Choose a layer and specify an ARN for Bun Lambda layer in AWS.webp)

Now click on Add button.

Verify the Bun Lambda layer

When you scroll down to Layers you’ll see the Bun layer attached:

![](./images/Verify if Bun AWS Lambda layer is attached.webp)

Enable Lambda Function URL

To test things out we can enable function URL for our Lambda.

  • Go to Configuration tab, navigate to Function URL and click on Create function URL.

![](./images/Create AWS Lambda function URL and enable it in Configuration tab - Bun.webp)

  • Select NONE in Auth type which will make our AWS Lambda function publicly accessible by anyone via AWS Lambda function URL.
  • Hit Save to deploy the changes.

![](./images/Select NONE in Auth type for publicly accessible Lambda function URL - Bun.webp)

Now you’ll see your AWS Lambda Function URL in Lambda Function overview page:

![](./images/Lambda Function URL in AWS Lambda Overview Page - Bun.webp)

Test your Bun Lambda function using function URL

Click on the blue Lambda Function URL link.

You’ll get to see your Lambda say Hello.

![](./images/Viewing output of Bun function in AWS Lambda function URL.webp)

Go to CloudWatch Log groups and navigate to your function name to get the logs from the Function. As you can see here we are getting the Lambda ARN in the INFO of the log.

![](./images/Getting Logs of Lambda function from CloudWatch log groups with Lambda ARN - Bun.webp)

Parsing Query Params: An Example

I’ve used the URL constructor to get pathname and get the first item after /.

You can learn more on MDN about the Request variable and it’s properties.

As of now search param didn’t work with Bun as it was not appearing in the request.url.

const path = new URL(request.url).pathname;
const name = path.split("/")[1]; // get the first param
return new Response(`You're awesome ${name}!`, {
  //...
});

Don’t forget to Deploy the function.

Test our Path Parameter Changes

Now append name with / in the URL: {{Lambda-URL}}/{{Your-Name}}

![](./images/Testing our Bun AWS Lambda function with query params.webp)

Test your Lambda Function with SAM Bun

It might be too much work for you to build APIs directly on AWS Lambda.

But with Bun, you can directly run and test your Lambda functions locally with bun run.

Create Bun HTTP server

  1. Create a directory eg. bun-lambda
  2. Copy your Lambda code into index.ts
  3. Create a file with server.ts and add the code below which will simply create HTTP server in Bun.
import fn from "./index.ts"; // import your lambda function

const server = Bun.serve({
  port: 3000,
  fetch: fn.fetch,
});

console.log(`Listening on http://localhost:${server.port}`);

Test local Bun Lambda server

Simply run your server with bun run.

bun run server.ts

You’ll see the server running with output:

Listening on http://localhost:3000

Now open the link and append your name after the /. You’ll get to see the same output as you saw from your AWS Lambda server.

![](./images/Output from Bun AWS Lambda function URL.webp)

So is Bun better than NodeJS on AWS Lambda?

Hold your spear before you make any decision.

Bun is not officially supported by AWS Lambda yet (and it won’t be anytime soon), since we had to use the Lambda layer with Amazon Linux.

The current state of Bun with AWS Lambda

  • Many features of API Gateway and other Lambda Function integration still doesn’t work.
  • Cold start is more than 2x of NodeJS.
  • Built-in error handler doesn’t work with API Gateway.
  • Setting up Lambda with Bun takes a while.
  • All NodeJS libraries might not work with Bun.

Where to use Bun then?

NodeJS gives us a decent speed and performance. But Bun takes it to the next level.

Even with Bun 1.0 out in the wild — we can’t use it in production with Lambda.

If you have a consistent and predictable traffic:

  • Bun on EC2 with Amazon Linux can be a match made in heaven.

If you’re just swapping NodeJS with Bun:

  • Make sure to test the ins and outs of your application.

Building something from Scratch using Bun APIs would be the best thing to do if you’re looking for speed and performance.

Have you tried out Bun yet? If not, what are you planning to do with Bun? Leave your thoughts in the comments.


Hills 🏔 and Skills, What's Common?

They both need you to be on top.

You will get lifetime access with:

All yours, just at:

$149

Just type and your search result will magically appear here