High-performance client-side image processing powered by Rust and WebAssembly
Process images entirely in the browser with near-native performance. No server uploads, works offline, respects user privacy.
Live Demo | Full Documentation | npm Package
npm install wasm-image-processorVite users: Install vite-plugin-wasm and add it to your config (see setup guide)
import { resize_square, blur, grayscale } from "wasm-image-processor";
// Resize an image to 512x512
const resizedBytes = resize_square(imageUint8Array, 512);
// Apply Gaussian blur
const blurredBytes = blur(imageUint8Array, 5.0);
// Convert to grayscale
const grayBytes = grayscale(imageUint8Array);Key features:
- Auto-initializes WASM (no manual setup)
- ~150KB gzipped bundle size
- TypeScript types included
- Supports PNG and JPEG formats
- See complete documentation for all functions
Project structure:
src/
lib.rs # WASM bindings & public API
processing/ # Core image processing logic
utils/ # Helpers
Cargo.toml
Local development:
# Build for web
wasm-pack build --target web --out-dir pkg
# Run tests
cargo test
wasm-pack test --headless --firefox
# Test in browser
cd example && npm install && npm run devKey dependencies:
image = "0.24"for core processingwasm-bindgen = "0.2"for JS interop- Safe Rust only, panic-safe for WASM context
Contributing: Fork the repo, create a feature branch, and open a PR. See documentation repo for docs contributions.
Core Operations:
resize_square(bytes, size)- Resize to square dimensionsresize(bytes, width, height)- Resize to custom dimensionscrop(bytes, x, y, width, height)- Crop to regionthumbnail(bytes, width, height)- Generate thumbnail
Filters & Adjustments:
blur(bytes, sigma)- Gaussian blurfast_blur(bytes, sigma)- Optimized blurcontrast(bytes, value)- Adjust contrast (-100 to 100)brighten(bytes, value)- Adjust brightness (-100 to 100)grayscale(bytes)- Convert to grayscaleinvert(bytes)- Invert colorshue_rotate(bytes, degrees)- Rotate hue (0-360)
Coming Soon:
rotate(bytes, degrees)- Rotate image
See full API documentation with live examples for each function.
For end users:
- Privacy: Images never leave your device
- Speed: Process images in milliseconds
- Offline: Works without internet connection
- Universal: Runs in any modern browser
For developers:
- Rust performance in JavaScript
- Simple, predictable API
- Tree-shakeable ES modules
- No server infrastructure needed
Profile picture editors: Generate multiple sizes for avatars without server round-trips. Resize to 32px, 64px, 128px, 256px instantly in the browser.
Photo galleries & portfolios: Create thumbnails client-side before upload. Apply filters for preview without processing server load.
PWA & offline apps: Process images when users have no internet connection. Perfect for field work apps, travel journals, or offline-first tools.
Privacy-sensitive applications: Medical imaging viewers, legal document processors, or any app where images contain sensitive data that shouldn't touch external servers.
Image compression tools: Build "TinyPNG alternatives" that run entirely in the browser. Users maintain full control of their files.
Batch processing utilities: Resize hundreds of product photos, apply watermarks, or normalize images for e-commerce without server costs or upload time.
Design tools & editors: Add real-time image adjustments (brightness, contrast, blur) to your web app without heavy JavaScript libraries.
Form enhancements: Automatically resize large images before form submission to reduce upload size and improve UX.
- Chrome/Edge 57+
- Firefox 52+
- Safari 11+
- Any browser with WebAssembly support
<input type="file" id="fileInput" />
<button id="downloadBtn" style="display: none;">Download Processed Image</button>
<script type="module">
import { resize_square, blur } from "wasm-image-processor";
const input = document.getElementById("fileInput");
const downloadBtn = document.getElementById("downloadBtn");
input.addEventListener("change", async (e) => {
const file = e.target.files[0];
if (!file) return;
try {
// Read file
const arrayBuffer = await file.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
// Process: resize and blur
const resized = resize_square(uint8Array, 512);
const processed = blur(resized, 2.0);
// Create downloadable blob
const blob = new Blob([processed], { type: "image/png" });
const url = URL.createObjectURL(blob);
// Setup download
downloadBtn.style.display = "block";
downloadBtn.onclick = () => {
const a = document.createElement("a");
a.href = url;
a.download = "processed-image.png";
a.click();
URL.revokeObjectURL(url);
};
} catch (error) {
console.error("Processing failed:", error);
}
});
</script>See more examples including Vue, Nuxt, and React patterns.
Processing happens entirely client-side using WebAssembly, providing:
- Fast processing with near-native performance
- Complete privacy - images never uploaded
- Offline capability
- Zero server costs
Typical operations:
- Resize 4K image: ~45ms
- Apply blur filter: ~30ms
- Grayscale conversion: ~10ms
Performance varies by device and image size.
Import errors: Ensure your bundler supports WebAssembly. Vite users need vite-plugin-wasm installed and configured.
"Failed to read image": Only PNG and JPEG formats are currently supported.
Memory issues: Large images may cause problems on mobile devices. Consider resizing or adding file size limits.
See troubleshooting guide for more help.
Contributions welcome! To contribute:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open a Pull Request
For documentation improvements, contribute to the docs repository.
MIT License - see LICENSE file for details.
Built with:
- Rust and wasm-bindgen
- image-rs crate for image processing
- Inspired by the need for privacy-respecting browser-based tools
Questions? Open an issue or check the documentation.