Node.js client for the Tinify API that intelligently compresses, resizes, converts, and stores images in AVIF, WebP, JPEG, and PNG formats.
—
Direct upload integration with Amazon S3, Google Cloud Storage, and other S3-compatible services for seamless cloud storage of processed images.
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;
}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()
};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()
};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"
});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}`);
}
});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);Cloud storage operations can throw the following errors:
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