npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@api-buddy/cloudinary

v3.0.0

Published

API Buddy integration for Cloudinary - Cloud-based image and video management

Downloads

13

Readme

@api-buddy/cloudinary

npm version License: MIT

A comprehensive Cloudinary integration for Next.js applications, providing a simple and type-safe way to upload, transform, and deliver images and videos.

Features

  • 🚀 Easy Setup: Get started quickly with a few simple steps
  • 🔒 Type-Safe: Full TypeScript support for all Cloudinary options and responses
  • Performance Optimized: Automatic image optimization and responsive images
  • 🎣 React Hooks: Custom hooks for easy file uploads and media management
  • 🖼️ Components: Pre-built React components for images and videos
  • 🛠 CLI Tool: Quick project setup with the included CLI
  • 🔄 Server & Client Support: Works with both server components and client components
  • 📱 Responsive Images: Automatic srcset generation for responsive images
  • 🎥 Video Support: Upload, transform, and deliver videos with ease

Installation

# Using npm
npm install @api-buddy/cloudinary cloudinary

# Using yarn
yarn add @api-buddy/cloudinary cloudinary

# Using pnpm
pnpm add @api-buddy/cloudinary cloudinary

If you're using TypeScript, you'll also want to install the Cloudinary types:

npm install --save-dev @types/cloudinary

Quick Start

1. Set Up Environment Variables

Create a .env.local file in your project root and add your Cloudinary credentials:

NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name
NEXT_PUBLIC_CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET=your_upload_preset

2. Set Up the Cloudinary Provider

Wrap your application with the CloudinaryProvider in your root layout:

// app/layout.tsx
'use client';

import { CloudinaryProvider } from '@api-buddy/cloudinary';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <CloudinaryProvider 
          config={{
            // Optional: Configure default settings here
            cloudName: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
            apiKey: process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY,
            apiSecret: process.env.CLOUDINARY_API_SECRET,
            uploadPreset: process.env.NEXT_PUBLIC_CLOUDINARY_UPLOAD_PRESET,
          }}
        >
          {children}
        </CloudinaryProvider>
      </body>
    </html>
  );
}

3. Upload Files

Create an API route to handle file uploads:

// app/api/upload/route.ts
import { NextResponse } from 'next/server';
import { upload } from '@api-buddy/cloudinary';

export async function POST(request: Request) {
  try {
    const formData = await request.formData();
    const file = formData.get('file') as File;
    
    if (!file) {
      return NextResponse.json(
        { success: false, error: 'No file provided' },
        { status: 400 }
      );
    }

    // Convert the file to a buffer
    const buffer = Buffer.from(await file.arrayBuffer());
    
    // Upload to Cloudinary
    const result = await upload(buffer, {
      folder: 'uploads',
      resourceType: 'auto',
      public_id: file.name.replace(/\.[^/.]+$/, ''), // Remove file extension
      filename_override: file.name,
      context: {
        filename: file.name,
        format: file.type,
        size: file.size,
      },
    });

    return NextResponse.json({ success: true, data: result });
  } catch (error) {
    console.error('Upload error:', error);
    return NextResponse.json(
      { success: false, error: 'Failed to upload file' },
      { status: 500 }
    );
  }
}

4. Use the useCloudinaryUpload Hook

'use client';

import { useCloudinaryUpload } from '@api-buddy/cloudinary';

export default function UploadForm() {
  const { uploadFile, isUploading, progress, error } = useCloudinaryUpload({
    options: {
      folder: 'images',
      resourceType: 'image',
    },
    onSuccess: (result) => {
      console.log('Upload successful:', result);
    },
    onError: (error) => {
      console.error('Upload error:', error);
    },
  });

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      await uploadFile(file);
    }
  };

  return (
    <div className="p-6 max-w-md mx-auto bg-white rounded-xl shadow-md">
      <h2 className="text-xl font-semibold mb-4">Upload an Image</h2>
      
      <div className="mb-4">
        <input
          type="file"
          accept="image/*"
          onChange={handleFileChange}
          disabled={isUploading}
          className="block w-full text-sm text-gray-500
            file:mr-4 file:py-2 file:px-4
            file:rounded-md file:border-0
            file:text-sm file:font-semibold
            file:bg-blue-50 file:text-blue-700
            hover:file:bg-blue-100"
        />
      </div>

      {isUploading && (
        <div className="w-full bg-gray-200 rounded-full h-2.5">
          <div
            className="bg-blue-600 h-2.5 rounded-full"
            style={{ width: `${progress}%` }}
          ></div>
          <p className="text-sm text-gray-600 mt-1">Uploading: {progress}%</p>
        </div>
      )}

      {error && (
        <div className="mt-4 p-3 bg-red-100 text-red-700 rounded-md">
          Error: {error.message}
        </div>
      )}
    </div>
  );
}

5. Display Images

import { CloudinaryImage } from '@api-buddy/cloudinary';

export default function ProfileImage({ publicId }: { publicId: string }) {
  return (
    <div className="w-32 h-32 rounded-full overflow-hidden">
      <CloudinaryImage
        publicId={publicId}
        alt="Profile image"
        width={128}
        height={128}
        className="w-full h-full object-cover"
        transformation={[
          { width: 256, height: 256, crop: 'thumb', gravity: 'face' },
          { radius: 'max' },
        ]}
      />
    </div>
  );
}

CLI Setup

For a quick setup, use the included CLI:

npx @api-buddy/cloudinary setup

This will:

  1. Install required dependencies
  2. Set up environment variables
  3. Create example components and API routes
  4. Configure your Next.js app to use Cloudinary

API Reference

CloudinaryProvider

A context provider that makes the Cloudinary client available throughout your application.

Props

  • config: Configuration object
    • cloudName: Your Cloudinary cloud name (required)
    • apiKey: Your Cloudinary API key (optional, defaults to process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY)
    • apiSecret: Your Cloudinary API secret (optional, defaults to process.env.CLOUDINARY_API_SECRET)
    • uploadPreset: Your Cloudinary upload preset (optional)
    • defaultUploadOptions: Default options for all uploads

useCloudinary()

A hook to access the Cloudinary client from the nearest CloudinaryProvider.

Returns

  • client: The Cloudinary client instance
  • config: The current Cloudinary configuration

useCloudinaryUpload(options)

A hook for handling file uploads to Cloudinary.

Parameters

  • options: Upload options
    • options: Default upload options for all uploads
    • onSuccess: Callback when an upload succeeds
    • onError: Callback when an upload fails
    • onProgress: Callback with upload progress (0-100)

Returns

  • uploadFile: Function to upload a single file
  • uploadFiles: Function to upload multiple files
  • isUploading: Boolean indicating if an upload is in progress
  • progress: Current upload progress (0-100)
  • error: Error object if an upload failed
  • reset: Function to reset the hook state

CloudinaryImage

A React component for displaying Cloudinary images with automatic optimization.

Props

  • publicId: The public ID of the image (required)
  • alt: Alternative text for the image (required)
  • width: Width of the image
  • height: Height of the image
  • className: CSS class name
  • style: Inline styles
  • loading: Loading behavior (lazy or eager)
  • transformation: Array of Cloudinary transformations
  • format: Image format to convert to
  • quality: Image quality (1-100)
  • responsive: Whether to generate responsive images
  • sizes: Sizes attribute for responsive images
  • srcSet: Custom srcset for responsive images
  • onLoad: Callback when the image loads
  • onError: Callback when the image fails to load

CloudinaryVideo

A React component for displaying Cloudinary videos.

Props

  • publicId: The public ID of the video (required)
  • width: Width of the video player
  • height: Height of the video player
  • className: CSS class name
  • style: Inline styles
  • autoPlay: Whether to autoplay the video
  • loop: Whether to loop the video
  • muted: Whether to mute the video
  • controls: Whether to show video controls
  • poster: URL of the poster image
  • transformation: Array of Cloudinary transformations
  • onPlay: Callback when the video starts playing
  • onPause: Callback when the video is paused
  • onEnded: Callback when the video ends
  • onError: Callback when the video fails to load

upload(file, options)

Upload a file to Cloudinary.

Parameters

Returns

A promise that resolves to the upload result.

deleteFile(publicId, options)

Delete a file from Cloudinary.

Parameters

  • publicId: The public ID of the file to delete
  • options: Delete options
    • resourceType: Type of resource (image, video, raw, or auto)
    • type: The type of the resource
    • invalidate: Whether to invalidate the CDN cache

Returns

A promise that resolves to the delete result.

getUrl(publicId, options)

Generate a URL for a Cloudinary resource.

Parameters

  • publicId: The public ID of the resource
  • options: URL and transformation options
    • transformation: Array of Cloudinary transformations
    • resourceType: Type of resource (image, video, raw, or auto)
    • type: The type of the resource
    • format: Format to convert the resource to
    • secure: Whether to use HTTPS
    • signUrl: Whether to sign the URL
    • version: The version of the resource

Returns

The generated URL as a string.

Examples

Uploading a File

import { upload } from '@api-buddy/cloudinary';

// In an API route or server component
const file = // your file buffer or stream
const result = await upload(file, {
  folder: 'uploads',
  resourceType: 'auto',
  public_id: 'my-file',
});

console.log('File uploaded:', result.url);

Using Transformations

import { CloudinaryImage } from '@api-buddy/cloudinary';

function ProductImage({ publicId }: { publicId: string }) {
  return (
    <CloudinaryImage
      publicId={publicId}
      alt="Product image"
      width={400}
      height={400}
      transformation={[
        { width: 800, height: 800, crop: 'fill' },
        { effect: 'sharpen' },
        { quality: 'auto' },
      ]}
    />
  );
}

Responsive Images

import { CloudinaryImage } from '@api-buddy/cloudinary';

function HeroImage({ publicId }: { publicId: string }) {
  return (
    <CloudinaryImage
      publicId={publicId}
      alt="Hero image"
      width={1200}
      height={630}
      className="w-full h-auto"
      responsive
      sizes="(max-width: 768px) 100vw, 50vw"
      transformation={[
        { width: 1200, height: 630, crop: 'fill' },
        { quality: 'auto' },
      ]}
    />
  );
}

Error Handling

All functions throw a CloudinaryError when something goes wrong. You can catch and handle these errors:

try {
  await upload(file, options);
} catch (error) {
  if (error.name === 'CloudinaryError') {
    console.error('Cloudinary error:', error.message);
    // Handle specific error cases
    if (error.code === 'LIMIT_FILE_SIZE') {
      // Handle file size limit exceeded
    } else if (error.code === 'UNAUTHORIZED') {
      // Handle authentication error
    } else {
      // Handle other errors
    }
  } else {
    // Handle non-Cloudinary errors
    console.error('Unexpected error:', error);
  }
}

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

MIT

Acknowledgments