Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/bun-lambda/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.DS_Store
.serverless/
node_modules/
bun-lambda-layer/
*.zip
92 changes: 92 additions & 0 deletions packages/bun-lambda/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# bun-lambda

A custom runtime layer that runs Bun on AWS Lambda.

## Setup

First, you will need to deploy the layer to your AWS account. Clone this repository and run the `publish-layer` script to get started.

```sh
git clone [email protected]:oven-sh/bun.git
cd packages/bun-lambda
bun install
bun run publish-layer
```

### `bun run build-layer`

Builds a Lambda layer for Bun and saves it to a `.zip` file.

| Flag | Description | Default |
| ----------- | -------------------------------------------------------------------- | ---------------------- |
| `--arch` | The architecture, either: "x64" or "aarch64" | aarch64 |
| `--release` | The release of Bun, either: "latest", "canary", or a release "x.y.z" | latest |
| `--output` | The path to write the layer as a `.zip`. | ./bun-lambda-layer.zip |

Example:

```sh
bun run build-layer -- \
--arch x64 \
--release canary \
--output /path/to/layer.zip
```

### `bun run publish-layer`

Builds a Lambda layer for Bun then publishes it to your AWS account.

| Flag | Description | Default |
| ---------- | ----------------------------------------- | ------- |
| `--layer` | The layer name. | bun |
| `--region` | The region name, or "\*" for all regions. | |
| `--public` | If the layer should be public. | false |

Example:

```sh
bun run publish-layer -- \
--arch aarch64 \
--release latest \
--output /path/to/layer.zip \
--region us-east-1
```

## Usage

Once you publish the layer to your AWS account, you can create a Lambda function that uses the layer.

Here's an example function that can run on Lambda using the layer for Bun:

### HTTP events

When an event is triggered from [API Gateway](https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html), the layer transforms the event payload into a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request). This means you can test your Lambda function locally using `bun run`, without any code changes.

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

### Non-HTTP events

For non-HTTP events — S3, SQS, EventBridge, etc. — the event payload is the body of the [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request).

```ts
export default {
async fetch(request: Request): Promise<Response> {
const event = await request.json();
// ...
return new Response();
},
};
```
3 changes: 3 additions & 0 deletions packages/bun-lambda/bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#! /bin/sh
export BUN_INSTALL_CACHE_DIR=/tmp/bun/cache
exec /opt/bun --cwd $LAMBDA_TASK_ROOT /opt/runtime.ts
Binary file added packages/bun-lambda/bun.lockb
Binary file not shown.
33 changes: 33 additions & 0 deletions packages/bun-lambda/example/lambda.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import type { Server, ServerWebSocket } from "bun";

export default {
async fetch(request: Request, server: Server): Promise<Response | undefined> {
console.log("Request", {
url: request.url,
method: request.method,
headers: request.headers.toJSON(),
body: request.body ? await request.text() : null,
});
if (server.upgrade(request)) {
console.log("WebSocket upgraded");
return;
}
return new Response("Hello from Bun on Lambda!", {
status: 200,
headers: {
"Content-Type": "text/plain;charset=utf-8",
},
});
},
websocket: {
async open(ws: ServerWebSocket): Promise<void> {
console.log("WebSocket opened");
},
async message(ws: ServerWebSocket, message: string): Promise<void> {
console.log("WebSocket message", message);
},
async close(ws: ServerWebSocket, code: number, reason?: string): Promise<void> {
console.log("WebSocket closed", { code, reason });
},
},
};
16 changes: 16 additions & 0 deletions packages/bun-lambda/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"devDependencies": {
"bun-types": "^0.4.0",
"jszip": "^3.10.1",
"oclif": "^3.6.5",
"prettier": "^2.8.2"
},
"dependencies": {
"aws4fetch": "^1.0.17"
},
"scripts": {
"build-layer": "bun scripts/build-layer.ts",
"publish-layer": "bun scripts/publish-layer.ts",
"format": "prettier --write ."
}
}
Loading