<?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: Anuj Kabra</title>
    <description>The latest articles on DEV Community by Anuj Kabra (@glinck).</description>
    <link>https://dev.to/glinck</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%2F4187667%2F3db58725-6cb8-408f-bacb-8a1fc2c6f50b.jpg</url>
      <title>DEV Community: Anuj Kabra</title>
      <link>https://dev.to/glinck</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/glinck"/>
    <language>en</language>
    <item>
      <title>Getting a PDF under 100 KB without turning the text into a picture</title>
      <dc:creator>Anuj Kabra</dc:creator>
      <pubDate>Fri, 16 Oct 2026 04:25:48 +0000</pubDate>
      <link>https://dev.to/glinck/getting-a-pdf-under-100-kb-without-turning-the-text-into-a-picture-586k</link>
      <guid>https://dev.to/glinck/getting-a-pdf-under-100-kb-without-turning-the-text-into-a-picture-586k</guid>
      <description>&lt;p&gt;The form said "PDF, maximum 100 KB". My file was a one-page letter exported from Word, and it was several times that. I ran it through the first online compressor I found, got a file under the limit, and only noticed later that I couldn't select a single word in it. The compressor had turned my page into a JPEG.&lt;/p&gt;

&lt;p&gt;That's the trade-off nobody mentions on the button. Here's how I think about it now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the unit
&lt;/h2&gt;

&lt;p&gt;"100 KB" can mean two different numbers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100 × 1024 = &lt;strong&gt;102,400 bytes&lt;/strong&gt; (the binary meaning)&lt;/li&gt;
&lt;li&gt;100 × 1000 = &lt;strong&gt;100,000 bytes&lt;/strong&gt; (the decimal meaning)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your file manager may not agree with the form either. Windows Explorer counts 1 KB as 1024 bytes. macOS Finder counts 1 KB as 1000 bytes. So the same file can look like "99 KB" on one machine and "101 KB" on another.&lt;/p&gt;

&lt;p&gt;Don't trust the rounded number. Look at the exact byte count:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Windows: right-click &amp;gt; Properties. The "Size" line shows the bytes in brackets.&lt;/li&gt;
&lt;li&gt;macOS: Get Info shows the byte count next to the size.&lt;/li&gt;
&lt;li&gt;Terminal: &lt;code&gt;ls -l file.pdf&lt;/code&gt; or &lt;code&gt;stat file.pdf&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're under 100,000 bytes, you pass under either meaning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a PDF is big in the first place
&lt;/h2&gt;

&lt;p&gt;Before compressing anything, it helps to know what's taking the space. Usually it's one of these:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Images.&lt;/strong&gt; A logo pasted at 3000 pixels wide and then shrunk on the page still carries all 3000 pixels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scans.&lt;/strong&gt; A scanned page is a photograph inside a PDF. That's a different problem (I wrote it up separately for scans and the 200 KB limit).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fonts.&lt;/strong&gt; Fully embedded fonts can add a lot, especially with several typefaces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leftovers.&lt;/strong&gt; Metadata, thumbnails and editing history from the app that made the file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have poppler installed, this one command shows every embedded image and its pixel size:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pdfimages &lt;span class="nt"&gt;-list&lt;/span&gt; letter.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A single row with a width in the thousands is usually your culprit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two ways a compressor can shrink a PDF
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Lossless rewrite.&lt;/strong&gt; Strip metadata, drop unused objects, pack the structure tighter. The text stays text. You can still select it, search it, and copy it. For a typed letter this often gets you under 100 KB on its own.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rasterise.&lt;/strong&gt; Draw each page as an image and save it as JPEG at whatever quality fits. This always "works" on size, which is why so many compressors do it. But the result is a picture of your document. No text selection, no search, and small print gets blurry. For a scan that's fine, because it was a picture anyway. For a text document it's a quiet downgrade.&lt;/p&gt;

&lt;p&gt;The compressor I first used picked option two without telling me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fix it at the source if you can
&lt;/h2&gt;

&lt;p&gt;The best compression is not making the big file at all.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Word on Windows:&lt;/strong&gt; File &amp;gt; Save As &amp;gt; PDF, then under "Optimize for" pick "Minimum size (publishing online)".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Images in the document:&lt;/strong&gt; resize them to the size they're actually shown before inserting. A logo shown 4 cm wide doesn't need to be 3000 px.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Docs:&lt;/strong&gt; File &amp;gt; Download &amp;gt; PDF usually gives a small file for text-only documents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ghostscript, if you're on a terminal
&lt;/h2&gt;

&lt;p&gt;Ghostscript can rewrite a PDF and downsample the images inside while keeping text as text:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gs &lt;span class="nt"&gt;-sDEVICE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pdfwrite &lt;span class="nt"&gt;-dPDFSETTINGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/ebook &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-dNOPAUSE&lt;/span&gt; &lt;span class="nt"&gt;-dBATCH&lt;/span&gt; &lt;span class="nt"&gt;-dQUIET&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
   &lt;span class="nt"&gt;-sOutputFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;letter-small.pdf letter.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;/ebook&lt;/code&gt; downsamples images to about 150 dpi. &lt;code&gt;/screen&lt;/code&gt; goes lower (about 72 dpi) and gets visibly rough. Text stays selectable either way. The downside: you have to try settings and check the size yourself, and Ghostscript doesn't aim for a target.&lt;/p&gt;

&lt;p&gt;On a Mac, Preview's File &amp;gt; Export with the "Reduce File Size" filter is built in, but it's aggressive with images and gives you no control over the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  A page that tries lossless first and tells you what happened
&lt;/h2&gt;

&lt;p&gt;I wanted something that aimed at a number and was honest about the method, so I made &lt;a href="https://toolocean.co/compress-pdf-to-100kb" rel="noopener noreferrer"&gt;a compress-to-100 KB page&lt;/a&gt; on ToolOcean. (Disclosure: I make ToolOcean, so weigh that.) It runs in the browser, so the PDF stays on your machine.&lt;/p&gt;

&lt;p&gt;What it does:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The ceiling is preset to 100 KB, and it means 102,400 bytes. The page says so next to the control.&lt;/li&gt;
&lt;li&gt;It tries the lossless rewrite first. If that fits, you get a file where the text is still selectable.&lt;/li&gt;
&lt;li&gt;Only if lossless can't fit does it redraw the pages as JPEG. The result note says which path ran, so you know whether you're sending text or pictures.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the page's own test file, a one-page Helvetica letter, the lossless path came out at 860 bytes. A real letter with a logo will be bigger, but it shows how small a text PDF can be when nothing heavy is inside.&lt;/p&gt;

&lt;p&gt;If the note says the pages were rasterised and the document is something you'll need to search later (a contract, an offer letter), keep the original and send the small copy only where the form demands it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When nothing gets it under the limit
&lt;/h2&gt;

&lt;p&gt;If lossless doesn't fit and you don't want pictures, the content itself is too heavy for 100 KB. Things to try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove the image that's causing it, or replace it with a smaller version, and re-export.&lt;/li&gt;
&lt;li&gt;Split the document and upload only the pages the form asks for.&lt;/li&gt;
&lt;li&gt;Check whether the form takes a JPG instead. A single page as a JPEG at the right pixel size is often easier to fit than a PDF.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The gotcha
&lt;/h2&gt;

&lt;p&gt;A file that Windows Explorer shows as "99 KB" is roughly 99 × 1024, about 101,000 bytes. That passes a form that counts 1 KB as 1024 bytes and fails one that counts 1000. When a form rejects a file that looks under the limit, this is usually why. If the limit is tight, aim for 95 KB and stop arguing with the unit.&lt;/p&gt;

&lt;p&gt;Drafted with AI help, tested and checked by me.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My bank statement PDF has a password. Here's how I remove it without uploading the statement anywhere</title>
      <dc:creator>Anuj Kabra</dc:creator>
      <pubDate>Fri, 16 Oct 2026 01:58:27 +0000</pubDate>
      <link>https://dev.to/glinck/my-bank-statement-pdf-has-a-password-heres-how-i-remove-it-without-uploading-the-statement-3clh</link>
      <guid>https://dev.to/glinck/my-bank-statement-pdf-has-a-password-heres-how-i-remove-it-without-uploading-the-statement-3clh</guid>
      <description>&lt;p&gt;Every month my bank emails me a statement as a password-protected PDF. That's fine until I need to do something with it: forward it to whoever files my taxes, attach three months of them to a loan application, or merge them into one file. At that point the password is in the way, and every "remove PDF password" site I found wanted me to upload the statement first.&lt;/p&gt;

&lt;p&gt;A bank statement is about the last file I want sitting on someone else's server. So here's what I actually do now, plus the built-in options and the one thing none of them will do.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, figure out which kind of password it is
&lt;/h2&gt;

&lt;p&gt;PDFs have two different passwords, and they behave very differently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open password&lt;/strong&gt; (the spec calls it the user password). The file won't show a single page until you type it. Bank statements are almost always this kind. The password format is usually explained in the email itself.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Owner password&lt;/strong&gt; (permissions). The file opens fine, but printing, copying text or editing is greyed out. You don't need to know this password to read the file, and clearing the restrictions doesn't need it either.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Quick test: double-click the file. If a password box appears before you see anything, it's an open password. If it opens but you can't print or select text, it's owner restrictions only. Some files have both.&lt;/p&gt;

&lt;p&gt;This matters because "removing the password" really means writing a new copy of the file without its encryption. To do that for an open-password file, you need the password. There's no trick around that for a modern file, which brings me to the warning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sites that "recover" passwords are guessing
&lt;/h2&gt;

&lt;p&gt;If a site offers to remove a password you don't know, it is running guesses against the file. Current PDFs are encrypted with AES, and a password that isn't trivially short isn't going to fall to a free web tool. You'd be handing over the file for nothing. If you've lost the password, ask the bank to resend the statement or tell you the format again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: the browser's print dialog
&lt;/h2&gt;

&lt;p&gt;The quickest built-in route: open the PDF in Chrome or Edge, type the password, then Print and choose "Save as PDF" as the printer. The saved copy has no password.&lt;/p&gt;

&lt;p&gt;The catch is that this re-prints the document rather than copying it. Links, bookmarks and form fields can get lost, and the file size can change a lot. If the PDF has a "no printing" restriction, the print route may be blocked. For a plain statement it's usually good enough.&lt;/p&gt;

&lt;p&gt;On a Mac, Preview can do something similar: open the file with the password, then File &amp;gt; Export as PDF and save a copy. If the copy still asks for a password, look at the encryption or permissions option in that export dialog before saving.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: qpdf, if you have a terminal
&lt;/h2&gt;

&lt;p&gt;If you're comfortable on the command line, &lt;code&gt;qpdf&lt;/code&gt; does this properly. It rewrites the file without encryption and doesn't re-render anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# put the password on the first line of a file so it stays out of shell history&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'YOURPASSWORD'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pw.txt
qpdf &lt;span class="nt"&gt;--decrypt&lt;/span&gt; &lt;span class="nt"&gt;--password-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pw.txt statement.pdf statement-clear.pdf
&lt;span class="nb"&gt;rm &lt;/span&gt;pw.txt

&lt;span class="c"&gt;# check the result&lt;/span&gt;
qpdf &lt;span class="nt"&gt;--show-encryption&lt;/span&gt; statement-clear.pdf
&lt;span class="c"&gt;# -&amp;gt; File is not encrypted&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For an owner-only file you don't need a password at all:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;qpdf &lt;span class="nt"&gt;--decrypt&lt;/span&gt; restricted.pdf restricted-clear.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;--password-file&lt;/code&gt; is in current qpdf releases. If your version is old and doesn't have it, &lt;code&gt;--password=...&lt;/code&gt; works too, but then the password lands in your shell history.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 3: a browser tool that never sends the file
&lt;/h2&gt;

&lt;p&gt;Not everyone has qpdf, and installing it on a work laptop isn't always possible. I wanted the qpdf behaviour on any machine with a browser, so I built a page for it: &lt;a href="https://toolocean.co/pdf-unlock" rel="noopener noreferrer"&gt;Remove a PDF password you know&lt;/a&gt;. The file is read by JavaScript inside the tab and the clear copy is written back to your downloads. Nothing goes to a server. (Disclosure: I make ToolOcean, so weigh that.)&lt;/p&gt;

&lt;p&gt;How it works in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose the PDF. Before anything is written, the page reports whether the file has no encryption, owner restrictions only, or needs an open password.&lt;/li&gt;
&lt;li&gt;If it needs a password, type it once and press Remove password. A wrong password is one error and stops there. There's no retry loop and no guessing, on purpose.&lt;/li&gt;
&lt;li&gt;A copy named with &lt;code&gt;-unlocked&lt;/code&gt; downloads. It opens without a prompt.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You don't have to take the "nothing is uploaded" line on trust. Open DevTools, go to the Network tab, clear it, then run the tool and look for any request the size of your file. Or load the page, turn on airplane mode, and use it offline.&lt;/p&gt;

&lt;p&gt;Things it won't do, so you're not surprised:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It won't find a password you don't have.&lt;/li&gt;
&lt;li&gt;Certificate-based PDF security (the kind tied to a digital ID) isn't supported and will fail with an error.&lt;/li&gt;
&lt;li&gt;It keeps the title and author fields. Removing the password and removing metadata are separate jobs.&lt;/li&gt;
&lt;li&gt;If the file had a certified digital signature, rewriting it breaks that signature. Keep the original if the signature is what matters.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  After the password is gone
&lt;/h2&gt;

&lt;p&gt;The clear copy is now a plain file. Anyone who gets it can read it. A few habits I've settled on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the original encrypted statement as your archive copy, and treat the clear one as temporary.&lt;/li&gt;
&lt;li&gt;Don't leave clear copies in a synced Downloads folder that half your devices can see.&lt;/li&gt;
&lt;li&gt;If you have to email it to someone, put your own password on it and send the password by a different channel (a message, a call). An encrypted PDF sent with its password in the same email protects nothing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The gotcha that sent me down this path
&lt;/h2&gt;

&lt;p&gt;I was merging statements and the merge step kept saying one file was "encrypted", even though it opened without asking for anything. That file had owner restrictions only. The merge tool I was using refused any file with an encryption dictionary, restrictions included. Clearing owner restrictions needs no password at all: run &lt;code&gt;qpdf --decrypt&lt;/code&gt; on it, or drop it on the page above, and the merge goes through.&lt;/p&gt;

&lt;p&gt;Drafted with AI help, tested and checked by me.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>security</category>
      <category>privacy</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
