Why I Migrated My SPA from AWS Lambda to Cloudflare Workers
The site
I wanted to build a simple SPA that would help me and my friends identify AI-generated images, keep my hand in full-stack development since I've spent the past few years steeped more in frontend, and provide a project for people in my community to open PRs against. (I have a running policy that I will be a resource for anyone who wants to practice development, and one of the best ways I've found to do that that is to have a simple but real-world project that people can contribute to.)
With that in mind, I originally built this app using Supabase, AWS Lambda, and Vercel, but I've since migrated it to Cloudflare Workers/Pages. AWS might look better on a resume, but it's just not worth the headache for something this small. I also chose to use an R2 bucket for image storage because of many claims that R2 is cheaper than S3 and works with S3 functions. To be transparent, I didn't do the full math on this.
The frontend
Simple Vite React app with Mantine. Not too much to say.
The backend
Deploying the lambdas was a bit of a nightmare. I know I run a risk by saying that, since they're supposed to be so easy, but it took forever to get the configuration right. I wanted to not use any LLM support for this, since it's such a simple app and I think it's important to flex those muscles now and then, but I ended up resorting to ChatGPT (this was months ago, before Claude was the LLM du jour, and slightly before Claude Code was even an option). Which resulted in the infurating experience of having ChatGPT correct the configuration that I had literally copy/pasted from the AWS docs... and it was correct.
Nevertheless, I finally got the lambdas working, and the images fetching and displaying to the frontend. At that point, I just stopped looking at it for a while.
The migration
A few weeks ago, I went to look at the site, and it was down. Did some digging, and both Cloudflare and AWS had some changes to how CORS works and how to fetch objects from R2 buckets. That might be on me - I definitely wasn't monitoring updates for this stack. I have enough to keep track of for my day job. Regardless, I started diving into how to update the configuration and fetching logic and almost immediately decided that it would be easier to just migrate everything over, even anticipating that it would be a headache to do that.
Turns out the migration was a breeze. The frontend was trivially easy to deploy on Cloudflare Pages. The backend was a bit more involved, but not much. The actual logic stayed the same, I just updated the template.yaml and samconfig.toml to wrangler.toml and then scrapped the presigned URL in favor of a proxy route. The wrangler.toml was really similar to the samconfig.toml, and I didn't have to mess with settings for exposing the API or antyhing like that.
Took me less than an hour and now my site is back up and running.
Final thoughts
I'm pretty happy with how Cloudflare worked out. They get a bad rap for their UX, and that's somewhat deserved, but especially for smaller projects AWS is just massive overkill. Not worth it for a tiny side project to prove that I am allowed to put that keyword somewhere on my resume.