File-to-file processing
Pass a browser File to the optimizer and receive a browser File back that can be used directly by an existing upload pipeline.
A framework-independent and fully typed image optimization library for browser uploads. Resize, compress and convert images locally before they reach your upload pipeline.
Built around browser File objects, Web Workers and WebAssembly, with support for mixed-file batches, controlled concurrency, target-size optimization and detailed processing metadata.
Large images increase upload times, bandwidth usage and storage requirements. jamit-image-optimizer adds a dedicated image-processing layer in front of an existing upload flow without taking ownership of the upload itself.
The package accepts normal browser File objects and returns normal File objects. This keeps it compatible with FormData, signed URLs, multipart uploads and custom backend APIs.
The package focuses on the parts that matter before an image reaches the network while remaining independent from frameworks and backend infrastructure.
Pass a browser File to the optimizer and receive a browser File back that can be used directly by an existing upload pipeline.
Images are decoded, resized and encoded inside the browser. The package itself does not upload files to an external service.
Expensive image-processing work runs outside the main UI thread to keep applications responsive during optimization.
JPEG, PNG and WebP processing is powered by browser-compatible WebAssembly codecs bundled into the worker build.
Images and non-image files can be processed together while preserving the original order of the upload selection.
JPEG and WebP output can search for a suitable quality level when an approximate target file size is required.
Batch processing limits the number of active image workers to avoid unnecessary CPU and memory pressure.
AbortSignal support and lifecycle callbacks make it possible to cancel work and reflect processing progress in the UI.
Each operation returns original and output metadata, size savings, compression information and processing timings.
The interactive playground demonstrates real browser-side processing with configurable output modes, quality, resize limits, target size and batch concurrency.
Images are optimized locally. Other file types can remain unchanged in the same batch.
JPEG · PNG · WebP · native HEIC / HEIF where supportedThe optimizer follows a predictable processing lifecycle while keeping the surrounding upload implementation completely under application control.
The input is classified as a supported image, unsupported image or passthrough file using MIME information and file signatures where applicable.
Supported images are decoded inside the worker using the appropriate codec or native browser capabilities.
Optional maximum width and height constraints are applied while preserving the aspect ratio and avoiding unnecessary upscaling.
The image is encoded according to the configured output mode, format, quality and optional target-size strategy.
The optimizer decides whether the generated output should replace the original and returns the final File together with detailed metadata.
jamit-image-optimizer ships as an ESM package with TypeScript declarations and can be installed with the package manager already used by your project.
pnpm add jamit-image-optimizernpm install jamit-image-optimizerThe published package does not require additional runtime dependencies from the consuming application. The codecs used by the worker are bundled into the package build.
Use optimizeImage() when a single supported image should be resized, compressed or converted before it is uploaded.
import { optimizeImage } from 'jamit-image-optimizer';
const result = await optimizeImage(file, {
mode: 'auto',
quality: 0.85,
resize: {
maxWidth: 1920,
maxHeight: 1920,
},
});
console.log(result.file);
console.log(result.savings.percent);The optimizer does not send files anywhere. Use the returned File with FormData, fetch, Axios, signed URLs, multipart uploads or any custom backend integration.
const result = await optimizeImage(file, {
mode: 'auto',
});
const formData = new FormData();
formData.append('file', result.file);
await fetch('/upload', {
method: 'POST',
body: formData,
});processFiles() is designed for upload interfaces where users select multiple files and the batch may contain both images and unrelated file types.
Supported images are processed with controlled concurrency while the output array keeps the same ordering as the input selection.
import { processFiles } from 'jamit-image-optimizer';
const result = await processFiles(files, {
mode: 'auto',
quality: 0.85,
resize: {
maxWidth: 1920,
maxHeight: 1920,
},
concurrency: 2,
});
await uploadFiles(result.files);PDFs, videos, text files and other non-image files can remain untouched in the same batch while supported images are optimized.
const result = await processFiles([
photo,
contractPdf,
screenshot,
video,
]);
for (const item of result.items) {
console.log({
name: item.originalFile.name,
kind: item.kind,
outcome: item.outcome,
});
}Three output modes cover format preservation, explicit conversion and automatic optimization without forcing applications into a single strategy.
The optimizer keeps the source format where an encoder for that format is available and applies resize or compression without intentionally converting it.
const result = await optimizeImage(file, {
mode: 'original',
quality: 0.8,
});Choose JPEG, PNG or WebP when the application requires a specific output format instead of preserving the source format.
const result = await optimizeImage(file, {
mode: 'format',
format: 'webp',
quality: 0.85,
});Auto mode evaluates WebP as an optimization candidate and keeps it only when using the generated output is actually beneficial.
const result = await optimizeImage(file, {
mode: 'auto',
quality: 0.85,
});Resize constraints and quality-based compression can be combined to reduce large camera images before they consume network bandwidth.
Define a maximum width, maximum height or both. The image is scaled down to fit the configured bounds without intentional upscaling.
const result = await optimizeImage(file, {
resize: {
maxWidth: 1920,
maxHeight: 1920,
},
});For quality-based output, the optimizer can perform a bounded quality search to approach a target byte size while respecting a configured minimum quality.
const result = await optimizeImage(file, {
quality: 0.9,
targetSize: 500 * 1024,
minQuality: 0.5,
});
console.log(result.compression.targetReached);Status callbacks and AbortSignal support make the optimizer suitable for interactive upload interfaces instead of only background scripts.
Receive lifecycle updates such as decoding, resizing, encoding and finalizing so the application can expose meaningful processing states.
await optimizeImage(file, {
onStatus(status) {
console.log(status.stage);
},
});Pass an AbortSignal to stop an active operation. Running workers are terminated instead of continuing unnecessary processing in the background.
const controller = new AbortController();
const promise = processFiles(files, {
concurrency: 2,
signal: controller.signal,
});
controller.abort();
await promise;HEIC and HEIF input support intentionally relies on native browser and operating-system decoding capabilities. The package does not bundle its own HEVC decoder.
When the environment can decode the file, it can be converted to an encodable output such as WebP, JPEG or PNG. When native decoding is unavailable, the package reports the unsupported codec path instead of pretending the format can be processed.
Large compressed images can expand dramatically when decoded. Configurable input-size, pixel-count and dimension limits allow applications to prevent unexpectedly expensive browser-side processing.
const result = await optimizeImage(file, {
limits: {
maxInputBytes: 20 * 1024 * 1024,
maxPixels: 12_000_000,
maxDimension: 8192,
},
});ImageOptimizerError exposes typed error codes for conditions such as invalid options, unavailable codecs, unsupported output formats, resource limits, worker failures and aborted operations.
import {
isImageOptimizerError,
optimizeImage,
} from 'jamit-image-optimizer';
try {
await optimizeImage(file);
} catch (error) {
if (isImageOptimizerError(error)) {
console.error(error.code);
console.error(error.message);
}
}The public API is plain TypeScript and works with browser File objects. Vue, Nuxt, React, Next.js, Svelte and Vanilla TypeScript applications can use the same package without a framework-specific adapter.
Image processing happens locally in the browser until the surrounding application decides what to do with the returned File.
jamit-image-optimizer does not send images, filenames, optimization metadata or processing telemetry to a JamIT service. The application's own upload or analytics infrastructure remains separate from the package.
The processing API depends on modern browser capabilities. HEIC and HEIF decoding additionally depends on the native codec support available in the browser and operating system.
The first public version includes single-image optimization, mixed-file batch processing, JPEG, PNG and WebP codecs, resize and quality controls, target-size optimization, native HEIC/HEIF decoding where available, controlled concurrency, abort support and detailed result metadata.
The package is published on npm and the source code, tests and development playground are available publicly on GitHub.
Review the implementation, browser tests, worker pipeline and public API, or report an issue directly in the repository.