<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: iqbalhssn78</title>
    <description>The latest articles on DEV Community by iqbalhssn78 (@iqbalhssn78).</description>
    <link>https://dev.to/iqbalhssn78</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4103805%2F8efa2f3b-e92d-4339-a1bb-02ad5288492b.png</url>
      <title>DEV Community: iqbalhssn78</title>
      <link>https://dev.to/iqbalhssn78</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iqbalhssn78"/>
    <language>en</language>
    <item>
      <title>The Best iLovePDF Alternatives (One of Them Never Touches Your Files)</title>
      <dc:creator>iqbalhssn78</dc:creator>
      <pubDate>Wed, 02 Sep 2026 10:13:32 +0000</pubDate>
      <link>https://dev.to/iqbalhssn78/the-best-ilovepdf-alternatives-one-of-them-never-touches-your-files-47j0</link>
      <guid>https://dev.to/iqbalhssn78/the-best-ilovepdf-alternatives-one-of-them-never-touches-your-files-47j0</guid>
      <description>&lt;h2&gt;
  
  
  Why People Look for iLovePDF Alternatives
&lt;/h2&gt;

&lt;p&gt;iLovePDF is good. Clean interface, reliable output, handles most PDF tasks. Three reasons come up every time people look for alternatives: daily task limits, files being uploaded to remote servers, and core features like OCR locked behind a paywall.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. I Have A Tool For That - Best for Privacy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://ihaveatoolforthat.com" rel="noopener noreferrer"&gt;ihaveatoolforthat.com&lt;/a&gt;&lt;/strong&gt; | Free | No file upload required&lt;/p&gt;

&lt;p&gt;This tool uses WebAssembly to run the PDF processing engine directly inside your browser. Your file never travels across the internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it covers:&lt;/strong&gt; Merge, Split, Compress, Rotate, Crop, Watermark, Page Numbers, Protect, Unlock, OCR (image to text), Extract Images, Extract Text, PDF to JPG, PDF to PNG, JPG to PDF, PNG to PDF.&lt;/p&gt;

&lt;p&gt;The privacy is verifiable. Open DevTools, go to the Network tab, then process any file. You will see zero outbound requests carrying your data. The architecture makes it structurally impossible for your file to leave your device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Tax returns, contracts, medical records, legal documents - anything you would not want sitting on a stranger server.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Stirling PDF - Best Self-Hosted Option
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;stirlingtools.com&lt;/strong&gt; | Free (Docker) | Files go to your own server&lt;/p&gt;

&lt;p&gt;Open source, 50+ operations, Docker-based. If you run your own server, Stirling PDF gives you complete control over where your files go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Developers and IT teams comfortable with self-hosting who need enterprise-level control.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. PDF24 Creator - Best Free Windows Desktop App
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;pdf24.org&lt;/strong&gt; | Free | Processes locally on your machine&lt;/p&gt;

&lt;p&gt;PDF24 Windows desktop application processes everything on your machine. No uploads, no limits, no subscription. Merge, split, compress, convert, OCR - all offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Windows users who prefer an installed application over browser tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. PDFgear - Best Full PDF Editor
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;pdfgear.com&lt;/strong&gt; | Free | Desktop and mobile&lt;/p&gt;

&lt;p&gt;The most feature-rich free PDF editor available. Annotation, editing, form filling, AI features - all free, running locally on your device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Users who need a proper PDF editor with full editing capability, not just utilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Sejda - Best iLovePDF-Like Browser Experience
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;sejda.com&lt;/strong&gt; | Free (3 tasks per day) | Server-based&lt;/p&gt;

&lt;p&gt;The closest browser experience to iLovePDF, with cleaner design and files deleted within 2 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Occasional use where you want the familiar online interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Pick Guide
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sensitive documents, zero uploads:&lt;/strong&gt; I Have A Tool For That&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted team control:&lt;/strong&gt; Stirling PDF&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows offline desktop app:&lt;/strong&gt; PDF24 Creator&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full PDF editing features:&lt;/strong&gt; PDFgear&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick occasional browser use:&lt;/strong&gt; Sejda&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;All file processing at &lt;a href="https://ihaveatoolforthat.com" rel="noopener noreferrer"&gt;ihaveatoolforthat.com&lt;/a&gt; runs locally in your browser via WebAssembly. Your files never leave your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>pdf</category>
      <category>privacy</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How WebAssembly became our privacy architecture (not just a performance trick)</title>
      <dc:creator>iqbalhssn78</dc:creator>
      <pubDate>Tue, 01 Sep 2026 07:05:58 +0000</pubDate>
      <link>https://dev.to/iqbalhssn78/how-webassembly-became-our-privacy-architecture-not-just-a-performance-trick-5c00</link>
      <guid>https://dev.to/iqbalhssn78/how-webassembly-became-our-privacy-architecture-not-just-a-performance-trick-5c00</guid>
      <description>&lt;p&gt;Most WebAssembly articles talk about performance. Yours runs 5x faster than pure JavaScript. Great.&lt;/p&gt;

&lt;p&gt;This one is about something different: &lt;strong&gt;how Wasm's sandboxed execution model makes certain privacy failures structurally impossible&lt;/strong&gt; -- and how we built 90+ browser tools around that property.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem We Were Solving
&lt;/h2&gt;

&lt;p&gt;When someone uses iLovePDF, Smallpdf, or Adobe Acrobat Online to process a PDF, their file travels to a remote server, gets processed, and sits there until "deleted" (usually 1-24 hours). For a casual PDF merge, fine. For a tax return, medical record, or legal contract -- that's a real data exposure event.&lt;/p&gt;

&lt;p&gt;Most "privacy-focused" alternatives solve this with a policy: &lt;em&gt;"We delete your files after processing."&lt;/em&gt; That's still an upload. The file still left the device.&lt;/p&gt;

&lt;p&gt;We wanted something different: &lt;strong&gt;make the upload architecturally impossible&lt;/strong&gt;, not just unlikely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why WebAssembly Works Here
&lt;/h2&gt;

&lt;p&gt;WebAssembly modules run inside the browser's sandboxed execution environment. The critical property for privacy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Wasm modules cannot initiate network connections.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They have no access to &lt;code&gt;fetch()&lt;/code&gt;, &lt;code&gt;XMLHttpRequest&lt;/code&gt;, or any network API. The only way a Wasm module can communicate with the outside world is through explicitly provided JavaScript host functions.&lt;/p&gt;

&lt;p&gt;This means if you build your processing pipeline correctly, there is no point at which a network request carrying file data can exist. It's not a privacy setting. It's a structural constraint of the runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  The In-Browser Pipeline
&lt;/h2&gt;

&lt;p&gt;Here's the exact pipeline for every file operation on our site:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Step 1: Read file locally -- stays in browser memory&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Step 2: Pass to Wasm module -- sandboxed, no network access&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;wasmModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Step 3: Create output Blob -- still in browser memory&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Step 4: Create a local URL for download&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Step 5: Trigger download -- from memory directly to device&lt;/span&gt;
&lt;span class="nx"&gt;downloadLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;downloadLink&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Step 6: Clean up -- no trace remains&lt;/span&gt;
&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At no point does file data touch a network socket. The &lt;code&gt;ArrayBuffer&lt;/code&gt; goes in, a processed &lt;code&gt;ArrayBuffer&lt;/code&gt; comes out, and a &lt;code&gt;Blob URL&lt;/code&gt; triggers a local download.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Open Source Stack
&lt;/h2&gt;

&lt;p&gt;All processing uses open source WebAssembly libraries:&lt;/p&gt;

&lt;h3&gt;
  
  
  PDF Processing -- pdf-lib (MIT)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Hopding/pdf-lib" rel="noopener noreferrer"&gt;pdf-lib&lt;/a&gt; handles PDF creation and modification in pure JavaScript. No Wasm compilation needed -- it operates directly on &lt;code&gt;ArrayBuffer&lt;/code&gt; data.&lt;/p&gt;

&lt;p&gt;Powers: Merge PDF, Split, Compress, Rotate, Crop, Watermark, Page Numbers, Protect (AES encryption), Unlock, Rearrange Pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  PDF Parsing -- pdfjs-dist (Apache 2.0)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/mozilla/pdf.js" rel="noopener noreferrer"&gt;PDF.js&lt;/a&gt; from Mozilla handles rendering and text extraction. We run it inside a &lt;strong&gt;dedicated Web Worker&lt;/strong&gt; -- isolated from the main thread, with no network API access.&lt;/p&gt;

&lt;p&gt;Powers: Extract Text from PDF, Extract Images, PDF preview.&lt;/p&gt;

&lt;h3&gt;
  
  
  OCR -- Tesseract.js (Apache 2.0)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/naptha/tesseract.js" rel="noopener noreferrer"&gt;Tesseract.js&lt;/a&gt; compiles the Tesseract OCR engine (C++) to WebAssembly. The full LSTM neural network runs in the browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createWorker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eng&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;recognize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageFile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 'text' contains the recognized content&lt;/span&gt;
&lt;span class="c1"&gt;// zero network requests containing image data occurred&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Wasm binary (~10MB) downloads once and is cached by the browser. After that, OCR works completely offline.&lt;/p&gt;

&lt;p&gt;Powers: Image to Text, Extract Text from scanned PDFs.&lt;/p&gt;

&lt;h3&gt;
  
  
  HEIC Decoding -- heic2any (MIT)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/alexcorvi/heic2any" rel="noopener noreferrer"&gt;heic2any&lt;/a&gt; decodes iPhone HEIC photos client-side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;heic2any&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;heicFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;toType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;quality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// blob is a local JPEG -- never left the device&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Powers: HEIC to JPG, HEIC to PNG.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Workers for CPU-Intensive Operations
&lt;/h2&gt;

&lt;p&gt;For heavy operations, we offload to a Web Worker to avoid blocking the main thread:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Main thread -- transfer ArrayBuffer (zero-copy)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/workers/pdf-processor.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;COMPRESS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;arrayBuffer&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;arrayBuffer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// transferable -- ownership moves, no copy&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;DONE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;deliverDownload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Transferring &lt;code&gt;ArrayBuffer&lt;/code&gt; objects rather than copying them keeps memory flat regardless of file size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying the Privacy Claim
&lt;/h2&gt;

&lt;p&gt;This is the part we care most about. Any user can verify this in 60 seconds:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;DevTools -&amp;gt; Network tab&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Check &lt;strong&gt;"Preserve log"&lt;/strong&gt; and clear existing entries&lt;/li&gt;
&lt;li&gt;Select a file and run any tool&lt;/li&gt;
&lt;li&gt;After processing completes, examine the Network tab&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll see requests for static assets -- JS bundles, CSS, the Wasm binary on first load. You will not see any request with your file's bytes as the payload.&lt;/p&gt;

&lt;p&gt;We documented the full pipeline at &lt;a href="https://ihaveatoolforthat.com/privacy-guarantee" rel="noopener noreferrer"&gt;ihaveatoolforthat.com/privacy-guarantee&lt;/a&gt; with the specific intent that any technically inclined user can verify the claims themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tradeoffs
&lt;/h2&gt;

&lt;p&gt;Client-side Wasm processing is not free. The honest tradeoffs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero network latency -- no upload/download round trip&lt;/li&gt;
&lt;li&gt;Works offline once Wasm binaries are cached&lt;/li&gt;
&lt;li&gt;No server infrastructure that scales with usage&lt;/li&gt;
&lt;li&gt;No breach surface for file data (nothing to steal from a server that never received it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First load: Wasm binaries can be large (Tesseract ~10MB)&lt;/li&gt;
&lt;li&gt;CPU-bound on the client -- slow devices process slowly&lt;/li&gt;
&lt;li&gt;Memory limited to browser tab allocation (~2GB practical limit)&lt;/li&gt;
&lt;li&gt;No server-side caching of results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our use case -- occasional document processing -- the tradeoffs are strongly in favor of client-side processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Architecture Gets You
&lt;/h2&gt;

&lt;p&gt;Beyond privacy, building this way has some unexpected benefits:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero infrastructure cost for processing.&lt;/strong&gt; Our servers host static files. The actual PDF merging, OCR, and image conversion runs on users' CPUs. We never pay for compute proportional to usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offline capability.&lt;/strong&gt; Once the Wasm binaries are cached, every tool works without an internet connection. We added &lt;code&gt;manifest.json&lt;/code&gt; and service worker support -- users can install it as a PWA and process files on a plane.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No rate limits.&lt;/strong&gt; Cloud services throttle you because they're paying for compute. We're not -- so there are no daily limits, no file size caps based on subscription tier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Broader Point
&lt;/h2&gt;

&lt;p&gt;WebAssembly's sandboxed execution model is usually discussed as a security property -- Wasm can't break out of its sandbox and do malicious things. But the same property works in the other direction: &lt;strong&gt;it also prevents Wasm code from doing things the user didn't explicitly authorize&lt;/strong&gt;, like sending their files to a server.&lt;/p&gt;

&lt;p&gt;If you're building tools that handle sensitive user data, this is worth thinking about not as a privacy feature you add -- but as a design constraint that makes certain privacy failures simply impossible by construction.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt; &lt;a href="https://ihaveatoolforthat.com" rel="noopener noreferrer"&gt;ihaveatoolforthat.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Technical details:&lt;/strong&gt; &lt;a href="https://ihaveatoolforthat.com/privacy-guarantee" rel="noopener noreferrer"&gt;ihaveatoolforthat.com/privacy-guarantee&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Built with pdf-lib, Tesseract.js, pdfjs-dist, and heic2any -- all MIT or Apache 2.0 licensed.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webassembly</category>
      <category>privacy</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
