<?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: Muath Aljehani</title>
    <description>The latest articles on DEV Community by Muath Aljehani (@muath_aljehani_9d9238bb3a).</description>
    <link>https://dev.to/muath_aljehani_9d9238bb3a</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3824470%2Fc80d6f45-34d8-4ba1-983d-33e269227087.jpg</url>
      <title>DEV Community: Muath Aljehani</title>
      <link>https://dev.to/muath_aljehani_9d9238bb3a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/muath_aljehani_9d9238bb3a"/>
    <language>en</language>
    <item>
      <title>I built a PDF toolkit that never uploads your files — here's how</title>
      <dc:creator>Muath Aljehani</dc:creator>
      <pubDate>Sat, 14 Mar 2026 19:49:59 +0000</pubDate>
      <link>https://dev.to/muath_aljehani_9d9238bb3a/i-built-a-pdf-toolkit-that-never-uploads-your-files-heres-how-5f2o</link>
      <guid>https://dev.to/muath_aljehani_9d9238bb3a/i-built-a-pdf-toolkit-that-never-uploads-your-files-heres-how-5f2o</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every time I needed to compress, merge, or convert a PDF, I had to &lt;br&gt;
upload it to some website. Most of them store your file on their &lt;br&gt;
servers for 24+ hours.&lt;/p&gt;

&lt;p&gt;For personal documents, contracts, or anything sensitive — that's a &lt;br&gt;
real privacy concern.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;What if all the processing happened locally in the browser?&lt;/p&gt;

&lt;p&gt;Modern JavaScript is powerful enough to handle PDF manipulation &lt;br&gt;
entirely client-side. No file ever needs to leave your device.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;opdf.io&lt;/strong&gt; — 27 free PDF tools that run 100% in your browser.&lt;/p&gt;

&lt;p&gt;Tools include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merge, split, compress, rotate&lt;/li&gt;
&lt;li&gt;PDF → Word, JPG, PNG&lt;/li&gt;
&lt;li&gt;OCR (works on scanned PDFs, supports Arabic)&lt;/li&gt;
&lt;li&gt;Sign, protect with password, redact sensitive info&lt;/li&gt;
&lt;li&gt;Watermark, page numbers, header &amp;amp; footer&lt;/li&gt;
&lt;li&gt;And more&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React + TypeScript + Vite&lt;/strong&gt; — frontend framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pdf-lib&lt;/strong&gt; — PDF creation and manipulation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF.js&lt;/strong&gt; — PDF rendering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tesseract.js&lt;/strong&gt; — in-browser OCR&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mammoth&lt;/strong&gt; — DOCX conversion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Pages&lt;/strong&gt; — hosting and edge delivery&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Interesting Challenges
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;OCR performance:&lt;/strong&gt; Tesseract.js runs in a Web Worker to avoid &lt;br&gt;
blocking the UI. Large scanned PDFs can take a while — showing &lt;br&gt;
progress without freezing the page took some work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bundle size:&lt;/strong&gt; Initial bundle was 648KB. After splitting &lt;br&gt;
translations into 19 per-language chunks and lazy-loading all &lt;br&gt;
tool pages, it's now 58KB — a 91% reduction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PDF.js worker:&lt;/strong&gt; Each page that uses PDF.js needs the worker &lt;br&gt;
configured. Ended up creating a shared &lt;code&gt;pdfjsWorker.ts&lt;/code&gt; that &lt;br&gt;
exports the pre-configured library.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;More tools based on user feedback&lt;/li&gt;
&lt;li&gt;Improve mobile experience&lt;/li&gt;
&lt;li&gt;Performance improvements for large files&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Happy to answer questions about the architecture or any specific &lt;br&gt;
implementation details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://opdf.io" rel="noopener noreferrer"&gt;https://opdf.io&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
