| name | file-upload |
| description | File upload patterns including multipart/form-data, presigned URLs for S3/R2, chunked uploads, progress tracking, drag-and-drop with react-dropzone, and client-side validation |
| layer | utility |
| category | backend |
| triggers | ["file upload","upload file","presigned URL","multipart","drag and drop upload","image upload","S3 upload","R2 upload","chunked upload","react-dropzone"] |
| inputs | ["Storage target (S3, R2, local filesystem, Supabase Storage)","File types and size limits","Upload method (direct, presigned URL, chunked)","Frontend framework (React, vanilla JS)"] |
| outputs | ["Upload endpoint implementation","Presigned URL generation","Client-side upload component with progress","Validation and security checks"] |
| linksTo | ["aws","cloudflare","nextjs","forms"] |
| linkedFrom | ["api-designer","media-processing"] |
| preferredNextSkills | ["media-processing","caching"] |
| fallbackSkills | ["aws","nodejs"] |
| riskLevel | medium |
| memoryReadPolicy | selective |
| memoryWritePolicy | none |
| sideEffects | ["Creates files in storage bucket","May add AWS SDK or S3 client dependencies"] |
File Upload Patterns Skill
Purpose
Implement secure, efficient file uploads from client to server or directly to cloud storage. Covers validation, progress tracking, presigned URLs for large files, and drag-and-drop UX.
Upload Strategy Decision
| Method | Max Size | Complexity | Best For |
|---|
| multipart/form-data | ~10MB | Low | Simple forms, small files |
| Presigned URL (S3/R2) | 5GB | Medium | Large files, serverless |
| Chunked/Resumable | Unlimited | High | Video, unreliable networks |
| Base64 in JSON | ~1MB | Low | Avatars, thumbnails only |
Key Patterns
1. Server-Side: Presigned URL Generation
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { randomUUID } from 'crypto';
const s3 = new S3Client({
region: process.env.AWS_REGION!,
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
const = [, , , ];
= * * ;
() {
{ filename, contentType, size } = req.();
(!.(contentType)) {
.({ : }, { : });
}
(size > ) {
.({ : }, { : });
}
key = ;
url = (
s3,
({
: process..!,
: key,
: contentType,
: size,
}),
{ : }
);
.({ url, key });
}