Typescript on AWS Lambda

Saturday, 2 July 2022

AWS Lambda supports a number of languages by default and is extensible to support any runtime you want. That comes at an additional cost in terms of implementing and hosting, though.

The main (and initial) runtimes on Lambda were Javascript and Python.

Background

I wasn't satisfied with the approach of "transpiling" my Typescript to Javascript to deploy it to Lambda so started looking for alternate methods of running Typescript on Lambda.

Native support for Deno would have been nice, but that's not (yet) available.

This got me thinking about ts-node since I use that in development (and in some production environments), I figured that maybe it could be used in Lambda.

Turns out it can, but as usual - at a cost.

Lambda supports the NODE_OPTIONS environment variable, which allows you to "register" the ts-node module, running Typescript without the intermediary step of "transpilation" to Javascript.

Creating the project

Start by creating a fresh Typescript project, same as here.

1yarn init
2yarn add typescript ts-node
3yarn add -D @types/node
4yarn run tsc --init

Create a handler, call it index.ts

1export const handler = () => { console.log("hello, typescript!"); return Promise.resolve(); }

Package this up for deployment to Lambda.

1zip -vr fn.zip ./

(This can obviously be automated, but for simplicity's sake, I'll run through the "manual" process)

Configure Lambda

Create an empty Lambda function selecting the Javascript runtime.

Configure the "Environment variables" in the function, adding:

NODE_OPTIONS with the value --require ts-node/register --no-warnings

Increase the memory available to at least 512MB and the function timeout to at least 5 seconds. I'll cover this in the caveats section below.

Upload your packaged function from above.

Test the function and observe the magic of Typescript running seamlessly in Lambda.

Caveat

Although this does work, it may not be ideal to use in production.

The typescript package adds ~64MB of bloat to your package.

This has the knock-on effect of slowing down your function on first execution, the dreaded "cold-start" issue.

Running functions with ts-node also increases memory usage, which is why the memory needs to be increased to at least 512MB. Testing my basic function used ~280MB of memory, but I recommend 512MB so there's a bit of a buffer.

Conclusion

Should you use this? Probably not. Did I have fun playing with this? Sure did.