A serverless image resizing application built with AWS CDK (Cloud Development Kit) using Node.js. This project implements an event-driven architecture that automatically resizes images uploaded to S3 and provides a React-based frontend for uploading and viewing images.
This project is a recreation of the LocalStack sample application using a completely different technology stack.
Original Stack:
- AWS CLI scripts for deployment
- Terraform for Infrastructure as Code
- Python Lambda functions (using boto3 and Pillow)
- Simple HTML/JavaScript frontend (jQuery, Bootstrap, Handlebars.js)
- Function URLs for Lambda invocation
- SSM Parameter Store for configuration
This Recreation:
- AWS CDK for Infrastructure as Code (declarative, type-safe)
- JavaScript Lambda functions (using AWS SDK v3 and Sharp)
- Modern React 19 + Vite frontend
- API Gateway REST API for centralized routing
- CloudFront + S3 for frontend deployment
- Environment variables for configuration
While maintaining the same core functionality, this recreation demonstrates how the same serverless architecture can be implemented using modern development practices and a JavaScript-first approach.
The React-based frontend provides an intuitive interface for uploading and managing images:
The interface includes API configuration, file upload, and a gallery view showing both original and resized images with file size comparisons.
The application automatically resizes uploaded images to a maximum of 400x400 pixels while preserving aspect ratio:
Example: Original image (5184×3456) resized to (400×267), maintaining the aspect ratio.
This application uses a modern serverless architecture with the following components:
- Storage Layer: Two S3 buckets for original and resized images with CORS configuration
- Lambda Functions:
- Presign Function: Generates presigned POST URLs for secure direct uploads
- List Function: Lists and provides signed URLs for images in both buckets
- Resize Function: Automatically triggered on upload, resizes images to max 400x400px
- API Gateway: REST API endpoints with CORS support for frontend communication
- Notifications: SNS topic for error notifications via email (connected to DLQ)
- React 19 with Vite build tool
- File upload interface
- Side-by-side display of original and resized images
- Real-time upload progress tracking
- File size comparison
- Automatic Image Processing: Images are resized automatically when uploaded to S3
- Aspect Ratio Preservation: Resizes images to fit within 400x400px while maintaining proportions
- Secure Uploads: Uses presigned POST URLs for direct-to-S3 uploads
- Error Handling: Dead letter queue with SNS email notifications
- LocalStack Support: Built-in configuration for local development
- AWS Services: S3, Lambda, API Gateway, SNS, CloudFormation (via CDK)
- Infrastructure: AWS CDK 2.x with JavaScript
- Local Development: LocalStack with cdklocal for local AWS emulation
- Image Processing: Sharp library (0.34.4)
- Frontend: React 19, Vite
- AWS SDK: v3 (@aws-sdk/client-s3, s3-request-presigner, s3-presigned-post)
- Runtime: Node.js 22.x for Lambda functions
- Node.js 18.x or later
- AWS CLI configured with appropriate credentials
- AWS CDK CLI (
npm install -g aws-cdk) - LocalStack (optional, for local development) with
cdklocalCLI
- Clone the repository and install dependencies:
npm install- Build the Sharp layer for Lambda:
npm run layer-sharp- Set up environment variables (optional):
export AWS_STAGE=production # or 'local' for LocalStack
export RESIZE_ERROR_EMAIL=your-email@example.comcdk bootstrap # First time only
cdk deployThe deployment will output the API Gateway endpoint URL. Save this for frontend configuration.
For local development using LocalStack:
export AWS_STAGE=local
cdklocal bootstrap # First time only
cdklocal deployNote: Use cdklocal instead of cdk when deploying to LocalStack.
- Navigate to the frontend directory:
cd frontend
npm install-
Configure the API endpoint in the web interface or set it programmatically
-
Start the development server:
npm run devcdk deploy- Deploy the stack to your AWS account/regioncdk diff- Compare deployed stack with current statecdk synth- Emit the synthesized CloudFormation templatecdk destroy- Remove all resources from AWS
- User uploads an image via the React frontend
- Frontend requests a presigned POST URL from API Gateway
- Image is uploaded directly to S3 images bucket
- S3 event triggers the resize Lambda function
- Resize function downloads, processes (resizes to ≤400x400px), and uploads to resized bucket
- User can view both original and resized versions via the list endpoint
- Any errors during resize are sent to SNS topic for email notification
├── bin/ # CDK app entry point
├── lib/ # CDK stack and construct definitions
│ └── constructs/ # Reusable CDK constructs
├── lambda/ # Lambda function code
│ ├── presign/ # Presigned URL generator
│ ├── list/ # Image listing function
│ ├── resize/ # Image processing function
│ └── layers/ # Lambda layers (Sharp)
├── frontend/ # React web application
├── scripts/ # Build utilities
AWS_STAGE: Controls deployment environment (localfor LocalStack,productionfor AWS)RESIZE_ERROR_EMAIL: Email address for error notifications
- Resize function timeout: 30 seconds
- Resize function memory: 512MB
- Runtime: Node.js 22.x
- Uses presigned POST URLs for secure, direct-to-S3 uploads
- CORS configuration for web access
- IAM roles with least-privilege permissions
- Dead letter queue for failed processing
To remove all resources from AWS:
cdk destroyNote: S3 buckets are configured with DESTROY removal policy for easy cleanup during development.
This project is for educational purposes.

