CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tinify

Node.js client for the Tinify API that intelligently compresses, resizes, converts, and stores images in AVIF, WebP, JPEG, and PNG formats.

Pending
Overview
Eval results
Files

cloud-storage.mddocs/

Cloud Storage Integration

Direct upload integration with Amazon S3, Google Cloud Storage, and other S3-compatible services for seamless cloud storage of processed images.

Capabilities

Store to Cloud Storage

Upload processed images directly to cloud storage services without downloading them locally first.

/**
 * Store processed image to cloud storage
 * @param options - Cloud storage configuration
 * @returns ResultMeta instance for accessing storage metadata
 */
store(options: StoreOptions): ResultMeta;

interface StoreOptions {
  /** Storage service type */
  service: "s3" | "gcs";
  /** AWS access key ID (required for S3) */
  aws_access_key_id?: string;
  /** AWS secret access key (required for S3) */
  aws_secret_access_key?: string;
  /** AWS region (optional, defaults to us-east-1) */
  region?: string;
  /** Storage path including bucket/container and object key */
  path: string;
  /** Additional service-specific headers and options */
  [key: string]: any;
}

Amazon S3 Storage

Store images directly to Amazon S3 buckets with full authentication and region support.

Usage Examples:

const tinify = require("tinify");

tinify.key = "your-api-key";

// Basic S3 storage
const resultMeta = tinify.fromFile("large-image.jpg")
  .resize({ method: "fit", width: 1200 })
  .store({
    service: "s3",
    aws_access_key_id: "AKIAIOSFODNN7EXAMPLE",
    aws_secret_access_key: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
    region: "us-west-2",
    path: "my-images-bucket/processed/optimized-image.jpg"
  });

// Get storage location
const location = await resultMeta.location();
console.log(`Image stored at: ${location}`);

// With additional S3 headers
const resultMeta2 = tinify.fromFile("photo.png")
  .convert({ type: "image/webp" })
  .store({
    service: "s3",
    aws_access_key_id: "ACCESS_KEY",
    aws_secret_access_key: "SECRET_KEY",
    region: "eu-west-1",
    path: "photos-bucket/webp/photo.webp",
    // Additional S3-specific headers
    "x-amz-acl": "public-read",
    "x-amz-meta-title": "Optimized Photo",
    "cache-control": "max-age=31536000"
  });

// Complex transformation with S3 storage
const transformedResult = tinify.fromUrl("https://example.com/original.png")
  .resize({ method: "cover", width: 800, height: 600 })
  .preserve("copyright")
  .convert({ type: "image/webp" })
  .store({
    service: "s3",
    aws_access_key_id: "ACCESS_KEY", 
    aws_secret_access_key: "SECRET_KEY",
    region: "us-east-1",
    path: "processed-images/thumbnails/image-800x600.webp"
  });

const dimensions = {
  width: await transformedResult.width(),
  height: await transformedResult.height()
};

Google Cloud Storage

Store images to Google Cloud Storage buckets.

Usage Examples:

const tinify = require("tinify");

tinify.key = "your-api-key";

// Google Cloud Storage
const resultMeta = tinify.fromFile("image.jpg")
  .resize({ method: "fit", width: 1000 })
  .store({
    service: "gcs",
    // GCS authentication and configuration
    path: "my-gcs-bucket/images/processed-image.jpg"
    // Additional GCS-specific options as needed
  });

const location = await resultMeta.location();
const dimensions = {
  width: await resultMeta.width(),
  height: await resultMeta.height()
};

S3-Compatible Services

The S3 service option works with other S3-compatible storage services by specifying custom endpoints and regions.

Usage Example:

const tinify = require("tinify");

tinify.key = "your-api-key";

// Custom S3-compatible service (e.g., DigitalOcean Spaces, MinIO)
const resultMeta = tinify.fromFile("document.png")
  .resize({ method: "fit", width: 800 })
  .store({
    service: "s3",
    aws_access_key_id: "CUSTOM_ACCESS_KEY",
    aws_secret_access_key: "CUSTOM_SECRET_KEY",
    region: "custom-region",
    path: "my-space/documents/processed-document.png",
    // Custom endpoint for S3-compatible services
    "x-amz-endpoint": "https://custom-endpoint.example.com"
  });

Storage Metadata

Access metadata about stored images including dimensions and storage location.

class ResultMeta {
  /** Get stored image width in pixels */
  width(): Promise<number>;
  width(callback: (err: Error | null, width?: number) => void): void;
  
  /** Get stored image height in pixels */
  height(): Promise<number>;
  height(callback: (err: Error | null, height?: number) => void): void;
  
  /** Get storage location URL */
  location(): Promise<string>;
  location(callback: (err: Error | null, location?: string) => void): void;
}

Usage Example:

const tinify = require("tinify");

tinify.key = "your-api-key";

const resultMeta = tinify.fromFile("photo.jpg")
  .resize({ method: "cover", width: 500, height: 500 })
  .store({
    service: "s3",
    aws_access_key_id: "ACCESS_KEY",
    aws_secret_access_key: "SECRET_KEY", 
    region: "us-west-1",
    path: "thumbnails/profile-photo.jpg"
  });

// Promise-based metadata access
const metadata = {
  width: await resultMeta.width(),
  height: await resultMeta.height(),
  location: await resultMeta.location()
};

console.log(`Stored image: ${metadata.width}×${metadata.height} at ${metadata.location}`);

// Callback-based metadata access
resultMeta.location((err, location) => {
  if (err) {
    console.error("Failed to get location:", err.message);
  } else {
    console.log(`Image available at: ${location}`);
  }
});

Batch Storage Operations

Store multiple processed variations of the same image to different storage locations.

Usage Example:

const tinify = require("tinify");

tinify.key = "your-api-key";

const baseSource = tinify.fromFile("high-res-photo.jpg");

// Store multiple sizes
const thumbnailMeta = baseSource
  .resize({ method: "cover", width: 200, height: 200 })
  .store({
    service: "s3",
    aws_access_key_id: "ACCESS_KEY",
    aws_secret_access_key: "SECRET_KEY",
    region: "us-west-2", 
    path: "images/thumbnails/photo-200x200.jpg"
  });

const mediumMeta = baseSource
  .resize({ method: "fit", width: 800 })
  .store({
    service: "s3",
    aws_access_key_id: "ACCESS_KEY",
    aws_secret_access_key: "SECRET_KEY",
    region: "us-west-2",
    path: "images/medium/photo-800w.jpg"
  });

const webpMeta = baseSource
  .resize({ method: "fit", width: 1200 })
  .convert({ type: "image/webp" })
  .store({
    service: "s3",
    aws_access_key_id: "ACCESS_KEY",
    aws_secret_access_key: "SECRET_KEY",
    region: "us-west-2",
    path: "images/webp/photo-1200w.webp"
  });

// Get all storage locations
const locations = {
  thumbnail: await thumbnailMeta.location(),
  medium: await mediumMeta.location(), 
  webp: await webpMeta.location()
};

console.log("All variations stored:", locations);

Error Handling

Cloud storage operations can throw the following errors:

  • ClientError: Invalid storage configuration, authentication failure, or permission issues
  • AccountError: Tinify API key issues or monthly limit exceeded
  • ConnectionError: Network connectivity problems
  • ServerError: Temporary issues with storage services or Tinify API

Error Handling Example:

const tinify = require("tinify");

tinify.key = "your-api-key";

try {
  const resultMeta = tinify.fromFile("image.jpg")
    .resize({ method: "fit", width: 1000 })
    .store({
      service: "s3",
      aws_access_key_id: "ACCESS_KEY",
      aws_secret_access_key: "SECRET_KEY",
      region: "us-west-1",
      path: "my-bucket/processed/image.jpg"
    });
    
  const location = await resultMeta.location();
  console.log(`Successfully stored at: ${location}`);
  
} catch (error) {
  if (error instanceof tinify.ClientError) {
    if (error.status === 403) {
      console.error("S3 permission denied:", error.message);
    } else if (error.status === 400) {
      console.error("Invalid S3 configuration:", error.message);
    } else {
      console.error("Storage error:", error.message);
    }
  } else if (error instanceof tinify.AccountError) {
    console.error("Tinify account issue:", error.message);
  } else if (error instanceof tinify.ConnectionError) {
    console.error("Network error:", error.message);
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-tinify

docs

cloud-storage.md

configuration.md

error-handling.md

image-sources.md

index.md

results.md

transformations.md

tile.json