file-upload

Installation
SKILL.md

Wire file uploads using presigned URLs — client uploads directly to storage, your server never touches the bytes. Reads the project first, picks the right storage provider.

Four things that silently break file uploads

  1. CORS not configured on the bucket. The browser makes a direct PUT to R2/S3. Without CORS rules allowing your origin, every upload fails with a CORS error. Vercel Blob handles this automatically — R2 and S3 don't.
  2. MIME type validation on the client only. The accept attribute on <input> is cosmetic — users can bypass it. Always validate the MIME type server-side when generating the presigned URL, not just on the client.
  3. No file size check before generating the presigned URL. If you generate a presigned URL and then the user uploads a 500MB file, it succeeds. Set a ContentLengthRange condition on S3/R2 presigned URLs, or check Content-Length on the initial request.
  4. Storing the presigned URL path as the permanent file URL. Presigned URLs expire. Store the permanent public URL (or your own proxy route), not the presigned URL.

Phase 1: Detect the Project

cat package.json | grep -E "@vercel/blob|@aws-sdk|@cloudflare"
  • @vercel/blob → Vercel Blob (simplest for Vercel-hosted apps)
  • @aws-sdk/client-s3 → AWS S3
  • @cloudflare/workers-types or Wrangler → Cloudflare R2
  • None → ask the user (default: Vercel Blob if on Vercel)
Installs
40
GitHub Stars
8
First Seen
Jun 20, 2026
file-upload — tushaarmehtaa/tushar-skills