How to Reduce CBZ File Sizes Locally Using WebAssembly
Shrink your digital comic library without uploading files. Learn how to use wasm-vips to compress CBZ files locally for speed and privacy.

How to Reduce CBZ File Sizes Locally Using WebAssembly
If you collect digital comics or manga, you already know the struggle. You download a massive archive, drop it onto your tablet or e-reader, and instantly watch your storage vanish.
A CBZ file is not a magical proprietary format. It is just a standard ZIP archive dressed up with a .cbz extension, packed full of raw image files—usually JPEGs or PNGs. Because comic publishers and scanlation groups want to preserve quality, a single volume can easily blow past 500MB. Try loading an entire series onto an iPad, and you hit a storage wall fast.
The obvious fix is to resize the images and compress them to a modern format like WebP. But how you do that matters immensely.
For years, the internet told you to rely on cloud-based converters. At MLOGICTECH, we took a completely different approach. We built a pipeline to shrink your comics entirely inside your browser using WebAssembly. Here is how we engineered it, why local processing crushes the cloud, and the real-world hurdles we hit while building it.
The Cloud Conversion Trap
Think about the traditional cloud-based workflow for resizing a CBZ file:
1.The Upload: You push a 500MB file over your network to a random server.
2.The Wait: You sit in a server queue while a remote machine unzips the file.
3.The Processing: A backend script resizes the images.
4.The Download: You pull the newly compressed 150MB file back to your device.
This is a massive waste of bandwidth. You are transmitting half a gigabyte of data across the internet just to reduce its size.
Worse, it is a glaring privacy risk. Your digital library is your business. Pushing personal files to a third-party server means trusting that they actually delete your data when they say they do. We built LokalTools on a strict principle: if a file does not need to leave your device, it shouldn't.
Enter Wasm-Vips: Bringing the Engine to the Client
To shrink a comic locally, we needed an image processing engine that was fast, lightweight, and capable of running in a browser. We chose libvips.
In the backend world, libvips is legendary. It is a horizontally threaded, demand-driven image processing library written in C. Unlike traditional tools that load an entire image into memory before doing anything, libvips uses streaming pipelines. It reads an image section by section, applies operations, and writes the output. This means it can process massive images while consuming almost zero RAM.
Thanks to WebAssembly (WASM), we do not need a backend server to run it. WASM is a binary instruction format that lets us execute native C and C++ code directly inside a web browser at near-native speeds. The wasm-vips project compiles the entire libvips engine into a payload your browser can run.
When you drop a CBZ file into our tool, here is the exact execution flow:
-A local JavaScript utility unzips the archive directly in your system's memory.
-We extract the raw JPEGs or PNGs.
-We stream those image buffers straight into wasm-vips.
-The WASM engine utilizes your local CPU (leveraging WebAssembly SIMD for hardware-accelerated vector math) to resize the dimensions and re-encode the pixels to a highly efficient format.
-Finally, we repack the optimized images back into a new ZIP archive and rename it .cbz.
Zero bytes are uploaded. The network is completely bypassed.
From the Developer's Desk: The Memory Leak Nightmare
Building a local wasm-vips pipeline sounds incredibly elegant. In reality, it was a brutal engineering challenge.
When I first prototyped the CBZ compressor for LokalTools, I wrote a simple loop. The script unzipped a 200-page comic, passed every single page into wasm-vips, resized them using vips.Image.thumbnailBuffer(), and spat them out.
I hit "Compress." The browser tab instantly flatlined. My RAM usage spiked by 4GB, and Chrome threw an Out Of Memory (OOM) crash screen.
The Gotcha: C and C++ require manual memory management. When libvips runs natively on a server, the operating system cleans up after the process dies. But in the browser, WebAssembly lives inside a JavaScript sandbox. The JS garbage collector has absolutely no idea when a C++ image object is finished processing. Because I was looping through 200 images, I was continuously allocating WASM memory without ever freeing it.
The Fix: We had to completely rethink our browser memory strategy.
First, we enforced strict memory cleanup. Every single wasm-vips operation had to be wrapped in tightly scoped blocks, explicitly calling .delete() on the image objects the millisecond they were no longer needed.
Second, we tackled the UI freezing. Heavy image encoding absolutely shreds the main browser thread. To stop the browser from locking up, we moved the entire wasm-vips instance into a dedicated Web Worker. This spins up a background thread separate from your UI.
Finally, to allow the Web Worker to efficiently share memory with the main thread without copying massive files back and forth, we implemented the SharedArrayBuffer API. This required configuring strict cross-origin isolation headers.
We also threw out the "process everything at once" model. Instead of feeding all 200 pages into WASM simultaneously, we built a sequential queue. The worker processes just a few pages at a time. The result is a buttery smooth user interface that slowly ticks up a progress bar while keeping memory usage clamped under 250MB.
The Trade-offs: When the Cloud Actually Wins
We are obsessed with client-side processing, but we also live in reality. Browser-based WebAssembly is incredibly powerful, yet it is ultimately constrained by the physical device holding it.
Local processing scales perfectly with your hardware. If you are reading on an M-series MacBook Pro or a flagship smartphone, local conversion is flawless. Your device will rip through a 300-page comic significantly faster than waiting for a cloud upload to finish.
However, edge cases exist. If you are using a severely underpowered, five-year-old budget phone and trying to compress a monolithic 3GB omnibus CBZ file, your local CPU is going to scream. The browser will likely struggle with the sheer file size before the conversion even begins, and you will drain your battery fast.
For massive, multi-gigabyte batch jobs on low-end hardware, a traditional server with 64GB of RAM and dedicated processing power is fundamentally better. But for the vast majority of everyday users—shrinking a manga volume to fit on an e-reader or optimizing a graphic novel for faster swiping—local WASM execution wins effortlessly on privacy, speed, and bandwidth.
Try It Yourself
Stop letting bloated digital comics eat your hard drive. Take control of your storage without exposing your reading library to the cloud.
Head over to the LokalTools CBZ Compressor and drop in a heavy comic archive. Watch exactly how fast your own machine can slice through the pages and repack them, right inside your browser, without a single byte ever touching our servers.