Deploying Sveltekit to AWS Lambda
I had a hard time using the sveltekit-adapter-aws and services like Elastic Beanstalk, ECS, and CloudFlare Pages. So I created a minimal example of deploying Sveltekit to AWS Lambda using the CDK.
The source code for this blog post is also available on GitHub
Known issues found after deploying this post
- Routing (solved): set the
ORIGIN
environment variable in the Lambda function to the deployed URL - Actions (solved): when behind a CloudFront distribution, actions need some tweaking to the methods, headers and query strings
Solutions to the known issues above can be found in the infra
folder on the dev branch of my open source event management system Cobra Events that takes this blog post further.
Prerequisites
- Install Node.js, i.e. using Node version manager (NVM)
- Install and use Node version 18, i.e.
nvm install 18 && nvm use 18
if using NVM - Create a basic Sveltekit application
npm create svelte@latest <app-name>
- Create an AWS account
- Authenticate your local environment for AWS, i.e.
aws sso login
, pasting in temporary credentials from SSO login, using a profile, etc. - Bootstrap your AWS account for the AWS Cloud Development Kit (CDK), i.e.
npx cdk bootstrap
Steps
- Create a directory to store the lambda handler. In this example, we'll call it
pre-build-lambda-assets
mkdir pre-build-lambda-assets
2. Add a minimal package.json
file in the new directory. This tells the Node runtime that we're using the module
type, which Svelte's node adapter uses to output the assets. It also installs the only two dependencies we'll need, aws-serverless-express
to make the server Lambda-friendly and polka
as a minimal web server.
Note: you can replacepolka
withexpress
or your Node server of choice. I just chosepolka
since it was what was used in theindex.js
file that Svelte outputs in the build directory and make minor tweaks to get it working with Lambda.
3. Run npm install
in this folder to generate a package-lock.json
. And then delete the node_modules
folder that it generated in this folder. Our script will install a fresh node_modules
in the build directory when we deploy rather than copying these.
4. Create a lambda handler file. This creates a basic web server just like the original Sveltekit node adapter , and then wraps it with the aws-serverless-express
functions. And finally, it passes in the event
and context
from the Lambda request.
5. Create a minimal AWS CDK stack that will deploy the Lambda function and API Gateway proxy.
6. Create a minimal deployment script to run the Sveltekit build, copy the assets we just created into the build directory, install the dependencies, and deploy with the CDK.
7. Add permissions to run this script
chmod +x ./deploy.sh
8. Install the Sveltekit node adapter
npm install @sveltejs/adapter-node --save-dev
9. Update the svelte.config.js
configuration file to use the node adapter
10. Run the deploy script
./deploy.sh
11. Open the hello world page in the browser by going to the url that the successful deployment outputs, named APIDomain
Recap
We created the following:
- A Lambda function that runs our Sveltekit code
- An API Gateway that proxies all requests to the Lambda function
Logical next steps are to add a CloudFront distrbution in front of API Gateway to cache requests for faster performance and adding an SSL certificate and custom domain to the distribution.
Pros of this approach
- Serverless: no paying for servers when not in use, can be scaled without having to configure an auto scaling policy, larger instance size, etc.
- Easy deployment
- Easy permissions with IAM. You can just grant the Lambda function with the policies it needs
Cons
- A little hacky until there's a custom adapter to handle this
Happy coding! SL