Whenever you search for a simple utility like "Merge PDF" or "Convert WebP to PNG", you are usually greeted by the same frustrating experience:
- A 15MB file upload limit behind an aggressive paywall.
- A subscription pop-up asking for $12/month.
- Your sensitive personal documents (tax returns, signed contracts, medical records) getting uploaded to an untrusted remote server.
As developers, we know that modern browsers have hardware-accelerated GPUs, multi-threaded Web Workers, and WebAssembly. There is zero technical justification for uploading a document to a cloud server just to merge two pages or change an image format.
So I decided to build SwiftUtils — a suite of 100% client-side, zero-upload web utilities that process everything directly in browser memory.
Here is the exact technical architecture behind how it works.
1. In-Browser PDF Merging with Zero Cloud Leaks
Most online PDF services transmit your PDFs across the wire to a backend running poppler or pdfcpu. Instead, we can load the document structure directly into browser memory using pdf-lib:
import { PDFDocument } from 'pdf-lib';
async function mergePDFsInBrowser(fileList) {
// 1. Create a fresh document in browser memory
const mergedPdf = await PDFDocument.create();
for (const file of fileList) {
const arrayBuffer = await file.arrayBuffer();
// 2. Parse the PDF structure locally
const pdf = await PDFDocument.load(arrayBuffer);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
// 3. Append pages to the merged document
copiedPages.forEach((page) => mergedPdf.addPage(page));
}
// 4. Save and generate a local memory blob
const pdfBytes = await mergedPdf.save();
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
return URL.createObjectURL(blob);
}
Why This Matters for Performance:
- Zero Network Bottleneck: A 50MB PDF merges in ~300ms locally rather than waiting 45 seconds on an upload/download roundtrip.
- True Privacy: The network tab shows zero outbound POST requests containing file data.
2. High-Fidelity 32-Bit Alpha Rasterization with HTML5 Canvas
When converting modern image formats like WebP, HEIC, or SVG into PNG, many online tools fail because they discard the alpha channel, turning transparent backgrounds into solid black or white squares.
By utilizing the browser's native CanvasRenderingContext2D, we maintain complete 32-bit RGBA color channels:
function convertToLosslessPNG(imageSource) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
const canvas = document.createElement('canvas');
canvas.width = img.naturalWidth || img.width;
canvas.height = img.naturalHeight || img.height;
const ctx = canvas.getContext('2d');
// Sub-pixel drawing preserving 100% alpha transparency
ctx.drawImage(img, 0, 0);
canvas.toBlob((blob) => {
if (blob) resolve(blob);
else reject(new Error('Canvas rasterization failed'));
}, 'image/png');
};
img.onerror = () => reject(new Error('Failed to load image'));
img.src = imageSource;
});
}
3. Handling Apple HEIC Photos with WebAssembly
Apple's iPhone cameras save images in HEIC/HEIF format. Browsers cannot natively display .heic files in standard <img> tags.
To bypass this without a server, we compile libde265 into WebAssembly using heic2any:
async function decodeHeicInBrowser(heicFile) {
// Processed via local WebAssembly thread
const pngBlob = await window.heic2any({
blob: heicFile,
toType: 'image/png'
});
return Array.isArray(pngBlob) ? pngBlob[0] : pngBlob;
}
4. Avoiding Memory Leaks During Large Batch Conversions
When users drop 50+ high-resolution photos into the browser, allocating dozens of object URLs will quickly exhaust browser RAM.
To prevent memory bloat, we always pair blob creation with lifecycle garbage collection:
// Once download completes or row is removed from UI:
URL.revokeObjectURL(temporaryPreviewUrl);
Try It Live & Check the Code
- Live Web Utilities: https://swiftutils.net
- GitHub Repository: https://github.com/taqiraza/swiftutils
If you find this useful or want to contribute more client-side conversion algorithms, feel free to drop a star on the repo or suggest new tools in the comments!
Top comments (0)