Building Kilo: Architectural Deep-Dive into 100% Client-Side Media Compression & Shopify GraphQL Sync
An architectural deep-dive into building Kilo (kilo.nazmulcodes.org): a zero-server browser compression engine using OffscreenCanvas and WebAssembly, paired with Shopify GraphQL Admin API to compress store media without external cloud processing costs.
Heavy image files are the primary cause of sluggish page load times and failing Core Web Vitals across e-commerce stores. When building Kilo (https://kilo.nazmulcodes.org/), my goal was twofold: give developers and merchants a completely free, 100% private in-browser compression tool with zero file size limits, and seamlessly integrate it with Stockly so merchants can optimize their product catalogs in a single click.
The Performance Challenge: High-Resolution Media vs. Egress Latency
E-commerce stores rely heavily on visual appeal to drive product conversions, often requiring high-resolution product photography. However, unoptimized image assets (often between 4MB and 12MB) degrade Largest Contentful Paint (LCP) and cause significant layout shifts. Historically, fixing this required running heavy image processing pipelines on the server using Node.js Sharp or cloud functions. While functional, this traditional architecture creates substantial cloud egress expenses, server bottlenecks, and sluggish merchant feedback during bulk product uploads.
Architecture: Off-Main-Thread Processing with Web Workers
To avoid server processing bottlenecks, Kilo shifts the entire compression workload directly to client-side hardware. By utilizing HTML5 OffscreenCanvas inside a dedicated Web Worker, heavy pixel quantization and compression calculations run completely decoupled from the main UI thread. This guarantees that the admin dashboard remains buttery smooth at 60 FPS while processing high-resolution image batches.
interface CompressPayload {
file: File;
maxWidth: number;
maxHeight: number;
quality: number;
}
// Dedicated Web Worker handling offscreen rendering
self.onmessage = async (event: MessageEvent<CompressPayload>) => {
const { file, maxWidth, maxHeight, quality } = event.data;
const bitmap = await createImageBitmap(file);
const ratio = Math.min(maxWidth / bitmap.width, maxHeight / bitmap.height, 1);
const targetWidth = Math.round(bitmap.width * ratio);
const targetHeight = Math.round(bitmap.height * ratio);
const canvas = new OffscreenCanvas(targetWidth, targetHeight);
const ctx = canvas.getContext('2d', { willReadFrequently: false });
if (!ctx) {
self.postMessage({ error: 'Failed to initialize 2D context' });
return;
}
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = 'high';
ctx.drawImage(bitmap, 0, 0, targetWidth, targetHeight);
const compressedBlob = await canvas.convertToBlob({
type: 'image/webp',
quality,
});
self.postMessage({ blob: compressedBlob, byteSize: compressedBlob.size });
};Direct Shopify CDN Ingestion via Staged Uploads
Routing compressed binary payloads back through our application backend would introduce redundant latency. Kilo leverages Shopify's native stagedUploadsCreate GraphQL mutation. This generates short-lived, pre-signed upload credentials directly to Shopify's managed Google Cloud Storage infrastructure, allowing the merchant's browser to stream the optimized WebP asset straight to the CDN.
- Generate Staged Target: The app issues a stagedUploadsCreate mutation to receive pre-signed Cloud Storage endpoints.
- Direct Browser Upload: The client initiates a direct multipart POST stream with the newly compressed binary blob.
- File Registry Sync: The app executes fileCreate or productCreateMedia using the generated resource URL to finalize ingestion.
Why 100% Client-Side Processing Matters
Most online compression tools require uploading private merchant photos to remote servers. This introduces network transfer latency, server storage costs, and privacy concerns. Kilo executes all transformations directly in client browser memory using HTML5 Canvas and WebAssembly. No files ever touch a backend server.
export async function convertToWebP(file: File, quality = 0.82): Promise<Blob> {
const imageBitmap = await createImageBitmap(file);
const canvas = new OffscreenCanvas(imageBitmap.width, imageBitmap.height);
const ctx = canvas.getContext("2d");
ctx?.drawImage(imageBitmap, 0, 0);
return canvas.convertToBlob({ type: "image/webp", quality });
}OffscreenCanvas processes image encoding off the browser main thread, ensuring the UI remains buttery smooth even when processing 20MB raw photography.
The Stockly Ecosystem Integration (1-Click Shopify Sync)
Through the Stockly companion bridge at kilo.nazmulcodes.org/shopify, merchants who have Stockly installed can authenticate their store and fetch their catalog thumbnails via the Shopify Admin GraphQL API. With a single click, Kilo computes the optimal compression ratio and prepares optimized assets ready for instant storefront publishing.
Summary & Key Conclusion
Kilo demonstrates that combining client-side web capabilities with ecosystem-driven SaaS like Stockly creates exceptional speed, uncompromising privacy, and measurable merchant ROI.

Written by Nazmul Hawlader
Top RatedSenior Full-Stack Engineer & Official Shopify App Store developer. Founder of Stockly and Kilo (kilo.nazmulcodes.org), specializing in high-performance Shopify apps, client-side media compression, and sub-second web performance.