React does not compress images by itself. In a browser-side upload flow, take the selected File, process it with an image-compression library or browser APIs, then upload the resulting File or Blob. The example below uses browser-image-compression, which returns a Promise that resolves to a file.
Compress a selected image before uploading it
Install the package with npm install browser-image-compression, then call it from your file input handler. This example keeps the original file if the result is not smaller, reports errors, and prevents an earlier selection from updating the UI after a newer one is chosen.
import { useRef, useState } from 'react';
import imageCompression from 'browser-image-compression';
export default function ImageUploader() {
const [status, setStatus] = useState('');
const [error, setError] = useState('');
const latestJob = useRef(0);
async function handleFileChange(event) {
const input = event.currentTarget;
const file = input.files?.[0];
if (!file) return;
const job = ++latestJob.current;
setError('');
setStatus('Compressing…');
try {
const compressed = await imageCompression(file, {
maxSizeMB: 1,
maxWidthOrHeight: 1920,
useWebWorker: true,
});
if (job !== latestJob.current) return;
// Compression is not guaranteed to shrink every file.
const uploadFile = compressed.size < file.size ? compressed : file;
await uploadImage(uploadFile);
setStatus(`Uploaded ${uploadFile.name}`);
} catch (err) {
if (job !== latestJob.current) return;
setError(err instanceof Error ? err.message : 'Image processing or upload failed.');
setStatus('');
} finally {
// Permit choosing the same file again after processing or failure.
input.value = '';
}
}
async function uploadImage(file) {
const formData = new FormData();
formData.append('image', file, file.name);
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
if (!response.ok) throw new Error(`Upload failed (${response.status})`);
}
return (
<div>
<label>
Choose an image
<input type="file" accept="image/*" onChange={handleFileChange} />
</label>
<p role="status">{status}</p>
{error && <p role="alert">{error}</p>}
</div>
);
}
Replace /api/upload with your upload endpoint and adapt the form field name to what that endpoint expects. The maxSizeMB and maxWidthOrHeight values above are example limits, not a promise that every image will land below a particular size. The package documents these controls and its React use at npmjs.com/package/browser-image-compression.
Choose size, dimensions, and format deliberately
A byte-size target and a pixel-dimension limit solve different problems. A smaller maximum dimension reduces the image’s pixel width or height; a target size asks the encoder to aim for a file size. Choose limits from your product’s upload constraints and the visual quality your users need, then inspect representative output rather than assuming one setting fits every image.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →#1 Best Overall
- Maximum size:
maxSizeMBsets the package’s target maximum file size. - Maximum dimension:
maxWidthOrHeightconstrains the longer side, useful when oversized camera images are unnecessary for the display. - Quality and type:
initialQualityandfileTypelet you make explicit quality and output-format choices. Check the output type and quality with your own image mix and supported browsers. - Progress and cancellation: The package documents
onProgressand an abort signal option, useful for longer work or a cancelable interface. - Metadata: Decide whether to preserve EXIF metadata using
preserveExif; do not conflate retaining metadata with correcting image orientation.
Its documented formats include JPEG, PNG, WebP, and BMP. Browser canvas limits and WebP compatibility can vary, so avoid forcing a format until it has been checked against your browser and device support matrix. See the project repository for package details and compatibility notes.
Keep the interface responsive and handle orientation
Decoding large images and re-encoding them through a canvas can take time and memory. The package offers worker processing and documents fallback to the main thread; its non-blocking worker path depends on browser support for OffscreenCanvas. A worker is not a guarantee that every device or image will process identically.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
When enabling the worker option, check your deployment Content Security Policy. The package notes its worker setup may need blob: in script-src, or a self-hosted worker-library URL. If processing is still slow or fails on a supported device, test a representative large image with worker mode on and off.
Camera images can carry EXIF orientation information. Test portrait and landscape photos from real target devices and decide whether additional EXIF fields should remain in the output. Browser image APIs expose lower-level decode and orientation controls; see MDN’s WorkerGlobalScope.createImageBitmap documentation.
Rank #3
Use browser APIs when you need a custom pipeline
A custom implementation can use createImageBitmap to decode an image and canvas toBlob to encode it. Chrome’s overview demonstrates fetching a Blob, decoding it with createImageBitmap, and using canvas output; it also discusses use in workers: Chrome for Developers: createImageBitmap in Chrome 50.
This route gives control but leaves more responsibility with your application: handling decode and encode errors, output type and filename, quality, orientation, metadata, cancellation, browser compatibility, and whether the result is smaller than the input. A resizing-focused option is pica, which documents worker, WebAssembly, createImageBitmap, and JavaScript fallback approaches. The cited documentation does not establish a comparable speed or quality benchmark across these choices, so test with your own images and devices before choosing on performance grounds.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Troubleshoot common problems
- No file is processed: Confirm a file was selected before reading
files[0]; the input may be empty when cleared or canceled. - The upload still exceeds your limit: Check the actual
File.sizeof the returned result and the server’s limit. A target is not proof that every output meets a backend constraint; reject, ask the user to choose a smaller image, or apply a product-specific fallback. - The output is not smaller: Compare the compressed and original sizes and choose deliberately, as the example does. Already-small files or format conversion may not benefit.
- Images appear rotated or metadata is missing: Test camera photos and explicitly choose orientation and EXIF handling. These are separate concerns.
- Worker errors or CSP violations: Review the package’s worker requirements and your
script-srcpolicy; test the documented self-hosting option or disable worker processing where needed. - Large image crashes or fails: Test against browser canvas limits and device memory. The package documents automatic dimension adjustment to stay within canvas limits, but that does not remove the need to test your supported environments.
- WebP or another requested output is wrong or unsupported: Verify actual browser support and inspect the resulting file’s MIME type rather than relying only on the requested setting.
- Promise rejection leaves the UI stuck: Catch processing and upload failures, clear the loading state, and provide a retry path. If you expose cancellation, handle the abort separately from a genuine processing error.
Performance, reliability, and cost considerations
Client-side compression trades some browser CPU, memory, and waiting time for sending a potentially smaller upload. The exact savings and processing time depend on the input, settings, browser, and device; the cited sources do not provide an independent compression-ratio or speed measurement. Test representative photos and graphics across the devices you support, including large files and slow devices. Retain server-side validation and limits: browser processing does not make client-submitted content trustworthy.
If you need more control than a package provides, the browser API route is flexible but increases compatibility and maintenance work. For either route, measure actual output sizes, handle failures, and avoid claiming a fixed savings percentage without measurements from your own workload.
Best Value
Or skip the browser setup
ScreenshotNeo is a website screenshot API, not a compressor for a user’s selected image. If your task is instead to capture a webpage as an image, one GET request returns a screenshot or PDF. Docs: ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides screenshot tools for AI agents. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Those are webpage captures, not image-compression credits.
Sign up for ScreenshotNeo’s free plan to get 1,000 webpage screenshots a month with no card.
Frequently Asked Questions
Does React have a built-in image compression function?
No. React handles the interface; use a browser image library or browser APIs to process the selected file.
Can I guarantee every compressed image will be under my upload limit?
Do not rely on the client-side target alone. Check the resulting file size and enforce the actual limit on your server.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




