A comprehensive, high-performance asset transformation server supporting real-time processing of images, videos, audio, documents, fonts, icons, and more. Built with NestJS and Fastify for maximum throughput.
- Multi-Resource Support: Transform images, videos, audio, documents, fonts, icons, Lottie animations, markdown, spreadsheets, and 3D models
- Real-time Processing: On-the-fly transformation with URL-based parameters
- Intelligent Streaming: Automatic buffering/streaming selection based on file size
- Memory Efficient: Optimized for large files (tested with 700MB+ PDFs)
- AWS S3 Integration: Seamless integration with S3 for asset storage
- CloudFront Compatible: Designed for CDN deployment with proper cache headers
- Type-safe: Full TypeScript support with comprehensive type definitions
- Installation
- Quick Start
- Configuration
- API Endpoints
- Transform Parameters
- Architecture
- Development
- Deployment
- License
- Node.js >= 22.10.0
- pnpm >= 10.12.4
- AWS S3 bucket configured
# Clone the repository
git clone https://github.com/your-org/asset-transform.git
cd asset-transform
# Install dependencies
pnpm install
# Copy environment configuration
cp .env.example .env
# Edit .env with your AWS credentials# Development mode
pnpm dev
# Production build
pnpm build
# Production start
pnpm startThe server will start on http://localhost:3000.
curl http://localhost:3000/healthCreate a .env file with the following variables:
# Required
NODE_ENV=development
ENVIRONMENT=development
# AWS S3 Configuration
AWS_CREDENTIAL_ACCESS_KEY=your-access-key
AWS_CREDENTIAL_SECRET_ACCESS_KEY=your-secret-key
AWS_S3_BUCKET=your-bucket-name
AWS_S3_REGION=ap-northeast-2
AWS_ACCOUNT_ID=123456789012
AWS_CF_CDN_DISTRIBUTION_ID=E1234567890ABC
# Optional: Sentry Error Tracking
# SENTRY_DSN=https://xxx@sentry.io/xxx
# SENTRY_AUTH_TOKEN=sntrys_xxx
# SENTRY_RELEASE=v1.0.0All endpoints follow the pattern: GET /cdn/v1/{resourceType}/{filePath}
| Resource Type | Endpoint | Description |
|---|---|---|
| Image | /cdn/v1/image/* |
Image transformation (resize, format, quality) |
| Video | /cdn/v1/video/* |
Video processing and thumbnails |
| Audio | /cdn/v1/audio/* |
Audio processing |
| Document | /cdn/v1/document/* |
PDF processing, page extraction |
| Font | /cdn/v1/font/* |
Font subsetting and conversion |
| Icon | /cdn/v1/icon/* |
SVG optimization, color/size changes |
| Lottie | /cdn/v1/lottie/* |
Lottie animation processing |
| Markdown | /cdn/v1/markdown/* |
Markdown to HTML conversion |
| Spreadsheet | /cdn/v1/spreadsheet/* |
Excel/CSV processing |
| Model | /cdn/v1/model/* |
3D model optimization (GLTF/GLB) |
The server supports automatic resource type detection based on file extension:
# These are equivalent:
GET /cdn/v1/image/photos/image.jpg
GET /cdn/v1/photos/image.jpg # Auto-detected as image
Transform images using query parameters:
GET /cdn/v1/image/photo.jpg?transform=w:800,h:600,q:80,f:webp
| Parameter | Description | Example |
|---|---|---|
w |
Width | w:800 |
h |
Height | h:600 |
q |
Quality (1-100) | q:80 |
f |
Format (webp, avif, jpeg, png) | f:webp |
fit |
Fit mode (cover, contain, fill, inside, outside) | fit:cover |
blur |
Blur sigma | blur:5 |
sharpen |
Sharpen | sharpen:true |
grayscale |
Grayscale | grayscale:true |
rotate |
Rotation degrees | rotate:90 |
flip |
Flip vertically | flip:true |
flop |
Flip horizontally | flop:true |
GET /cdn/v1/document/report.pdf?transform=page:1,format:png
| Parameter | Description | Example |
|---|---|---|
page |
Page number | page:1 |
format |
Output format (png, jpeg) | format:png |
scale |
Scale factor | scale:2 |
GET /cdn/v1/font/custom.ttf?transform=subset:Hello World,format:woff2
| Parameter | Description | Example |
|---|---|---|
subset |
Characters to include | subset:ABC123 |
format |
Output format (woff, woff2) | format:woff2 |
GET /cdn/v1/icon/logo.svg?transform=color:ff0000,w:64,h:64
| Parameter | Description | Example |
|---|---|---|
color |
Fill color (hex) | color:ff0000 |
w |
Width | w:64 |
h |
Height | h:64 |
src/
├── app.module.ts # Main application module
├── main.ts # Application entry point
├── instrument.ts # Sentry instrumentation (optional)
│
├── cdn/ # CDN resource modules
│ ├── base/ # Base CDN service
│ ├── image/ # Image processing
│ ├── video/ # Video processing
│ ├── audio/ # Audio processing
│ ├── document/ # Document processing
│ ├── font/ # Font processing
│ ├── icon/ # Icon processing
│ ├── lottie/ # Lottie processing
│ ├── markdown/ # Markdown processing
│ ├── spreadsheet/ # Spreadsheet processing
│ ├── model/ # 3D model processing
│ └── unknown/ # Unknown file type handling
│
├── common/ # Shared utilities
│ ├── interfaces/ # TypeScript interfaces
│ ├── responses/ # Response builders
│ ├── services/ # Common services
│ ├── strategies/ # Processing strategies
│ ├── types/ # Type definitions
│ └── utils/ # Utility functions
│
├── health/ # Health check module
├── infrastructure/ # AWS services (S3, CloudFront)
└── logger/ # Logging configuration
The server uses intelligent processing strategies based on file characteristics:
| Strategy | Use Case | Description |
|---|---|---|
| Buffering | Small files with transforms | Full file in memory |
| Streaming | Large files without transforms | Memory-efficient streaming |
| Redirect | Very large files | Redirect to S3 presigned URL |
| Resource Type | Streaming Threshold | Redirect Threshold |
|---|---|---|
| Image | 50 MB | 100 MB |
| Document | 30 MB | 100 MB |
| Video | 100 MB | 500 MB |
| Audio | 50 MB | 200 MB |
# Run in development mode with hot reload
pnpm dev
# Run tests
pnpm test
# Run tests with coverage
pnpm test:cov
# Run tests with UI
pnpm test:ui
# Type checking
pnpm check-types
# Linting
pnpm lint
# Format code
pnpm format# Build image
docker build -t asset-transform .
# Run container
docker run -p 3000:3000 --env-file .env asset-transformdocker compose up -d# Start with PM2
pm2 start ecosystem.config.js
# View logs
pm2 logs asset-transformFor optimal CDN performance, configure CloudFront with:
- Origin: Point to your server
- Cache Behaviors: Configure per resource type
- TTL Settings:
- Images: 1 year (31536000s)
- Videos/Audio: 6 months (15552000s)
- Documents: 1 month (2592000s)
- Fonts/Icons: 1 year (31536000s)
Tested on standard cloud infrastructure:
| Metric | Value |
|---|---|
| TTFB (small files) | < 50ms |
| TTFB (large files) | < 1s |
| Memory (700MB PDF) | ~10MB |
| Concurrent requests | 1000+ |
- Automatic garbage collection optimization
- Streaming for large files
- Request-scoped resource cleanup
The server provides detailed error responses:
{
"statusCode": 400,
"message": "Invalid transform parameter",
"error": "Bad Request",
"details": {
"parameter": "width",
"value": "invalid",
"expected": "number"
}
}Enable error tracking by setting SENTRY_DSN environment variable.
GET /health- Basic health checkGET /health/ready- Readiness probeGET /health/live- Liveness probe
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.