Sankalp Rai Gambhir· Fullstack Software & AI Engineer
HomeProjectsInsightsSkillsBlogContactResume
Back to Projects

Vercel Clone: Serverless Deployment Platform

A production-grade, serverless platform for deploying frontend applications with automatic builds, preview deployments, and custom domains, inspired by Vercel.

GoAWS LambdaAPI GatewayDynamoDBS3SQSCloudFrontReactTypeScriptViteTailwind CSSTanStack QueryZustandshadcn/uiDocker
GitHubLive Demo
Vercel Clone: Serverless Deployment Platform
3 (API, Worker, Router)
Serverless Functions
5+
AWS Services
15+
API Endpoints
8+
Frontend Pages
Overview

Vercel Clone is a full-stack, serverless deployment platform built on AWS and Go for the backend, and React + TypeScript for the frontend. It enables users to create projects, trigger builds from GitHub, and deploy static sites with preview and production URLs. The backend leverages AWS Lambda, API Gateway, S3, DynamoDB, and SQS for scalable, event-driven workflows. The frontend provides a modern dashboard for managing projects, deployments, and build logs, with real-time status updates and a polished UI.

Timeline: 2.5 months
Role: Fullstack Software Engineer
Implementation Overview
  • ✓Serverless architecture with AWS Lambda, API Gateway, S3, DynamoDB, and SQS
  • ✓Automatic builds triggered by API or GitHub webhooks
  • ✓Preview deployments for every commit with unique URLs
  • ✓Production deployments and instant rollbacks
  • ✓Custom domain support and subdomain routing
  • ✓Real-time build log streaming via CloudWatch
  • ✓Modern React dashboard with project and deployment management
  • ✓Type-safe API integration with React Query and Zod
  • ✓Live status polling and optimistic UI updates
  • ✓Dockerized local development with DynamoDB and LocalStack

Technical Deep Dive

1
Problem

Coordinating asynchronous build jobs and status updates in a serverless environment

✓

Solution

Used SQS for reliable build job queuing and Lambda for scalable execution

</>

Implementation

SQS Build Job Enqueue (Backend)

// Enqueue a build job in SQS
func EnqueueBuildJob(job BuildJob) error {
  msg, err := json.Marshal(job)
  if err != nil {
    return err
  }
  _, err = sqsClient.SendMessage(context.TODO(), &sqs.SendMessageInput{
    QueueUrl: aws.String(queueURL),
    MessageBody: aws.String(string(msg)),
  })
  return err
}
Key Insight: This function serializes a build job and sends it to the SQS queue for asynchronous processing by the worker Lambda.
2
Problem

Efficiently streaming build logs from AWS CloudWatch to the frontend

✓

Solution

Implemented log polling endpoints and frontend polling for near real-time updates

</>

Implementation

React Query: Poll Build Status (Frontend)

const { data, refetch } = useQuery(['deployment', id], () => fetchDeployment(id), {
  refetchInterval: (data) => data?.status === 'building' ? 2000 : false,
});
Key Insight: This React Query hook polls the deployment status every 2 seconds while the build is in progress, providing real-time updates in the UI.
3
Problem

Ensuring atomic deployment state transitions and preventing race conditions

✓

Solution

Employed DynamoDB transactions and conditional updates for atomic state changes

</>

Implementation

DynamoDB Transaction for Deployment State

// Atomically update deployment status
_, err := dynamoClient.TransactWriteItems(context.TODO(), &dynamodb.TransactWriteItemsInput{
  TransactItems: []types.TransactWriteItem{
    {
      Update: &types.Update{
        TableName: aws.String(deploymentsTable),
        Key: map[string]types.AttributeValue{
          "id": &types.AttributeValueMemberS{Value: deploymentID},
        },
        UpdateExpression: aws.String("SET #status = :newStatus"),
        ExpressionAttributeNames: map[string]string{
          "#status": "status"
        },
        ExpressionAttributeValues: map[string]types.AttributeValue{
          ":newStatus": &types.AttributeValueMemberS{Value: newStatus},
        },
        ConditionExpression: aws.String("#status = :expected"),
        ExpressionAttributeValues: map[string]types.AttributeValue{
          ":expected": &types.AttributeValueMemberS{Value: expectedStatus},
        },
      },
    },
  },
})
Key Insight: This DynamoDB transaction ensures that deployment status updates are atomic and only occur if the current status matches the expected value, preventing race conditions.
4
Problem

Handling custom domain routing and SSL termination at scale

✓

Solution

Leveraged CloudFront and Lambda@Edge for dynamic subdomain and custom domain routing

View Full Repository