API Reference

API Overview

Complete guide to integrating compress.im compression capabilities into your applications. Learn about client-side processing, security, and implementation patterns.

compress.im Team
12 min read
Updated January 2025

API Overview

compress.im provides client-side compression capabilities through JavaScript APIs. All processing happens in the user's browser, ensuring privacy and reducing server load.

Privacy First
All compression happens locally in the user's browser. Files never leave the user's device, ensuring complete privacy and security.

Architecture Overview

Client-Side Processing

Our compression system runs entirely in the browser using modern web APIs:

  • Web Workers - Heavy compression tasks run in background threads
  • Canvas API - Image manipulation and format conversion
  • File API - Direct file handling without server uploads
  • Streams API - Memory-efficient processing of large files

Core Components

ComponentPurposeMain FeaturesUse Cases
ImageCompressionServiceImage processingFormat conversion, quality controlPhotos, graphics, web images
PDFCompressionServicePDF optimizationSize reduction, structure optimizationDocuments, reports, forms
BatchProcessorMultiple filesConcurrent processing, progress trackingBulk operations
PerformanceMonitorAnalyticsMetrics collection, optimizationPerformance analysis
FormatConverterFormat supportAdvanced format handlingAVIF, TIFF, BMP conversion

Getting Started

Basic Image Compression

import { ImageCompressionService } from '@/lib/imageCompression'

// Simple image compression
async function compressImage(file) {
  const options = {
    maxSizeMB: 1,      // Target file size
    quality: 0.8,      // Quality (0-1)
    maxWidthOrHeight: 1920,
    useWebWorker: true,
    preserveExif: false
  }
  
  try {
    const compressedFile = await ImageCompressionService.compressImage(
      file, 
      options,
      (progress) => console.log(`Progress: ${progress}%`)
    )
    
    console.log(`Original: ${file.size} bytes`)
    console.log(`Compressed: ${compressedFile.size} bytes`)
    console.log(`Reduction: ${((file.size - compressedFile.size) / file.size * 100).toFixed(1)}%`)
    
    return compressedFile
  } catch (error) {
    console.error('Compression failed:', error.message)
    throw error
  }
}

Basic PDF Compression

import { PDFCompressionService } from '@/lib/pdfCompression'

// Simple PDF compression
async function compressPDF(file) {
  const options = {
    mode: 'balanced',  // 'size', 'quality', or 'balanced'
    imageQuality: 0.8,
    removeMetadata: true
  }
  
  try {
    const compressedFile = await PDFCompressionService.compressPDF(
      file,
      options,
      (progress) => console.log(`Progress: ${progress}%`)
    )
    
    return compressedFile
  } catch (error) {
    console.error('PDF compression failed:', error.message)
    throw error
  }
}

Advanced Usage

Batch Processing

Process multiple files efficiently with progress tracking:

import { ImageCompressionService } from '@/lib/imageCompression'

async function processBatch(files) {
  const options = {
    quality: 0.8,
    maxSizeMB: 2,
    useWebWorker: true
  }
  
  // Convert files to compressed image objects
  const images = files.map(file => ({
    id: `img_${Date.now()}_${Math.random()}`,
    originalFile: file,
    originalSize: file.size,
    name: file.name
  }))
  
  // Process with callbacks
  await ImageCompressionService.processImagesBatch(
    images,
    options,
    // Progress callback for individual files
    (imageId, progress) => {
      console.log(`${imageId}: ${progress}%`)
      updateProgressUI(imageId, progress)
    },
    // Completion callback for individual files
    (imageId, result, error) => {
      if (error) {
        console.error(`${imageId} failed: ${error}`)
        handleError(imageId, error)
      } else {
        console.log(`${imageId} completed`)
        handleSuccess(imageId, result)
      }
    }
  )
}

Format Conversion

Convert between different image formats:

// Convert to WebP with fallback
const options = {
  format: 'webp',           // Target format
  quality: 0.85,
  enableAdvancedFormats: true,
  fallbackFormat: 'jpeg'    // Fallback if WebP fails
}

// The service will automatically handle format conversion
const webpFile = await ImageCompressionService.compressImage(file, options)

// Check if conversion was successful
if (webpFile.type === 'image/webp') {
  console.log('Successfully converted to WebP')
} else {
  console.log('Fell back to JPEG')
}

Error Handling

Common Error Types

try {
  const result = await ImageCompressionService.compressImage(file, options)
} catch (error) {
  switch (error.name) {
    case 'UnsupportedFormatError':
      // File format not supported for compression
      showError('Please use JPEG, PNG, or WebP files')
      break
      
    case 'FileSizeError':
      // File too large to process
      showError('File is too large. Please use files under 50MB')
      break
      
    case 'BrowserSupportError':
      // Browser doesn't support required features
      showError('Your browser doesn't support this feature')
      break
      
    case 'MemoryError':
      // Not enough memory to process file
      showError('Not enough memory. Try a smaller file or close other tabs')
      break
      
    default:
      // Generic compression error
      showError(`Compression failed: ${error.message}`)
  }
}

Robust Error Recovery

async function compressWithRetry(file, options, maxRetries = 3) {
  let lastError
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      // Adjust options for retry attempts
      const adjustedOptions = attempt > 1 
        ? { ...options, quality: Math.max(0.5, options.quality - 0.1 * attempt) }
        : options
      
      return await ImageCompressionService.compressImage(file, adjustedOptions)
      
    } catch (error) {
      lastError = error
      console.warn(`Attempt ${attempt} failed:`, error.message)
      
      // Don't retry certain errors
      if (error.name === 'UnsupportedFormatError' || 
          error.name === 'BrowserSupportError') {
        break
      }
      
      // Wait before retry
      if (attempt < maxRetries) {
        await new Promise(resolve => setTimeout(resolve, 1000 * attempt))
      }
    }
  }
  
  throw lastError
}

Performance Optimization

Memory Management

Memory Considerations
Large files can consume significant memory during processing. Monitor usage and implement appropriate limits.
import { PerformanceMonitor } from '@/lib/performanceMonitor'

// Check browser capabilities before processing
const capabilities = PerformanceMonitor.getBrowserCapabilities()

if (capabilities.estimatedMemoryGB < 2) {
  console.warn('Limited memory detected')
  // Reduce batch size or quality settings
}

// Get optimal settings for current batch
const optimalSettings = PerformanceMonitor.getOptimalSettings(
  fileCount, 
  averageFileSize
)

if (optimalSettings.memoryWarning) {
  showWarning(optimalSettings.memoryWarning)
}

// Use recommended settings
const batchOptions = {
  concurrency: optimalSettings.recommendedConcurrency,
  chunkSize: optimalSettings.recommendedChunkSize
}

Progress Tracking

class CompressionProgress {
  constructor() {
    this.files = new Map()
    this.overall = { completed: 0, total: 0, percentage: 0 }
  }
  
  updateFileProgress(fileId, progress) {
    this.files.set(fileId, progress)
    this.calculateOverallProgress()
    this.notifyListeners()
  }
  
  calculateOverallProgress() {
    const progresses = Array.from(this.files.values())
    const total = progresses.reduce((sum, p) => sum + p, 0)
    this.overall.percentage = progresses.length > 0 
      ? total / progresses.length 
      : 0
  }
  
  notifyListeners() {
    // Update UI with current progress
    document.dispatchEvent(new CustomEvent('compressionProgress', {
      detail: {
        files: Object.fromEntries(this.files),
        overall: this.overall
      }
    }))
  }
}

Security Considerations

File Validation

function validateFile(file) {
  // Size limits
  const MAX_SIZE = 100 * 1024 * 1024 // 100MB
  if (file.size > MAX_SIZE) {
    throw new Error('File too large')
  }
  
  // MIME type validation
  const allowedTypes = [
    'image/jpeg', 'image/png', 'image/webp', 'image/avif',
    'application/pdf'
  ]
  if (!allowedTypes.includes(file.type)) {
    throw new Error('Unsupported file type')
  }
  
  // Additional security checks
  return validateFileSignature(file)
}

async function validateFileSignature(file) {
  const buffer = await file.slice(0, 16).arrayBuffer()
  const signature = new Uint8Array(buffer)
  
  // Check file signatures match MIME types
  const signatures = {
    'image/jpeg': [0xFF, 0xD8, 0xFF],
    'image/png': [0x89, 0x50, 0x4E, 0x47],
    'application/pdf': [0x25, 0x50, 0x44, 0x46]
  }
  
  // Validate signature matches declared type
  // Implementation details...
  return true
}

Data Privacy

Client-Side Processing
All compression happens in browser, files never uploaded
No Data Collection
No file content or metadata is transmitted or stored
Memory Cleanup
Automatic cleanup of file objects and temporary data
Secure Contexts
Requires HTTPS for advanced features and security

Browser Compatibility

Feature Detection

function checkBrowserSupport() {
  const support = {
    webWorkers: typeof Worker !== 'undefined',
    canvas: typeof HTMLCanvasElement !== 'undefined',
    fileAPI: typeof File !== 'undefined' && typeof FileReader !== 'undefined',
    webp: checkWebPSupport(),
    avif: checkAVIFSupport(),
    streams: typeof ReadableStream !== 'undefined'
  }
  
  return support
}

async function checkWebPSupport() {
  return new Promise(resolve => {
    const canvas = document.createElement('canvas')
    canvas.width = 1
    canvas.height = 1
    const dataURL = canvas.toDataURL('image/webp')
    resolve(dataURL.indexOf('image/webp') === 5)
  })
}

// Use feature detection to adapt functionality
const browserSupport = checkBrowserSupport()
if (!browserSupport.webWorkers) {
  console.warn('Web Workers not supported, falling back to main thread')
}

Graceful Degradation

Progressive Enhancement
Design your application to work with basic compression features and enhance with advanced capabilities when available.

Integration Examples

React Hook

import { useState, useCallback } from 'react'
import { ImageCompressionService } from '@/lib/imageCompression'

export function useImageCompression() {
  const [isCompressing, setIsCompressing] = useState(false)
  const [progress, setProgress] = useState(0)
  const [error, setError] = useState(null)
  
  const compressImage = useCallback(async (file, options) => {
    setIsCompressing(true)
    setProgress(0)
    setError(null)
    
    try {
      const result = await ImageCompressionService.compressImage(
        file,
        options,
        setProgress
      )
      return result
    } catch (err) {
      setError(err.message)
      throw err
    } finally {
      setIsCompressing(false)
    }
  }, [])
  
  return {
    compressImage,
    isCompressing,
    progress,
    error
  }
}

Vue.js Composable

import { ref, computed } from 'vue'
import { ImageCompressionService } from '@/lib/imageCompression'

export function useCompression() {
  const files = ref([])
  const isProcessing = ref(false)
  const progress = ref(new Map())
  
  const overallProgress = computed(() => {
    if (progress.value.size === 0) return 0
    const total = Array.from(progress.value.values())
      .reduce((sum, p) => sum + p, 0)
    return total / progress.value.size
  })
  
  const addFile = (file) => {
    files.value.push(file)
  }
  
  const processAll = async () => {
    isProcessing.value = true
    // Implementation...
  }
  
  return {
    files,
    isProcessing,
    progress: overallProgress,
    addFile,
    processAll
  }
}

Next Steps

Now that you understand the basics, explore these advanced topics:

Ready to Build
You now have everything needed to integrate compression into your application. Start with simple use cases and gradually add advanced features.