Skip to main content
Technology & EngineeringStorage Services205 lines

Cloudinary

Build with Cloudinary for image and video management. Use this skill when the project needs to integrate Cloudinary for image upload, transformation, optimization, responsive images, video processing, or AI-powered media management. Covers the Cloudinary Node SDK, upload API, transformation URLs, and Next.js integration.

Quick Summary27 lines
You are a media specialist who integrates Cloudinary into projects. Cloudinary is
a cloud-based media management platform for image and video upload, transformation,
optimization, and delivery via CDN.

## Key Points

- Always use `f_auto,q_auto` for automatic format and quality optimization
- Use `gravity: 'auto'` for AI-based smart cropping
- Use upload presets for client-side uploads — restricts what can be uploaded
- Use `CldImage` in Next.js — it integrates with next/image optimization
- Use folders and tags to organize assets
- Set `crop: 'limit'` on upload to cap maximum dimensions
- Serving original unoptimized images — always apply `q_auto,f_auto`
- Generating transformation URLs client-side with API secret exposed
- Not using responsive sizes — serve different sizes for different viewports
- Uploading duplicate images — use `overwrite: true` or check `public_id`
- Storing Cloudinary URLs in the database — store `public_id` and generate URLs
- Not setting upload limits — allow arbitrarily large file uploads

## Quick Example

```bash
npm install cloudinary
npm install next-cloudinary  # For Next.js
```
skilldb get storage-services-skills/cloudinaryFull skill: 205 lines
Paste into your CLAUDE.md or agent config

Cloudinary Integration

You are a media specialist who integrates Cloudinary into projects. Cloudinary is a cloud-based media management platform for image and video upload, transformation, optimization, and delivery via CDN.

Core Philosophy

URL-based transformations

Cloudinary transforms images and videos through URL parameters — resize, crop, format-convert, add overlays, apply effects — all by modifying the delivery URL. No server-side image processing needed.

Automatic optimization

Cloudinary's f_auto and q_auto parameters automatically deliver the best format (WebP, AVIF) and quality for each browser. You don't manage format negotiation — Cloudinary handles it at the CDN edge.

Upload once, transform infinitely

Upload the original asset once. Generate any variation (thumbnail, hero, social card, video preview) on the fly via URL transformations. No need to pre-generate sizes.

Setup

Install

npm install cloudinary
npm install next-cloudinary  # For Next.js

Initialize

import { v2 as cloudinary } from 'cloudinary';

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_CLOUD_NAME!,
  api_key: process.env.CLOUDINARY_API_KEY!,
  api_secret: process.env.CLOUDINARY_API_SECRET!,
});

Key Techniques

Upload

// Server-side upload
const result = await cloudinary.uploader.upload(filePath, {
  folder: 'posts',
  public_id: 'my-image',
  transformation: [{ width: 2000, crop: 'limit' }], // Max 2000px wide on upload
  tags: ['blog', 'hero'],
});
// result.secure_url, result.public_id, result.width, result.height

// Upload from buffer
const result = await cloudinary.uploader.upload_stream(
  { folder: 'avatars', public_id: userId },
  (error, result) => { /* handle */ }
).end(buffer);

// Upload from URL
const result = await cloudinary.uploader.upload('https://example.com/photo.jpg', {
  folder: 'imports',
});

// Signed upload preset (client-side uploads)
const preset = await cloudinary.api.create_upload_preset({
  name: 'user_avatars',
  folder: 'avatars',
  allowed_formats: ['jpg', 'png', 'webp'],
  transformation: [{ width: 500, height: 500, crop: 'fill', gravity: 'face' }],
});

URL transformations

// Generate transformation URL
const url = cloudinary.url('posts/hero-image', {
  width: 800,
  height: 400,
  crop: 'fill',
  gravity: 'auto',       // AI-based smart crop
  quality: 'auto',       // Automatic quality
  fetch_format: 'auto',  // WebP/AVIF auto
});

// Thumbnail
const thumb = cloudinary.url('posts/hero-image', {
  width: 150,
  height: 150,
  crop: 'thumb',
  gravity: 'face',
});

// Text overlay
const social = cloudinary.url('posts/hero-image', {
  transformation: [
    { width: 1200, height: 630, crop: 'fill' },
    { overlay: { text: 'My Blog Post Title', font_family: 'Arial', font_size: 48 },
      gravity: 'south', y: 40, color: 'white' },
  ],
});

// Raw URL pattern
// https://res.cloudinary.com/{cloud}/image/upload/w_800,h_400,c_fill,g_auto,q_auto,f_auto/posts/hero-image

Next.js integration (next-cloudinary)

import { CldImage, CldUploadWidget } from 'next-cloudinary';

// Optimized image component
function HeroImage({ publicId }: { publicId: string }) {
  return (
    <CldImage
      src={publicId}
      width={1200}
      height={630}
      crop="fill"
      gravity="auto"
      alt="Hero image"
      sizes="100vw"
    />
  );
}

// Upload widget
function ImageUploader({ onUpload }: { onUpload: (url: string) => void }) {
  return (
    <CldUploadWidget
      uploadPreset="user_avatars"
      onSuccess={(result) => {
        if (typeof result.info !== 'string') {
          onUpload(result.info.secure_url);
        }
      }}
    >
      {({ open }) => <button onClick={() => open()}>Upload Image</button>}
    </CldUploadWidget>
  );
}

Video

// Video transformation
const videoUrl = cloudinary.url('videos/intro', {
  resource_type: 'video',
  width: 720,
  crop: 'scale',
  quality: 'auto',
  fetch_format: 'auto', // MP4/WebM auto
});

// Video thumbnail
const poster = cloudinary.url('videos/intro', {
  resource_type: 'video',
  format: 'jpg',
  transformation: [{ width: 1280, height: 720, crop: 'fill' }],
});

Delete and manage

// Delete
await cloudinary.uploader.destroy('posts/old-image');

// Rename
await cloudinary.uploader.rename('posts/old-name', 'posts/new-name');

// List resources
const { resources } = await cloudinary.api.resources({
  type: 'upload',
  prefix: 'posts/',
  max_results: 50,
});

Best Practices

  • Always use f_auto,q_auto for automatic format and quality optimization
  • Use gravity: 'auto' for AI-based smart cropping
  • Use upload presets for client-side uploads — restricts what can be uploaded
  • Use CldImage in Next.js — it integrates with next/image optimization
  • Use folders and tags to organize assets
  • Set crop: 'limit' on upload to cap maximum dimensions

Anti-Patterns

  • Serving original unoptimized images — always apply q_auto,f_auto
  • Generating transformation URLs client-side with API secret exposed
  • Not using responsive sizes — serve different sizes for different viewports
  • Uploading duplicate images — use overwrite: true or check public_id
  • Storing Cloudinary URLs in the database — store public_id and generate URLs
  • Not setting upload limits — allow arbitrarily large file uploads

Install this skill directly: skilldb add storage-services-skills

Get CLI access →

Related Skills

Imagekit

Build with ImageKit for real-time image optimization and delivery. Use this skill when the project needs to integrate ImageKit for image uploads, URL-based transformations, automatic format optimization, video optimization, or a Cloudinary alternative with simpler pricing. Covers the ImageKit SDK, URL transformations, upload API, and Next.js integration.

Storage Services166L

Tigris

Build with Tigris for globally distributed S3-compatible object storage. Use this skill when the project needs to integrate Tigris for file uploads, presigned URLs, automatic geo-replication, or edge-cached storage with zero egress fees. Covers the S3 API compatibility, Fly.io integration, and global caching patterns.

Storage Services168L

Uploadthing

Build with UploadThing for file uploads in Next.js and React. Use this skill when the project needs to integrate UploadThing for type-safe file uploads, presigned URLs, file validation, image/video uploads, or a developer-friendly upload service. Covers UploadThing route handlers, React components, file validation, and hooks.

Storage Services222L

Vercel Blob

Build with Vercel Blob for file storage in Next.js. Use this skill when the project needs to integrate Vercel Blob for file uploads, image storage, or serverless-friendly object storage on Vercel. Covers the Vercel Blob SDK, client uploads, server uploads, and file management.

Storage Services157L

AWS S3

Build with AWS S3 for object storage. Use this skill when the project needs to integrate Amazon S3 for file uploads, presigned URLs, static assets, backups, or CDN origin storage. Covers the AWS SDK v3, presigned URLs, multipart uploads, bucket policies, and CloudFront integration.

Storage Services204L

Backblaze B2

Build with Backblaze B2 for low-cost S3-compatible object storage. Use this skill when the project needs to integrate Backblaze B2 for file uploads, presigned URLs, lifecycle rules, or budget-friendly storage with Cloudflare CDN integration. Covers the S3-compatible API, native B2 API, and cost-optimization patterns.

Storage Services206L