compress-image-easy
v1.0.3
Published
A simple npm package to compress images (GIF, JPEG, PNG, etc.) in the browser
Maintainers
Readme
compress-image-easy
A simple npm package to compress images (GIF, JPEG, PNG, etc.) in the browser. Just pass a file and get a compressed image back.
Installation
npm install compress-image-easyUsage
Important: This package is designed for browser-only use. It requires browser APIs (Canvas, File API, Web Workers) and cannot be used in Node.js or during server-side rendering (SSR).
Basic Usage
import { compressImage } from "compress-image-easy";
// Get file from input
const file = event.target.files[0];
// Compress the image
const compressed = await compressImage(file);
if (compressed) {
console.log("Original size:", file.size);
console.log("Compressed size:", compressed.size);
// Use the compressed file
const url = URL.createObjectURL(compressed);
// ... use the URL
}With Options
import { compressImage } from "compress-image-easy";
const compressed = await compressImage(file, {
// GIF-specific options
gifQuality: 70, // Quality 0-100 (default: 70)
gifScale: 0.5, // Scale factor 0-1 (default: 0.5)
gifWorkers: 2, // Number of workers (default: 2)
gifFrameSkip: 2, // Skip frames for large GIFs (default: auto)
// Non-GIF options
maxSizeMB: 1, // Max size in MB (default: 1)
useWebWorker: true, // Use web worker (default: true)
});Setup for GIF Compression
For GIF compression to work, you need to make the gif.worker.js file available in your public directory.
Option 1: Copy the worker files manually
Copy node_modules/compress-image-easy/worker/gif.worker.js and node_modules/compress-image-easy/worker/gif.worker.js.map to your public folder, then specify the path:
Option 2: Use a bundler
If you're using a bundler (webpack, vite, etc.), you can import and configure it:
// In your build config or at runtime
import workerPath from "compress-image-easy/worker/gif.worker.js?url";
const compressed = await compressImage(file, {
workerScriptPath: workerPath,
});API
compressImage(file: File, options?: CompressOptions): Promise<File | null>
Compresses an image file.
Parameters:
file: The image file to compress (File object)options: Optional compression settings (see below)
Returns:
Promise<File | null>: The compressed file, ornullif compression fails
CompressOptions
interface CompressOptions {
gifQuality?: number; // 0-100, default: 70
gifScale?: number; // 0-1, default: 0.5
gifWorkers?: number; // default: 2
gifFrameSkip?: number; // default: auto (2 if >20 frames)
maxSizeMB?: number; // default: 1(would work for normal images, gif is based on frames so maxSize to be compressed cannot be specified)
useWebWorker?: boolean; // default: true
workerScriptPath?: string; // Path to gif.worker.js
}Supported Formats
- GIF (with frame optimization)
- JPEG/JPG
- PNG
- WebP
- Other browser-supported image formats
Using with Next.js or SSR Frameworks
If you're using Next.js or another SSR framework, you must use dynamic imports to avoid SSR issues:
Next.js Example (Recommended)
"use client"; // Important: Mark as client component
import { useState } from "react";
export default function ImageCompressor() {
const [compressed, setCompressed] = useState<File | null>(null);
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file) return;
// Dynamic import to avoid SSR issues
const { compressImage } = await import("compress-image-easy");
const result = await compressImage(file);
if (result) {
setCompressed(result);
}
};
return (
<div>
<input type="file" accept="image/*" onChange={handleFileChange} />
{compressed && <p>Compressed! Size: {compressed.size} bytes</p>}
</div>
);
}Alternative: Using useEffect
"use client";
import { useState, useEffect } from "react";
export default function ImageCompressor() {
const [compressImage, setCompressImage] = useState<any>(null);
const [compressed, setCompressed] = useState<File | null>(null);
useEffect(() => {
// Load the module only in browser
import("compress-image-easy").then((module) => {
setCompressImage(() => module.compressImage);
});
}, []);
const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file || !compressImage) return;
const result = await compressImage(file, {
workerScriptPath: "/gif.worker.js",
});
if (result) {
setCompressed(result);
}
};
return (
<div>
<input type="file" accept="image/*" onChange={handleFileChange} />
{compressed && <p>Compressed! Size: {compressed.size} bytes</p>}
</div>
);
}React (with useEffect)
import { useEffect, useState } from "react";
import { compressImage } from "compress-image-easy";
function MyComponent() {
const [compressed, setCompressed] = useState<File | null>(null);
useEffect(() => {
// Ensure we're in browser before using
if (typeof window === "undefined") return;
// Your compression logic here
}, []);
// ... rest of component
}Browser Support
This package requires browser APIs (Canvas, File API, Web Workers). It works in all modern browsers that support these APIs.
Note: This package cannot be used in Node.js environments or during server-side rendering. It will return null if called in a non-browser environment.
License
MIT
