The tiny Vercel

@imarikchakma · Jul 31, 2024

Today I am going to share my experience of building a tiny version of Vercel. I have been using Vercel for a long time and I love the experience they provide.

One day Kamran told me about tiiny.host and I was amazed by the simplicity of it (Definitely give it a try). I decided to reverse engineer it and build my own version of it.

I was also exploring Rust at that time and I thought it would be a great opportunity to build something with Rust. I started to build the backend with Rust using Actix Web as the web framework.

You can try out a hosted site using this architecture here. Only the about and writings pages are deployed.

The Stack

I tried to keep the stack as simple as possible. Here is the stack I used:

The Architecture

In the beginning, I thought I will use the Rust backend as the reverse proxy. But it would be tough to scale the backend. So I decided to use CloudFront as the reverse proxy. I was using CloudFront functions instead of Lambda and CloudFront Key Value Store instead of DynamoDB to store the site metadata. But I was also facing some delay while serving the sites even after it was stored in S3. So I decided to use Lambda and DynamoDB.

Tiny Vercel Architecture

The architecture is simple, we have a REST API built with Actix Web. The API is responsible for handling the project files and metadata. The files are stored in S3 and the metadata is stored in DynamoDB. When a user uploads a project, the API stores the files in S3 and the metadata in DynamoDB. Either the user can choose a subdomain or the API will generate a subdomain for the project.

When a user requests to that subdomain, the CloudFront viewer request triggers a Lambda function. The Lambda function checks the subdomain from the request Host header and fetches the metadata from DynamoDB. If the metadata is found, it updates the request URI to the S3 file URL and forwards the request to the S3 bucket.

I used a trick to invalidate the cache for that File. I attach a Header called X-Nano-Cache-Key(which is just a mix of site_id=x=updated_timestamp) in the request. So, I can able to cache the files in CloudFront and invalidate the cache when the file is updated. I use Cache Policy for the cache settings.

So I was able to use CloudFront as the CDN and as a reverse proxy.

Conclusion

I was able to build a tiny version of Vercel with Rust and AWS. I learned a lot while building this. Here is the source code if you want to take a look.

There are a lot of room for improvement in the project. I will keep working on it and make it better. Please let me know if you have any suggestions or feedback. I would love to hear from you.