<?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: Tomaz</title>
    <description>The latest articles on DEV Community by Tomaz (@tomaz_8a7b374c4dc1136233b).</description>
    <link>https://dev.to/tomaz_8a7b374c4dc1136233b</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%2F4084000%2F8ae7e4d6-ec1c-473b-9ee6-389a8ab10628.png</url>
      <title>DEV Community: Tomaz</title>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tomaz_8a7b374c4dc1136233b"/>
    <language>en</language>
    <item>
      <title>🔓 Remove PDF Password: Unlock a PDF **you have the password for** — in your browser</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Tue, 22 Sep 2026 09:25:35 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/remove-pdf-password-unlock-a-pdf-you-have-the-password-for-in-your-browser-bd4</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/remove-pdf-password-unlock-a-pdf-you-have-the-password-for-in-your-browser-bd4</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;You have a password-protected PDF &lt;strong&gt;and&lt;/strong&gt; the password. Typing it every single time you open the file is tedious. Drop it into &lt;strong&gt;&lt;a href="https://tooladda.online/pdf-password-remover.html" rel="noopener noreferrer"&gt;tooladda.online/pdf-password-remover.html&lt;/a&gt;&lt;/strong&gt;, enter the password once, download a copy without it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both the file and the password stay in your browser. Uploading an encrypted document &lt;em&gt;along with its password&lt;/em&gt; to a web service is close to the worst thing you can do with it — that's exactly the step this tool removes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚖️ What this is, and what it isn't
&lt;/h2&gt;

&lt;p&gt;Let's be completely clear, because the search term is ambiguous:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✅ &lt;strong&gt;This is&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A tool that decrypts a PDF &lt;strong&gt;using the password you supply&lt;/strong&gt; and saves an unencrypted copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌ &lt;strong&gt;This is not&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A cracker, a brute-forcer, or a way to open a file whose password you don't know&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔑 &lt;strong&gt;It needs&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The correct password. No password, no output — there's no bypass here&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Why can't it just crack it?&lt;/strong&gt; Because the content is genuinely encrypted. Without the key there is nothing to read — not "hard to read", &lt;em&gt;nothing&lt;/em&gt;. That's the entire point of encryption, and it's the same reason nobody can recover a lost password for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  The legitimate cases — which are most of them
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Why it's fine&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🏦 &lt;strong&gt;Bank statements&lt;/strong&gt; auto-locked with your DOB or PAN&lt;/td&gt;
&lt;td&gt;It's your statement and your password. Removing the lock to archive it locally is normal.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💳 &lt;strong&gt;Card statements&lt;/strong&gt; you want to search across months&lt;/td&gt;
&lt;td&gt;You can't grep a folder of files that each demand a password.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📄 &lt;strong&gt;A document you encrypted yourself&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;You set it; you can unset it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧾 &lt;strong&gt;Payslips&lt;/strong&gt; locked by your employer's payroll system&lt;/td&gt;
&lt;td&gt;Yours, and you have the password.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📚 &lt;strong&gt;A file you own&lt;/strong&gt; where the password is a daily nuisance&lt;/td&gt;
&lt;td&gt;Convenience, not circumvention.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔄 &lt;strong&gt;Preparing to merge or edit&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Most PDF tools can't process an encrypted file at all.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Removing protection from a document &lt;strong&gt;you have no right to access&lt;/strong&gt; is not something this tool enables — you still need the password. But do note that copyright and licence terms are separate from technical protection: having the password to a purchased ebook doesn't grant you the right to redistribute it. Use this on your own documents.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCflJIgRW5jcnlwdGVkIFBERlwiXSAtLT4gQntcIllvdXIgYnJvd3NlclwifVxuICAgIENbXCLwn5SRIFRoZSBwYXNzd29yZDxici8-eW91IGFscmVhZHkga25vd1wiXSAtLT4gQlxuICAgIEIgLS0-IER7XCJQYXNzd29yZCBjb3JyZWN0P1wifVxuICAgIEQgLS0-fFwibm9cInwgRVtcIuKdjCBOb3RoaW5nIGhhcHBlbnM8YnIvPuKAlCBubyBieXBhc3MgZXhpc3RzXCJdXG4gICAgRCAtLT58XCJ5ZXNcInwgRltcIkRlY3J5cHQgY29udGVudFwiXVxuICAgIEYgLS0-IEdbXCLwn5OEIFVubG9ja2VkIGNvcHk8YnIvPuKsh--4jyBkb3dubG9hZFwiXVxuICAgIEIgLS4tPnxcIvCfmqsgZmlsZSArIHBhc3N3b3JkPGJyLz5uZXZlciB0cmFuc21pdHRlZFwifCBYKChcIlNlcnZlclwiKSlcblxuICAgIHN0eWxlIEEgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBDIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQiBmaWxsOiM3ODM1MGYsc3Ryb2tlOiM0NTFhMDMsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEUgZmlsbDojZWY0NDQ0LHN0cm9rZTojYjkxYzFjLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBHIGZpbGw6IzIyYzU1ZSxzdHJva2U6IzE1ODAzZCxjb2xvcjojZmZmXG4gICAgc3R5bGUgWCBmaWxsOiMzZjNmNDYsc3Ryb2tlOiM3MTcxN2EsY29sb3I6I2ZmZixzdHJva2UtZGFzaGFycmF5OiA1IDUiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCflJIgRW5jcnlwdGVkIFBERlwiXSAtLT4gQntcIllvdXIgYnJvd3NlclwifVxuICAgIENbXCLwn5SRIFRoZSBwYXNzd29yZDxici8-eW91IGFscmVhZHkga25vd1wiXSAtLT4gQlxuICAgIEIgLS0-IER7XCJQYXNzd29yZCBjb3JyZWN0P1wifVxuICAgIEQgLS0-fFwibm9cInwgRVtcIuKdjCBOb3RoaW5nIGhhcHBlbnM8YnIvPuKAlCBubyBieXBhc3MgZXhpc3RzXCJdXG4gICAgRCAtLT58XCJ5ZXNcInwgRltcIkRlY3J5cHQgY29udGVudFwiXVxuICAgIEYgLS0-IEdbXCLwn5OEIFVubG9ja2VkIGNvcHk8YnIvPuKsh--4jyBkb3dubG9hZFwiXVxuICAgIEIgLS4tPnxcIvCfmqsgZmlsZSArIHBhc3N3b3JkPGJyLz5uZXZlciB0cmFuc21pdHRlZFwifCBYKChcIlNlcnZlclwiKSlcblxuICAgIHN0eWxlIEEgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBDIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQiBmaWxsOiM3ODM1MGYsc3Ryb2tlOiM0NTFhMDMsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEUgZmlsbDojZWY0NDQ0LHN0cm9rZTojYjkxYzFjLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBHIGZpbGw6IzIyYzU1ZSxzdHJva2U6IzE1ODAzZCxjb2xvcjojZmZmXG4gICAgc3R5bGUgWCBmaWxsOiMzZjNmNDYsc3Ryb2tlOiM3MTcxN2EsY29sb3I6I2ZmZixzdHJva2UtZGFzaGFycmF5OiA1IDUiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ%3Ftype%3Dpng" alt="Diagram" width="1294" height="318"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔒 Password stays local
The one operation where "no upload" is not a nice-to-have. Your document and its key never appear in the same request to anyone.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🪶 Content untouched
Decryption doesn't re-render anything. Text stays selectable, images keep their quality, page count and layout are identical.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔧 Makes other tools work
Merging, splitting and compressing all fail on encrypted files. Unlock first, then the rest of the toolkit works normally.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🚫 No account, no log
Nothing recorded about which files you unlocked or what the passwords were.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/pdf-password-remover.html
2.  Drop   →  your encrypted PDF
3.  Enter  →  the correct password
4.  Download→ the unlocked copy (keep the original too)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Unlock now — tooladda.online/pdf-password-remover.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once it's unlocked, that file is &lt;strong&gt;unprotected&lt;/strong&gt;. If it's a bank statement or a payslip, store the unlocked copy somewhere your device already protects — an encrypted disk or a locked folder — rather than a shared drive or a Downloads folder you sync everywhere.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, no watermark.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can it open a PDF if I don't know the password?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. The content is encrypted — without the key there's nothing to decrypt. Any site claiming otherwise for a strong password is either doing something else or misleading you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is my file or password uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Both stay in your browser, which is the only sensible way to do this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it legal to remove a password from my own bank statement?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Removing protection from a document you're entitled to access, using the password you were given, is ordinary use. Redistribution rights are a separate matter governed by copyright and licence terms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the quality change?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Decryption doesn't re-encode anything — the pages are identical.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why won't my other PDF tools accept the file?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because it's encrypted. Unlock it here first, then merge, split or compress as normal.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Decryption performed client-side in vanilla JavaScript with the password you supply; no upload endpoint exists.&lt;/li&gt;
&lt;li&gt;Page content is copied rather than re-rendered, so the output is byte-faithful apart from the removed encryption.&lt;/li&gt;
&lt;li&gt;No password is stored, logged or persisted anywhere.&lt;/li&gt;
&lt;li&gt;Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/pdf-password-remover.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Remove PDF Password runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>🔒 Protect PDF: Encrypt with a password — locally, so the file never travels</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Mon, 21 Sep 2026 10:08:34 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/protect-pdf-encrypt-with-a-password-locally-so-the-file-never-travels-48da</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/protect-pdf-encrypt-with-a-password-locally-so-the-file-never-travels-48da</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Drop the PDF into &lt;strong&gt;&lt;a href="https://tooladda.online/pdf-password-protector.html" rel="noopener noreferrer"&gt;tooladda.online/pdf-password-protector.html&lt;/a&gt;&lt;/strong&gt;, set a password, download the encrypted file. Neither the document nor the password ever leaves your browser.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think about what an online "protect PDF" service actually receives: &lt;strong&gt;your confidential document and the password you chose for it&lt;/strong&gt;, together, in one request. That's the whole reason this runs client-side.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔑 Two different passwords — and only one of them is real security
&lt;/h2&gt;

&lt;p&gt;Every PDF supports two, they do completely different things, and confusing them is the commonest mistake here.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;User password&lt;/strong&gt; (open password)&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;Owner password&lt;/strong&gt; (permissions password)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Needed to&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Open the file at all&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Change the restrictions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content encrypted?&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Yes&lt;/strong&gt; — the bytes are unreadable without it&lt;/td&gt;
&lt;td&gt;⚠️ Content is encrypted with a &lt;em&gt;known&lt;/em&gt; empty user password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blocks reading&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No — the file opens freely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blocks printing / copying&lt;/td&gt;
&lt;td&gt;Via permissions, once open&lt;/td&gt;
&lt;td&gt;Supposed to — but &lt;strong&gt;only advisory&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforced by&lt;/td&gt;
&lt;td&gt;Cryptography&lt;/td&gt;
&lt;td&gt;The &lt;strong&gt;honour system&lt;/strong&gt; of the PDF reader&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permissions are advisory.&lt;/strong&gt; "Do not allow printing" and "do not allow copying" are flags in the file that a well-behaved reader chooses to respect. Plenty of readers and libraries simply ignore them, and there is no cryptography stopping them. If content must not be extracted, an owner password will not achieve that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Only the user password provides actual protection.&lt;/strong&gt; If it matters, set a user password.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  And the password is the whole security
&lt;/h3&gt;

&lt;p&gt;Encryption strength is irrelevant if the password is &lt;code&gt;invoice2024&lt;/code&gt;. The file's protection is exactly as strong as the password, and an attacker with the file can guess offline at whatever rate their hardware allows — no rate limiting, no lockout.&lt;/p&gt;

&lt;p&gt;Use the password generator for something with real entropy, and — this matters — &lt;strong&gt;send the password through a different channel than the file&lt;/strong&gt;. Emailing an encrypted PDF and its password in the same thread protects you from nothing at all.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBDW1wi8J-UkSBQYXNzd29yZFwiXSAtLT4gQlxuICAgIEIgLS0-IER7XCJXaGljaCBwYXNzd29yZD9cIn1cbiAgICBEIC0tPnxcInVzZXJcInwgRVtcIvCflJIgRmlsZSBjYW4ndCBvcGVuPGJyLz53aXRob3V0IGl0IOKAlCByZWFsXCJdXG4gICAgRCAtLT58XCJvd25lclwifCBGW1wi4pqg77iPIFBlcm1pc3Npb25zIG9ubHk8YnIvPuKAlCBhZHZpc29yeVwiXVxuICAgIEUgLS0-IEdbXCLwn5OEIEVuY3J5cHRlZCBQREZcIl1cbiAgICBGIC0tPiBHXG4gICAgQiAtLi0-fFwi8J-aqyBmaWxlIEFORCBwYXNzd29yZDxici8-bmV2ZXIgdHJhbnNtaXR0ZWRcInwgWCgoXCJTZXJ2ZXJcIikpXG5cbiAgICBzdHlsZSBBIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQyBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojNGMxZDk1LHN0cm9rZTojMmUxMDY1LGNvbG9yOiNmZmZcbiAgICBzdHlsZSBFIGZpbGw6IzIyYzU1ZSxzdHJva2U6IzE1ODAzZCxjb2xvcjojZmZmXG4gICAgc3R5bGUgRiBmaWxsOiNmNTllMGIsc3Ryb2tlOiNiNDUzMDksY29sb3I6IzAwMFxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBDW1wi8J-UkSBQYXNzd29yZFwiXSAtLT4gQlxuICAgIEIgLS0-IER7XCJXaGljaCBwYXNzd29yZD9cIn1cbiAgICBEIC0tPnxcInVzZXJcInwgRVtcIvCflJIgRmlsZSBjYW4ndCBvcGVuPGJyLz53aXRob3V0IGl0IOKAlCByZWFsXCJdXG4gICAgRCAtLT58XCJvd25lclwifCBGW1wi4pqg77iPIFBlcm1pc3Npb25zIG9ubHk8YnIvPuKAlCBhZHZpc29yeVwiXVxuICAgIEUgLS0-IEdbXCLwn5OEIEVuY3J5cHRlZCBQREZcIl1cbiAgICBGIC0tPiBHXG4gICAgQiAtLi0-fFwi8J-aqyBmaWxlIEFORCBwYXNzd29yZDxici8-bmV2ZXIgdHJhbnNtaXR0ZWRcInwgWCgoXCJTZXJ2ZXJcIikpXG5cbiAgICBzdHlsZSBBIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQyBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojNGMxZDk1LHN0cm9rZTojMmUxMDY1LGNvbG9yOiNmZmZcbiAgICBzdHlsZSBFIGZpbGw6IzIyYzU1ZSxzdHJva2U6IzE1ODAzZCxjb2xvcjojZmZmXG4gICAgc3R5bGUgRiBmaWxsOiNmNTllMGIsc3Ryb2tlOiNiNDUzMDksY29sb3I6IzAwMFxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" alt="Diagram" width="1296" height="321"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔐 Real encryption, done locally
The PDF is genuinely encrypted in your browser. No upload means no window where your document and its password sit together on someone else's machine.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🎛️ Permission flags
Set print, copy and edit restrictions — with an honest note that readers may ignore them, which most tools won't tell you.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔑 Both password types explained
Choose deliberately between "can't open" and "can open but restricted", instead of picking whichever box appeared first.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🚫 Nothing stored
No account, no history of protected files, no copy of your password anywhere.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Which password&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🏦 &lt;strong&gt;Emailing a bank statement&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;User password — must not open without it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📄 &lt;strong&gt;Sending an offer letter&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;User password, shared over a different channel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧾 &lt;strong&gt;Invoice to a client&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Usually none; owner password at most&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📚 &lt;strong&gt;Paid course material&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;User password per buyer (accepting that it can be shared onward)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🏥 &lt;strong&gt;Medical records&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;User password, strong, out-of-band&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💾 &lt;strong&gt;Archiving something sensitive&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;User password, stored in your password manager&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/pdf-password-protector.html
2.  Drop   →  your PDF
3.  Set    →  a USER password (strong, from a generator)
4.  Send   →  the file one way, the password another way
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Protect now — tooladda.online/pdf-password-protector.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Save the password before you close the tab.&lt;/strong&gt; There is no recovery, no reset link, and no support desk that can open the file for you — that's what encryption means. Keep an unencrypted original somewhere safe, or store the password in a manager.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, no watermark, no file-size limit beyond your device's memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is my file or password uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Neither. Both stay in your browser — the only safe arrangement for this particular operation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User password or owner password?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;User password if the content must be protected. An owner password only sets advisory restrictions and doesn't stop anyone reading the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can "disable printing" be bypassed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. Permissions rely on the reader choosing to honour them, and many don't. Only the user password is enforced cryptographically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I forgot the password. Can you recover it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Nobody can. Keep an unencrypted original and store the password in a manager.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I remove protection later?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With the password remover — using the correct password. It's a remover, not a cracker.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PDF encryption applied client-side in vanilla JavaScript; no upload endpoint exists.&lt;/li&gt;
&lt;li&gt;Both user and owner passwords supported, with permission flags settable independently.&lt;/li&gt;
&lt;li&gt;Nothing persisted: no history, no localStorage of passwords.&lt;/li&gt;
&lt;li&gt;Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/pdf-password-protector.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Protect PDF runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>💧 Watermark PDF: Text or logo, tiled or single, with a live preview</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Sun, 20 Sep 2026 09:24:13 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/watermark-pdf-text-or-logo-tiled-or-single-with-a-live-preview-2eil</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/watermark-pdf-text-or-logo-tiled-or-single-with-a-live-preview-2eil</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Add &lt;strong&gt;CONFIDENTIAL&lt;/strong&gt;, &lt;strong&gt;DRAFT&lt;/strong&gt;, a client name or your logo across every page — or just page one — at &lt;strong&gt;&lt;a href="https://tooladda.online/pdf-watermark.html" rel="noopener noreferrer"&gt;tooladda.online/pdf-watermark.html&lt;/a&gt;&lt;/strong&gt;. Live preview, so you see the result before you commit.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ironically, the tools that add "CONFIDENTIAL" watermarks usually want you to upload the confidential document first. This one doesn't — the whole thing runs in your browser.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚠️ A watermark is a deterrent, not a lock
&lt;/h2&gt;

&lt;p&gt;Worth being blunt about, because people rely on this wrongly:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A watermark &lt;strong&gt;does&lt;/strong&gt;
&lt;/th&gt;
&lt;th&gt;A watermark &lt;strong&gt;does not&lt;/strong&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Signal status — draft, confidential, internal&lt;/td&gt;
&lt;td&gt;Prevent copying, printing or forwarding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deter casual reuse of a photo or design&lt;/td&gt;
&lt;td&gt;Stop anyone determined from removing it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Make a leak traceable if you personalise it per recipient&lt;/td&gt;
&lt;td&gt;Encrypt or protect the content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discourage passing a draft off as final&lt;/td&gt;
&lt;td&gt;Survive a screenshot-and-crop&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A visible watermark over content can be edited out with ordinary tools. If you need the content &lt;strong&gt;actually protected&lt;/strong&gt;, that's password encryption; if you need information &lt;strong&gt;removed&lt;/strong&gt;, that's redaction. A watermark is a label.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The one thing that genuinely works:&lt;/strong&gt; watermark each copy with the &lt;strong&gt;recipient's name&lt;/strong&gt;. It doesn't prevent a leak, but it tells you exactly who leaked it — and people behave differently when they know their name is on the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the settings right
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;The mistake&lt;/th&gt;
&lt;th&gt;Do this instead&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Opacity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;80% — unreadable document&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;10–20%&lt;/strong&gt; for body pages; you should be able to read the text through it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rotation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0° — reads like a heading and gets mistaken for content&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;45°&lt;/strong&gt; diagonal, unmistakably an overlay&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tiling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single small mark, easily cropped out&lt;/td&gt;
&lt;td&gt;Tile it for high-security drafts; single centred mark for a light "DRAFT" label&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Colour&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Black — fights the text&lt;/td&gt;
&lt;td&gt;Mid-grey or a light brand tint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Placement&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Over a signature or a figure&lt;/td&gt;
&lt;td&gt;Diagonal across the middle, where it overlaps text but hides nothing critical&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBDW1wi4pyP77iPIFRleHQgb3Ig8J-WvO-4jyBsb2dvXCJdIC0tPiBCXG4gICAgQiAtLT4gRFtcIk9wYWNpdHkgwrcgcm90YXRpb248YnIvPnNpemUgwrcgY29sb3VyXCJdXG4gICAgRCAtLT4gRXtcIkNvdmVyYWdlXCJ9XG4gICAgRSAtLT58XCJsaWdodCBsYWJlbFwifCBGW1wiU2luZ2xlIGNlbnRyZWRcIl1cbiAgICBFIC0tPnxcImhpZ2ggc2VjdXJpdHlcInwgR1tcIlRpbGVkIGFjcm9zcyBwYWdlXCJdXG4gICAgRiAtLT4gSFtcIvCfkYHvuI8gTGl2ZSBwcmV2aWV3XCJdXG4gICAgRyAtLT4gSFxuICAgIEggLS0-IElbXCLwn5OEIFdhdGVybWFya2VkIFBERlwiXVxuICAgIEIgLS4tPnxcIvCfmqsgbm8gdXBsb2FkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEMgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzBjNGE2ZSxzdHJva2U6IzA4MmY0OSxjb2xvcjojZmZmXG4gICAgc3R5bGUgSCBmaWxsOiMzOGJkZjgsc3Ryb2tlOiMwMjg0YzcsY29sb3I6IzAwMFxuICAgIHN0eWxlIEkgZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBYIGZpbGw6IzNmM2Y0NixzdHJva2U6IzcxNzE3YSxjb2xvcjojZmZmLHN0cm9rZS1kYXNoYXJyYXk6IDUgNSIsIm1lcm1haWQiOnsidGhlbWUiOiJkYXJrIn19%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBDW1wi4pyP77iPIFRleHQgb3Ig8J-WvO-4jyBsb2dvXCJdIC0tPiBCXG4gICAgQiAtLT4gRFtcIk9wYWNpdHkgwrcgcm90YXRpb248YnIvPnNpemUgwrcgY29sb3VyXCJdXG4gICAgRCAtLT4gRXtcIkNvdmVyYWdlXCJ9XG4gICAgRSAtLT58XCJsaWdodCBsYWJlbFwifCBGW1wiU2luZ2xlIGNlbnRyZWRcIl1cbiAgICBFIC0tPnxcImhpZ2ggc2VjdXJpdHlcInwgR1tcIlRpbGVkIGFjcm9zcyBwYWdlXCJdXG4gICAgRiAtLT4gSFtcIvCfkYHvuI8gTGl2ZSBwcmV2aWV3XCJdXG4gICAgRyAtLT4gSFxuICAgIEggLS0-IElbXCLwn5OEIFdhdGVybWFya2VkIFBERlwiXVxuICAgIEIgLS4tPnxcIvCfmqsgbm8gdXBsb2FkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEMgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzBjNGE2ZSxzdHJva2U6IzA4MmY0OSxjb2xvcjojZmZmXG4gICAgc3R5bGUgSCBmaWxsOiMzOGJkZjgsc3Ryb2tlOiMwMjg0YzcsY29sb3I6IzAwMFxuICAgIHN0eWxlIEkgZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBYIGZpbGw6IzNmM2Y0NixzdHJva2U6IzcxNzE3YSxjb2xvcjojZmZmLHN0cm9rZS1kYXNoYXJyYXk6IDUgNSIsIm1lcm1haWQiOnsidGhlbWUiOiJkYXJrIn19%3Ftype%3Dpng" alt="Diagram" width="1719" height="246"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 👁️ Live preview
Adjust opacity and rotation and watch the actual page update. Watermarking blind and re-doing it three times is the normal experience elsewhere.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🖼️ Text **or** image
Type a label, or drop in a PNG logo with transparency for proper branded output.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔲 Tiling and page selection
Cover the whole page in a repeating mark, or apply to page 1 only — first-page-only is right for a cover label.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🎛️ Full transform control
Opacity, rotation, scale, colour and position, all adjustable rather than three fixed presets.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;📝 &lt;strong&gt;Circulating a draft&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"DRAFT" — 15% opacity, 45°, single centred&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🤝 &lt;strong&gt;Sending a proposal to a client&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Your logo, low opacity, footer position&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 &lt;strong&gt;Sharing an internal report&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"CONFIDENTIAL — ", tiled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📸 &lt;strong&gt;Protecting a design portfolio&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Studio name tiled at low opacity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎓 &lt;strong&gt;Sample papers or course material&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"SAMPLE" diagonal so it can't be resold as the real thing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📄 &lt;strong&gt;Marking superseded documents&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"SUPERSEDED" so nobody works from the old version&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/pdf-watermark.html
2.  Drop   →  your PDF
3.  Set    →  text or logo, 10-20% opacity, 45° rotation
4.  Check  →  the live preview, then download
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Add a watermark — tooladda.online/pdf-watermark.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keep the &lt;strong&gt;unwatermarked original&lt;/strong&gt;. Watermarking writes a new file and the mark is baked into the page content — there's no undo, so treat the watermarked copy as a distribution artefact rather than your master.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Watermark on the watermarker?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, and no — the only mark on your PDF is the one you asked for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is my document uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Which matters a lot for a tool people reach for specifically to mark documents confidential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can someone remove my watermark?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, with enough effort — a visible overlay is always removable. Use it as a label and a deterrent, not as protection. For real protection, encrypt the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What opacity should I use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;10–20% on body pages. If you can't comfortably read the text underneath, it's too strong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use my logo with transparency?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — a PNG with an alpha channel composites properly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I watermark only some pages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, page selection is supported. First page only is common for cover labels.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Watermark drawn as real PDF content in vanilla JavaScript, client-side — no server round-trip.&lt;/li&gt;
&lt;li&gt;Text watermarks stay vector (crisp at any zoom); image watermarks composite with their alpha channel.&lt;/li&gt;
&lt;li&gt;Live preview renders the actual output page rather than an approximation.&lt;/li&gt;
&lt;li&gt;Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/pdf-watermark.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Watermark PDF runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>📑 Extract PDF Pages: Pull out the pages you need — or pull out the text</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Sat, 19 Sep 2026 08:54:16 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/extract-pdf-pages-pull-out-the-pages-you-need-or-pull-out-the-text-2i9l</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/extract-pdf-pages-pull-out-the-pages-you-need-or-pull-out-the-text-2i9l</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Two different jobs, one tool at &lt;strong&gt;&lt;a href="https://tooladda.online/pdf-extract.html" rel="noopener noreferrer"&gt;tooladda.online/pdf-extract.html&lt;/a&gt;&lt;/strong&gt;: extract &lt;strong&gt;pages&lt;/strong&gt; into a smaller PDF, or extract the &lt;strong&gt;text&lt;/strong&gt; as plain text you can paste anywhere.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extraction runs in your browser. Useful when the document is a contract or a report you have no business uploading to a free web service.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 "Extract" means two different things — know which one you need
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You want&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;th&gt;You get&lt;/th&gt;
&lt;th&gt;Text still selectable?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pages 12–18 as their own PDF&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Page extraction&lt;/td&gt;
&lt;td&gt;A new PDF, byte-identical pages&lt;/td&gt;
&lt;td&gt;✅ Yes — pages are copied, not re-rendered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;The words, to paste into a doc&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Text extraction&lt;/td&gt;
&lt;td&gt;Plain text&lt;/td&gt;
&lt;td&gt;n/a — it &lt;em&gt;is&lt;/em&gt; text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A picture of the pages&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;PDF to Images&lt;/td&gt;
&lt;td&gt;PNG/JPEG&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Page extraction here is &lt;strong&gt;lossless&lt;/strong&gt;: the page objects are copied into a new document, so fonts, images and vector art come across untouched and the file size stays proportional. Nothing is rasterised.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why text extraction sometimes returns nothing
&lt;/h3&gt;

&lt;p&gt;This catches everyone once. There are two kinds of PDF:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Digital PDF&lt;/strong&gt; — exported from Word, a browser, or a report generator. It contains a real text layer. Extraction works perfectly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scanned PDF&lt;/strong&gt; — a photo or scan of paper. There is &lt;strong&gt;no text layer at all&lt;/strong&gt;, just an image of words. Extraction returns empty, and that's not a bug — there is genuinely nothing there to extract.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Five-second test:&lt;/strong&gt; open the PDF, &lt;code&gt;Ctrl+A&lt;/code&gt;, &lt;code&gt;Ctrl+C&lt;/code&gt;, paste into Notepad. Blank means it's a scan, and you need OCR rather than extraction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two more things that surprise people
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Text comes out in a jumbled order&lt;/td&gt;
&lt;td&gt;Multi-column layouts. A PDF stores text in drawing order, not reading order, so columns interleave.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ligatures come out mangled (&lt;code&gt;ﬁ&lt;/code&gt;, &lt;code&gt;ﬂ&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;The font mapped a glyph pair to one character. Search-and-replace them after pasting.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Table structure disappears&lt;/td&gt;
&lt;td&gt;PDFs have no concept of a table — just text at coordinates. The alignment was visual, not structural.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDe1wiV2hhdCBkbyB5b3UgbmVlZD9cIn1cbiAgICBDIC0tPnxcInBhZ2VzXCJ8IERbXCJSYW5nZTogMS0zLCA5LCAyMC1cIl1cbiAgICBDIC0tPnxcIndvcmRzXCJ8IEVbXCJSZWFkIHRleHQgbGF5ZXJcIl1cbiAgICBEIC0tPiBGW1wi8J-ThCBOZXcgUERGPGJyLz5sb3NzbGVzcyBjb3B5XCJdXG4gICAgRSAtLT4gR3tcIlRleHQgbGF5ZXIgcHJlc2VudD9cIn1cbiAgICBHIC0tPnxcInllc1wifCBIW1wi8J-TiyBQbGFpbiB0ZXh0IG91dFwiXVxuICAgIEcgLS0-fFwibm8g4oCUIGl0J3MgYSBzY2FuXCJ8IElbXCLimqDvuI8gTmVlZHMgT0NSXCJdXG4gICAgQiAtLi0-fFwi8J-aqyBubyB1cGxvYWRcInwgWCgoXCJTZXJ2ZXJcIikpXG5cbiAgICBzdHlsZSBBIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQiBmaWxsOiM3ZjFkMWQsc3Ryb2tlOiM0NTBhMGEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEYgZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBIIGZpbGw6IzIyYzU1ZSxzdHJva2U6IzE1ODAzZCxjb2xvcjojZmZmXG4gICAgc3R5bGUgSSBmaWxsOiNlZjQ0NDQsc3Ryb2tlOiNiOTFjMWMsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDe1wiV2hhdCBkbyB5b3UgbmVlZD9cIn1cbiAgICBDIC0tPnxcInBhZ2VzXCJ8IERbXCJSYW5nZTogMS0zLCA5LCAyMC1cIl1cbiAgICBDIC0tPnxcIndvcmRzXCJ8IEVbXCJSZWFkIHRleHQgbGF5ZXJcIl1cbiAgICBEIC0tPiBGW1wi8J-ThCBOZXcgUERGPGJyLz5sb3NzbGVzcyBjb3B5XCJdXG4gICAgRSAtLT4gR3tcIlRleHQgbGF5ZXIgcHJlc2VudD9cIn1cbiAgICBHIC0tPnxcInllc1wifCBIW1wi8J-TiyBQbGFpbiB0ZXh0IG91dFwiXVxuICAgIEcgLS0-fFwibm8g4oCUIGl0J3MgYSBzY2FuXCJ8IElbXCLimqDvuI8gTmVlZHMgT0NSXCJdXG4gICAgQiAtLi0-fFwi8J-aqyBubyB1cGxvYWRcInwgWCgoXCJTZXJ2ZXJcIikpXG5cbiAgICBzdHlsZSBBIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQiBmaWxsOiM3ZjFkMWQsc3Ryb2tlOiM0NTBhMGEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEYgZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBIIGZpbGw6IzIyYzU1ZSxzdHJva2U6IzE1ODAzZCxjb2xvcjojZmZmXG4gICAgc3R5bGUgSSBmaWxsOiNlZjQ0NDQsc3Ryb2tlOiNiOTFjMWMsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" alt="Diagram" width="1566" height="355"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🪶 Lossless page extraction
Pages are copied, not re-rendered. Quality, fonts and selectable text all survive, and a 40-page extract from a 400-page file takes a second.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 📋 Text extraction too
Get the words out without a Word conversion round-trip that mangles the formatting anyway.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🎯 Flexible ranges
`1-3, 9, 20-` in one go. Both ends of a range are inclusive, and the thumbnails let you confirm before you commit.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🔒 Nothing leaves the tab
No upload endpoint exists, so a confidential document stays confidential by construction.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What you do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;📤 &lt;strong&gt;Portal wants only the relevant section&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Extract those pages instead of uploading 300.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📋 &lt;strong&gt;Quoting from a report&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Pull the text out and paste it without retyping.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 &lt;strong&gt;Sharing part of a document&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Send pages 4–9 and nothing else.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📚 &lt;strong&gt;One chapter from an ebook PDF&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Extract to its own file for reading on a tablet.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧾 &lt;strong&gt;One invoice from a batch&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Pull the single page you need to forward.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔍 &lt;strong&gt;Searching a long PDF offline&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Extract the text and grep it.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/pdf-extract.html
2.  Drop   →  your PDF
3.  Choose →  page range (e.g. 12-18, 25) or text extraction
4.  Verify →  thumbnails / the extracted text, then download
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Extract now — tooladda.online/pdf-extract.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check the &lt;strong&gt;physical&lt;/strong&gt; page positions in the thumbnails, not the numbers printed on the page. A cover plus roman-numeral front matter means "page 1" often sits at position 4, and that's how people extract the wrong seven pages.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no watermark, no signup, no page limit beyond your device's memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does extraction reduce quality?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Page extraction copies the original page objects — it's lossless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text extraction returned nothing. Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your PDF is a scan with no text layer. Test it by trying to select text in a viewer — if you can't, there's nothing to extract and you need OCR.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is the extracted text out of order?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Multi-column layouts. PDFs store text in drawing order rather than reading order, so columns interleave. Single-column documents extract cleanly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is &lt;code&gt;12-18&lt;/code&gt; seven pages?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — both ends are inclusive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extract vs split — what's the difference?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extract pulls a selection into one new file. Split is built for breaking a document into many files — every page, or every N pages.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Client-side page-object copying, so extraction is lossless and fast; no rasterisation step.&lt;/li&gt;
&lt;li&gt;Text extraction reads the PDF's own text layer and reports honestly when there isn't one.&lt;/li&gt;
&lt;li&gt;No upload endpoint; works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/pdf-extract.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Extract PDF Pages runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>🏞️ PDF to Images: Any page, any DPI — JPG, PNG, WebP or AVIF</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Fri, 18 Sep 2026 09:07:25 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/pdf-to-images-any-page-any-dpi-jpg-png-webp-or-avif-3ldp</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/pdf-to-images-any-page-any-dpi-jpg-png-webp-or-avif-3ldp</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Drop a PDF into &lt;strong&gt;&lt;a href="https://tooladda.online/pdf-to-images.html" rel="noopener noreferrer"&gt;tooladda.online/pdf-to-images.html&lt;/a&gt;&lt;/strong&gt;, choose which pages and at what DPI, download the images or a ZIP. Rendering happens locally, so a 200-page document doesn't need uploading.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Contracts, statements and reports get converted here. Every page is rasterised in your browser — nothing is transmitted.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔍 DPI is the only setting that matters — pick it deliberately
&lt;/h2&gt;

&lt;p&gt;DPI decides how many pixels each page becomes. Get it wrong and you either get a blurry image or a 40 MB PNG of a text page. An A4 page is 8.27 × 11.69 inches, so:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;DPI&lt;/th&gt;
&lt;th&gt;A4 page becomes&lt;/th&gt;
&lt;th&gt;Use it for&lt;/th&gt;
&lt;th&gt;File size&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;72&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;595 × 842 px&lt;/td&gt;
&lt;td&gt;Thumbnails, contact sheets&lt;/td&gt;
&lt;td&gt;Tiny&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;96&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;794 × 1123 px&lt;/td&gt;
&lt;td&gt;On-screen preview, web embedding&lt;/td&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;150&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1240 × 1754 px&lt;/td&gt;
&lt;td&gt;🎯 &lt;strong&gt;The sensible default&lt;/strong&gt; — sharp on screen, readable text&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;300&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2480 × 3508 px&lt;/td&gt;
&lt;td&gt;Printing, OCR, archival&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;600&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;4960 × 7016 px&lt;/td&gt;
&lt;td&gt;Fine-detail print work only&lt;/td&gt;
&lt;td&gt;Very large — often 20 MB+ per page&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The rule:&lt;/strong&gt; 150 DPI unless you're printing or running OCR, in which case 300. Above 300 you're generating megabytes with no visible benefit for almost every real use.&lt;/p&gt;

&lt;h3&gt;
  
  
  And choose the format for the content
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Page content&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Text, tables, line drawings&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;PNG&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sharp edges stay sharp; JPEG smears them&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Photographs, scanned photos&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;JPEG&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Far smaller, and no visible penalty on continuous tone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web embedding&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;WebP&lt;/strong&gt; / &lt;strong&gt;AVIF&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Substantially smaller than both at equal quality&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Converting a PDF to images &lt;strong&gt;throws away the text layer&lt;/strong&gt;. The output is a picture of the words, so nothing is searchable, selectable or copyable afterwards. If you actually want the words, use Extract PDF Text instead — this tool is for when you need pixels.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDW1wiUGFnZSB0aHVtYm5haWxzPGJyLz5waWNrIHdoaWNoIHBhZ2VzXCJdXG4gICAgQyAtLT4gRFtcIkNob29zZSBEUEk8YnIvPjcyIOKGkiA2MDBcIl1cbiAgICBEIC0tPiBFe1wiRm9ybWF0XCJ9XG4gICAgRSAtLT58XCJ0ZXh0IHBhZ2VzXCJ8IEZbXCJQTkdcIl1cbiAgICBFIC0tPnxcInBob3Rvc1wifCBHW1wiSlBFR1wiXVxuICAgIEUgLS0-fFwid2ViXCJ8IEhbXCJXZWJQIC8gQVZJRlwiXVxuICAgIEYgLS0-IElbXCLirIfvuI8gRmlsZXMgb3Ig8J-XnO-4jyBaSVBcIl1cbiAgICBHIC0tPiBJXG4gICAgSCAtLT4gSVxuICAgIEIgLS4tPnxcIvCfmqsgbm8gdXBsb2FkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojODMxODQzLHN0cm9rZTojNTAwNzI0LGNvbG9yOiNmZmZcbiAgICBzdHlsZSBEIGZpbGw6I2ZiNzE4NSxzdHJva2U6I2UxMWQ0OCxjb2xvcjojZmZmXG4gICAgc3R5bGUgSSBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgWW91ciBQREZcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDW1wiUGFnZSB0aHVtYm5haWxzPGJyLz5waWNrIHdoaWNoIHBhZ2VzXCJdXG4gICAgQyAtLT4gRFtcIkNob29zZSBEUEk8YnIvPjcyIOKGkiA2MDBcIl1cbiAgICBEIC0tPiBFe1wiRm9ybWF0XCJ9XG4gICAgRSAtLT58XCJ0ZXh0IHBhZ2VzXCJ8IEZbXCJQTkdcIl1cbiAgICBFIC0tPnxcInBob3Rvc1wifCBHW1wiSlBFR1wiXVxuICAgIEUgLS0-fFwid2ViXCJ8IEhbXCJXZWJQIC8gQVZJRlwiXVxuICAgIEYgLS0-IElbXCLirIfvuI8gRmlsZXMgb3Ig8J-XnO-4jyBaSVBcIl1cbiAgICBHIC0tPiBJXG4gICAgSCAtLT4gSVxuICAgIEIgLS4tPnxcIvCfmqsgbm8gdXBsb2FkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojODMxODQzLHN0cm9rZTojNTAwNzI0LGNvbG9yOiNmZmZcbiAgICBzdHlsZSBEIGZpbGw6I2ZiNzE4NSxzdHJva2U6I2UxMWQ0OCxjb2xvcjojZmZmXG4gICAgc3R5bGUgSSBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" alt="Diagram" width="1558" height="298"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🎚️ Real DPI control
Not "low / medium / high" — an actual number, so you can hit an exact pixel size or match a print requirement.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 📑 Page selection
Convert page 7, or pages 20–35, instead of rendering all 300 and deleting the rest.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🖼️ Four output formats
PNG for text, JPEG for photos, WebP and AVIF when the images are headed for a website.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🗜️ ZIP for batches
A 60-page conversion arrives as one download instead of sixty save dialogs.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🖼️ &lt;strong&gt;Page image for a slide or blog post&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;150 DPI, PNG (or WebP for the web)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🖨️ &lt;strong&gt;Send a page to a print shop&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;300 DPI, PNG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔍 &lt;strong&gt;Feed pages into OCR&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;300 DPI, PNG — OCR accuracy depends heavily on this&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📱 &lt;strong&gt;Share a page on WhatsApp&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;150 DPI, JPEG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎨 &lt;strong&gt;Extract artwork from a brochure&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Highest DPI you need, PNG&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👀 &lt;strong&gt;Quick visual index of a long PDF&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;72 DPI, JPEG, all pages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/pdf-to-images.html
2.  Drop   →  your PDF
3.  Choose →  pages, DPI (150 default / 300 for print &amp;amp; OCR), format
4.  Export →  individual files or a ZIP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Convert now — tooladda.online/pdf-to-images.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Convert &lt;strong&gt;one page first&lt;/strong&gt; at your chosen DPI and look at it full size. Getting the setting wrong on page 1 costs a second; getting it wrong on 200 pages costs a lot of waiting and a large download.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Page limit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no watermark, no signup. The limit is your device's memory, not a plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is my PDF uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No — pages are rendered in your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What DPI should I use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;150 for screen use, 300 for printing or OCR. Above 300 mostly just makes bigger files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will the text still be selectable?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Images are pixels. For selectable text use Extract PDF Text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JPEG or PNG?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PNG for pages that are mostly text or line art; JPEG for photographic pages. JPEG artefacts cluster on sharp edges, which is exactly what text is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I get back to a PDF afterwards?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — Images to PDF. The text layer won't come back, though.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PDF rendered page-by-page onto a canvas in the browser at your requested scale; no server rasteriser.&lt;/li&gt;
&lt;li&gt;DPI maps to a canvas scale factor against the page's real point dimensions, so the pixel output is predictable.&lt;/li&gt;
&lt;li&gt;Encoding to PNG/JPEG/WebP/AVIF handled by the browser's own codecs; ZIP built client-side.&lt;/li&gt;
&lt;li&gt;Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/pdf-to-images.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where PDF to Images runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>🖼️ Images to PDF: JPG · PNG · WebP · HEIC one clean, correctly-sized PDF</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Thu, 17 Sep 2026 09:35:27 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/images-to-pdf-jpg-png-webp-heic-one-clean-correctly-sized-pdf-2ncg</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/images-to-pdf-jpg-png-webp-heic-one-clean-correctly-sized-pdf-2ncg</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Drop your photos into &lt;strong&gt;&lt;a href="https://tooladda.online/images-to-pdf.html" rel="noopener noreferrer"&gt;tooladda.online/images-to-pdf.html&lt;/a&gt;&lt;/strong&gt;, drag them into order, pick a page size, download one PDF. Phone photos of documents become a submittable file in about fifteen seconds.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are usually photos of your &lt;strong&gt;ID, marksheets or signed pages&lt;/strong&gt;. Everything is assembled in your browser — no upload, so nothing sits in a stranger's temp folder after you submit the form.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📐 The page-fitting decision that ruins document scans
&lt;/h2&gt;

&lt;p&gt;A phone photo is roughly &lt;strong&gt;4:3&lt;/strong&gt;. A4 is roughly &lt;strong&gt;1:1.414&lt;/strong&gt;. Those don't match, so something has to give — and which choice you make decides whether your document looks scanned or looks like a snapshot someone pasted into Word.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fit (contain)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scales the image until it fits inside the page&lt;/td&gt;
&lt;td&gt;✅ Whole image visible, white bars on two sides. &lt;strong&gt;Use this for documents&lt;/strong&gt; — nothing gets cut off.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Fill (cover)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scales until the page is covered, crops the overflow&lt;/td&gt;
&lt;td&gt;❌ Edges of your document get sliced away. Fine for a photo book, fatal for a marksheet.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Actual size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uses the image's own DPI to place it&lt;/td&gt;
&lt;td&gt;Unpredictable unless you know the DPI — a 4000 px photo tagged 72 DPI becomes a 1.4-metre page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Page = image&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Page size follows each image&lt;/td&gt;
&lt;td&gt;No bars, but every page is a different size — see below&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The "page = image" trap:&lt;/strong&gt; it looks tidiest on screen, and then someone prints it. A PDF with twelve different page sizes prints with twelve different margins and scalings. If the file will ever be printed or merged, pick a single &lt;strong&gt;A4 or Letter with Fit&lt;/strong&gt; and accept the white bars.&lt;/p&gt;

&lt;h3&gt;
  
  
  Photograph documents properly and this tool does the rest
&lt;/h3&gt;

&lt;p&gt;Flat on a table, phone directly overhead (not at an angle), daylight from the side rather than behind you, and no shadow of your own hand across the page. A straight, evenly lit photo converted at "Fit" is genuinely hard to distinguish from a flatbed scan.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk7cgSlBHIMK3IFBORzxici8-V2ViUCDCtyBIRUlDXCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQiAtLT4gQ1tcIuKGle-4jyBEcmFnIHRvIG9yZGVyPGJyLz7wn5SEIHJvdGF0ZSBwYWdlc1wiXVxuICAgIEMgLS0-IERbXCJQYWdlIHNpemU6PGJyLz5BNCDCtyBMZXR0ZXIgwrcgZml0XCJdXG4gICAgRCAtLT4gRVtcIkZpdCBtb2RlPGJyLz5jb250YWluIC8gY292ZXJcIl1cbiAgICBFIC0tPiBGW1wi8J-ThCBTaW5nbGUgUERGXCJdXG4gICAgQiAtLi0-fFwi8J-aqyBub3RoaW5nIHVwbG9hZGVkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojN2YxZDFkLHN0cm9rZTojNDUwYTBhLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBFIGZpbGw6I2Y4NzE3MSxzdHJva2U6I2RjMjYyNixjb2xvcjojZmZmXG4gICAgc3R5bGUgRiBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk7cgSlBHIMK3IFBORzxici8-V2ViUCDCtyBIRUlDXCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQiAtLT4gQ1tcIuKGle-4jyBEcmFnIHRvIG9yZGVyPGJyLz7wn5SEIHJvdGF0ZSBwYWdlc1wiXVxuICAgIEMgLS0-IERbXCJQYWdlIHNpemU6PGJyLz5BNCDCtyBMZXR0ZXIgwrcgZml0XCJdXG4gICAgRCAtLT4gRVtcIkZpdCBtb2RlPGJyLz5jb250YWluIC8gY292ZXJcIl1cbiAgICBFIC0tPiBGW1wi8J-ThCBTaW5nbGUgUERGXCJdXG4gICAgQiAtLi0-fFwi8J-aqyBub3RoaW5nIHVwbG9hZGVkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojN2YxZDFkLHN0cm9rZTojNDUwYTBhLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBFIGZpbGw6I2Y4NzE3MSxzdHJva2U6I2RjMjYyNixjb2xvcjojZmZmXG4gICAgc3R5bGUgRiBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" alt="Diagram" width="1392" height="206"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 📱 HEIC works directly
iPhone photos convert without a separate step. Most "images to PDF" sites reject HEIC outright and send you looking for a converter first.

&lt;/td&gt;
&lt;td width="50%"&gt;

### ↕️ Reorder and rotate before export
Fix the sideways page and put page 3 where it belongs *before* the PDF exists, instead of re-doing the whole thing.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 📄 Real page-size control
A4, Letter, or page-per-image — with fit modes that are explained rather than guessed at.

&lt;/td&gt;
&lt;td width="50%"&gt;

### ♾️ No file cap, no watermark
Two photos or eighty. Nothing stamped across your output, no page limit before an upsell.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What you do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;📤 &lt;strong&gt;Portal wants one PDF, you have 6 photos&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Combine them, A4 + Fit, done.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧾 &lt;strong&gt;Expense receipts&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Photograph each, convert to one PDF for finance.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎓 &lt;strong&gt;Certificates and marksheets&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;One file per application instead of eight attachments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✍️ &lt;strong&gt;Signed pages you printed and photographed&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Merge back with the rest of the document.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📖 &lt;strong&gt;Photographed book pages&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Turn a chapter into a readable PDF.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🏠 &lt;strong&gt;Property or insurance documents&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Bundle photos into one archivable file.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/images-to-pdf.html
2.  Drop   →  all your images at once
3.  Set    →  order, rotation, A4 + Fit (for documents)
4.  Export →  one PDF — then compress if there's a size limit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Start now — tooladda.online/images-to-pdf.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the upload form has a KB limit, convert here first and then run the PDF through the PDF Compressor with a target size. Compressing the photos individually beforehand gives you a worse-looking document at the same final size.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Watermark or file limit?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no watermark, no signup, and the limit is your device's memory rather than a plan tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are my photos uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. They're read and assembled into the PDF inside your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it accept HEIC from my iPhone?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, directly. If you need HEIC in another format instead, the HEIC converter handles that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does my PDF have white bars on the sides?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because your photo's shape doesn't match A4, and Fit mode preserves the whole image rather than cropping it. That's the correct behaviour for documents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My PDF is huge. Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern phone photos are 4–12 MP each, and the PDF embeds them at full resolution. Compress the output, or resize the images first with the Image Resizer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I add more images to an existing PDF?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — use Merge PDF, which accepts PDFs and images together.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Client-side PDF assembly in vanilla JavaScript; images embedded as real PDF image objects.&lt;/li&gt;
&lt;li&gt;HEIC decoded in-browser, no server round-trip.&lt;/li&gt;
&lt;li&gt;Fit/cover geometry computed per page so page size and image aspect are handled explicitly.&lt;/li&gt;
&lt;li&gt;Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/images-to-pdf.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Images to PDF runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>💬 WhatsApp Chat Analyzer: Your whole chat history, analysed — without uploading a single message</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Wed, 16 Sep 2026 09:26:17 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/whatsapp-chat-analyzer-your-whole-chat-history-analysed-without-uploading-a-single-message-405c</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/whatsapp-chat-analyzer-your-whole-chat-history-analysed-without-uploading-a-single-message-405c</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Export a chat from WhatsApp, drop the &lt;code&gt;_chat.txt&lt;/code&gt; into &lt;strong&gt;&lt;a href="https://tooladda.online/whatsapp-chat-analyzer.html" rel="noopener noreferrer"&gt;tooladda.online/whatsapp-chat-analyzer.html&lt;/a&gt;&lt;/strong&gt;, and get message counts, activity heatmaps by hour and weekday, a word cloud, emoji rankings and response-time stats.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the tool where "no upload" stops being a nice-to-have.&lt;/strong&gt; A chat export is years of private conversation between real people — some of whom never agreed to anything. Every message is parsed inside your browser. Nothing is transmitted, nothing is stored, and closing the tab ends it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📤 Getting the export right (and the format gotcha)
&lt;/h2&gt;

&lt;p&gt;In WhatsApp: open the chat → ⋮ / chat name → &lt;strong&gt;Export chat&lt;/strong&gt; → &lt;strong&gt;Without media&lt;/strong&gt; (a with-media export is enormous and the analyzer only needs the text).&lt;/p&gt;

&lt;p&gt;You'll get &lt;code&gt;_chat.txt&lt;/code&gt; — or &lt;code&gt;WhatsApp Chat with Name.txt&lt;/code&gt; — and its &lt;strong&gt;format differs by platform&lt;/strong&gt;, which is why many analyzers fail on half of all exports:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Line format&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;iOS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;[15/01/2024, 21:04:33] Rahul: message text&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Android&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;15/01/2024, 21:04 - Rahul: message text&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The date order also follows the phone's locale — &lt;code&gt;15/01/2024&lt;/code&gt; in most of the world, &lt;code&gt;01/15/2024&lt;/code&gt; on a US-configured device. Get that backwards and every chart is wrong, silently: your "busiest month" is nonsense. This parser detects the platform format and the date ordering rather than assuming one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also in the file:&lt;/strong&gt; system lines (&lt;code&gt;Messages and calls are end-to-end encrypted&lt;/code&gt;, &lt;code&gt;X added Y&lt;/code&gt;, &lt;code&gt;‎image omitted&lt;/code&gt;) that are not messages from anyone. Counting those as messages inflates whoever happened to create the group.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgX2NoYXQudHh0PGJyLz5leHBvcnRcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDW1wiRGV0ZWN0IGZvcm1hdDxici8-aU9TIC8gQW5kcm9pZCArIGRhdGUgb3JkZXJcIl1cbiAgICBDIC0tPiBEW1wiUGFyc2UgbWVzc2FnZXM8YnIvPmZpbHRlciBzeXN0ZW0gbGluZXNcIl1cbiAgICBEIC0tPiBFW1wi8J-TiiBQZXItcGVyc29uIGNvdW50czxici8-bWVzc2FnZXMgwrcgd29yZHMgwrcgbWVkaWFcIl1cbiAgICBEIC0tPiBGW1wi8J-VkCBBY3Rpdml0eSBieSBob3VyLDxici8-d2Vla2RheSwgbW9udGhcIl1cbiAgICBEIC0tPiBHW1wi8J-YgiBFbW9qaSByYW5raW5nPGJyLz4rIHdvcmQgY2xvdWRcIl1cbiAgICBEIC0tPiBIW1wi4o-x77iPIFJlc3BvbnNlIHRpbWVzXCJdXG4gICAgQiAtLi0-fFwi8J-aqyBub3RoaW5nIHVwbG9hZGVkLCBub3RoaW5nIHN0b3JlZFwifCBYKChcIlNlcnZlclwiKSlcblxuICAgIHN0eWxlIEEgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzE0NTMyZCxzdHJva2U6IzA1MmUxNixjb2xvcjojZmZmXG4gICAgc3R5bGUgQyBmaWxsOiM0YWRlODAsc3Ryb2tlOiMxNmEzNGEsY29sb3I6IzAwMFxuICAgIHN0eWxlIEggZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBYIGZpbGw6IzNmM2Y0NixzdHJva2U6IzcxNzE3YSxjb2xvcjojZmZmLHN0cm9rZS1kYXNoYXJyYXk6IDUgNSIsIm1lcm1haWQiOnsidGhlbWUiOiJkYXJrIn19%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk4QgX2NoYXQudHh0PGJyLz5leHBvcnRcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDW1wiRGV0ZWN0IGZvcm1hdDxici8-aU9TIC8gQW5kcm9pZCArIGRhdGUgb3JkZXJcIl1cbiAgICBDIC0tPiBEW1wiUGFyc2UgbWVzc2FnZXM8YnIvPmZpbHRlciBzeXN0ZW0gbGluZXNcIl1cbiAgICBEIC0tPiBFW1wi8J-TiiBQZXItcGVyc29uIGNvdW50czxici8-bWVzc2FnZXMgwrcgd29yZHMgwrcgbWVkaWFcIl1cbiAgICBEIC0tPiBGW1wi8J-VkCBBY3Rpdml0eSBieSBob3VyLDxici8-d2Vla2RheSwgbW9udGhcIl1cbiAgICBEIC0tPiBHW1wi8J-YgiBFbW9qaSByYW5raW5nPGJyLz4rIHdvcmQgY2xvdWRcIl1cbiAgICBEIC0tPiBIW1wi4o-x77iPIFJlc3BvbnNlIHRpbWVzXCJdXG4gICAgQiAtLi0-fFwi8J-aqyBub3RoaW5nIHVwbG9hZGVkLCBub3RoaW5nIHN0b3JlZFwifCBYKChcIlNlcnZlclwiKSlcblxuICAgIHN0eWxlIEEgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzE0NTMyZCxzdHJva2U6IzA1MmUxNixjb2xvcjojZmZmXG4gICAgc3R5bGUgQyBmaWxsOiM0YWRlODAsc3Ryb2tlOiMxNmEzNGEsY29sb3I6IzAwMFxuICAgIHN0eWxlIEggZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBYIGZpbGw6IzNmM2Y0NixzdHJva2U6IzcxNzE3YSxjb2xvcjojZmZmLHN0cm9rZS1kYXNoYXJyYXk6IDUgNSIsIm1lcm1haWQiOnsidGhlbWUiOiJkYXJrIn19%3Ftype%3Dpng" alt="Diagram" width="1383" height="454"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 📊 Per-person breakdown
Messages, words, average message length, media count. In a group of twelve, it's usually three people doing 80% of the talking — and now you can prove it.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🕐 Activity heatmaps
By hour of day, day of week and month. The hour-of-day chart is the interesting one: it shows the actual rhythm of a friendship or a team.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### ⏱️ Response times
Median time to reply, per person. Genuinely revealing, and the stat most people open this tool to find.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 😂 Emoji rankings &amp;amp; word cloud
Most-used emoji per person, and the words that dominate the conversation. This is the part people screenshot.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ What people use it for
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What they find&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🎁 &lt;strong&gt;Anniversary or birthday gift&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"We've sent 47,000 messages" — printed as a chart.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;👥 &lt;strong&gt;Group chat wrapped&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Year-in-review stats to post back into the group.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💼 &lt;strong&gt;Work group audit&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Whether a "quick coordination" group is eating everyone's evenings.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📈 &lt;strong&gt;Personal curiosity&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Your own activity pattern — often not what you assumed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎓 &lt;strong&gt;Data-viz practice&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;A real, messy dataset you already have.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📉 &lt;strong&gt;Noticing a drift&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;When a conversation started thinning out.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Export →  WhatsApp → chat → Export chat → WITHOUT media
2.  Open   →  tooladda.online/whatsapp-chat-analyzer.html
3.  Drop   →  the _chat.txt file
4.  Explore→  charts, rankings, response times
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Analyze now — tooladda.online/whatsapp-chat-analyzer.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A group chat export contains other people's words. Local processing protects it technically — it doesn't decide the ethics for you. Sharing a stats screenshot back into the group is usually fine and fun. Analysing someone's chat without their knowledge, or publishing message content, is not. Think before you screenshot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always export &lt;strong&gt;without media&lt;/strong&gt;. The with-media export can run to gigabytes and adds nothing — the analyzer reads the text file, and media just show up as &lt;code&gt;image omitted&lt;/code&gt; lines it counts for you anyway.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Are my messages uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, and no — every message is parsed inside your browser. Nothing is transmitted or stored. Open the Network tab while it runs and you'll see it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I export a chat from WhatsApp?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the chat → ⋮ or the chat name → Export chat → Without media. You'll get a &lt;code&gt;.txt&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How big a chat can it handle?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Limited by your device's memory. Exports with hundreds of thousands of messages are workable on a normal laptop — and would be a serious privacy problem to upload anywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work with iOS and Android exports?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — the two use different line formats, and the parser detects which one you have.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My dates look wrong. Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Date order follows the exporting phone's locale (DD/MM vs MM/DD). Check the detected setting; getting it backwards quietly corrupts every time-based chart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can it read a chat backup or a database file?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No — only the plain text export. Encrypted backups aren't readable, and that's by design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work on group chats?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, with per-participant breakdowns. Groups are where the stats get most interesting.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla JavaScript parser handling both iOS and Android export formats, with locale-aware date detection.&lt;/li&gt;
&lt;li&gt;System and media-placeholder lines are classified separately so they don't inflate message counts.&lt;/li&gt;
&lt;li&gt;Charts rendered client-side; no analytics library phoning home with your data.&lt;/li&gt;
&lt;li&gt;No upload endpoint exists. Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/whatsapp-chat-analyzer.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where WhatsApp Chat Analyzer runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>⌨️ Typing Speed Test: Net WPM and accuracy — scored honestly, no account</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Tue, 15 Sep 2026 09:32:52 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/typing-speed-test-net-wpm-and-accuracy-scored-honestly-no-account-204i</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/typing-speed-test-net-wpm-and-accuracy-scored-honestly-no-account-204i</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Take the test at &lt;strong&gt;&lt;a href="https://tooladda.online/typing-speed-test.html" rel="noopener noreferrer"&gt;tooladda.online/typing-speed-test.html&lt;/a&gt;&lt;/strong&gt; and get your &lt;strong&gt;net&lt;/strong&gt; WPM — speed after errors are subtracted. That's the number that reflects how fast you actually produce usable text.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No signup, no leaderboard harvesting your email, no interstitial ad between you and your result.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧮 Gross vs net WPM — and why accuracy beats speed
&lt;/h2&gt;

&lt;p&gt;First, the definition of a "word" in typing measurement: &lt;strong&gt;five characters, including spaces.&lt;/strong&gt; Not a dictionary word. This is the standard so that "a" and "encyclopaedia" don't distort the count.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Gross WPM  =  (total characters ÷ 5) ÷ minutes
Net WPM    =  Gross WPM − (uncorrected errors ÷ minutes)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now watch what that does to two typists over one minute:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Typist A&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Typist B&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Characters typed&lt;/td&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gross WPM&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;80&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Errors&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;94%&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Net WPM&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;68&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to fix the errors&lt;/td&gt;
&lt;td&gt;~15–20 seconds&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Effective output&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;≈ 55–60 wpm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;60 wpm&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Typist A looks 33% faster and finishes the paragraph at roughly the same time — because every error costs a backspace, a re-read, and often a lost train of thought. Errors are not a small penalty; they're the dominant cost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The practical consequence:&lt;/strong&gt; if your accuracy is under 96%, &lt;strong&gt;slow down&lt;/strong&gt;. Deliberately typing 10 wpm below your maximum until accuracy is consistently high will make you faster within a couple of weeks. Chasing peak speed with sloppy accuracy plateaus you for years.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where you actually stand
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Net WPM&lt;/th&gt;
&lt;th&gt;Level&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;20–30&lt;/td&gt;
&lt;td&gt;Beginner&lt;/td&gt;
&lt;td&gt;Likely still looking at the keyboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;35–45&lt;/td&gt;
&lt;td&gt;Average&lt;/td&gt;
&lt;td&gt;Typical untrained adult&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;50–60&lt;/td&gt;
&lt;td&gt;Proficient&lt;/td&gt;
&lt;td&gt;Comfortable for most office work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;65–80&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Touch typing, good technique&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80–100&lt;/td&gt;
&lt;td&gt;Very fast&lt;/td&gt;
&lt;td&gt;Professional transcription range&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100+&lt;/td&gt;
&lt;td&gt;Exceptional&lt;/td&gt;
&lt;td&gt;Top percentile&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIuKMqO-4jyBZb3UgdHlwZTxici8-dGhlIHBhc3NhZ2VcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDW1wiQ291bnQgY2hhcmFjdGVyczxici8-w7cgNSA9IHdvcmRzXCJdXG4gICAgQiAtLT4gRFtcIlRyYWNrIGVycm9yczxici8-cGVyIGtleXN0cm9rZVwiXVxuICAgIEMgLS0-IEVbXCJHcm9zcyBXUE1cIl1cbiAgICBEIC0tPiBGW1wiQWNjdXJhY3kgJVwiXVxuICAgIEUgLS0-IEdbXCLwn5OKIE5FVCBXUE08YnIvPj0gZ3Jvc3Mg4oiSIGVycm9ycy9taW5cIl1cbiAgICBGIC0tPiBHXG4gICAgRyAtLT4gSFtcIvCflIEgSW5zdGFudCByZXRyeVwiXVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojMzEyZTgxLHN0cm9rZTojMWUxYjRiLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBEIGZpbGw6I2Y1OWUwYixzdHJva2U6I2I0NTMwOSxjb2xvcjojMDAwXG4gICAgc3R5bGUgRyBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZiIsIm1lcm1haWQiOnsidGhlbWUiOiJkYXJrIn19%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIuKMqO-4jyBZb3UgdHlwZTxici8-dGhlIHBhc3NhZ2VcIl0gLS0-IEJ7XCJZb3VyIGJyb3dzZXJcIn1cbiAgICBCIC0tPiBDW1wiQ291bnQgY2hhcmFjdGVyczxici8-w7cgNSA9IHdvcmRzXCJdXG4gICAgQiAtLT4gRFtcIlRyYWNrIGVycm9yczxici8-cGVyIGtleXN0cm9rZVwiXVxuICAgIEMgLS0-IEVbXCJHcm9zcyBXUE1cIl1cbiAgICBEIC0tPiBGW1wiQWNjdXJhY3kgJVwiXVxuICAgIEUgLS0-IEdbXCLwn5OKIE5FVCBXUE08YnIvPj0gZ3Jvc3Mg4oiSIGVycm9ycy9taW5cIl1cbiAgICBGIC0tPiBHXG4gICAgRyAtLT4gSFtcIvCflIEgSW5zdGFudCByZXRyeVwiXVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojMzEyZTgxLHN0cm9rZTojMWUxYjRiLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBEIGZpbGw6I2Y1OWUwYixzdHJva2U6I2I0NTMwOSxjb2xvcjojMDAwXG4gICAgc3R5bGUgRyBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZiIsIm1lcm1haWQiOnsidGhlbWUiOiJkYXJrIn19%3Ftype%3Dpng" alt="Diagram" width="1261" height="222"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 📊 Net WPM, not just gross
Errors are subtracted, so the score means something. A test that reports only gross WPM is flattering you.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🎯 Per-keystroke accuracy
See exactly where you went wrong, so you can spot the specific keys and letter combinations that trip you.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔁 Instant retry
One key to restart with fresh text. Repetition is the whole training method; friction between attempts kills it.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🚫 No account, no ad wall
Take the test, see the result, close the tab. Nothing gated behind an email or a countdown ad.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Why people take it
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What matters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;💼 &lt;strong&gt;Job application asking for WPM&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Quote your &lt;strong&gt;net&lt;/strong&gt; WPM — it's the defensible number.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🖥️ &lt;strong&gt;Data entry / BPO roles&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Accuracy is usually weighted above raw speed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📈 &lt;strong&gt;Tracking practice progress&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Test weekly, same conditions, watch the trend.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⌨️ &lt;strong&gt;New keyboard or layout&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Measure the dip and the recovery curve.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎓 &lt;strong&gt;Students building a study skill&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Faster typing directly means faster note-taking.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🏁 &lt;strong&gt;Just curious&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Two minutes, no signup.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 How to actually get faster
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Test    →  tooladda.online/typing-speed-test.html — record your baseline
2.  Check   →  accuracy first. Under 96%? Slow down deliberately.
3.  Technique→ home row, all ten fingers, DON'T look at the keys
4.  Practise→  10 focused minutes daily beats two hours on Sunday
5.  Retest  →  weekly, same time of day, same keyboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Take the test — tooladda.online/typing-speed-test.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The single biggest gain for most people isn't finger speed — it's &lt;strong&gt;not looking at the keyboard&lt;/strong&gt;. Looking down forces your eyes to re-find your place in the text after every glance, and that re-orientation costs more time than the keystrokes do. Cover your hands if you have to.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Do I need to sign up?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, no email, no ad wall.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What counts as a "word"?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Five characters including spaces — the universal standard, so word length doesn't skew the score.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gross or net WPM — which should I quote?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Net. It accounts for errors and is what a serious employer means when they ask.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's a good typing speed?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;40 wpm is average, 60+ is proficient, 80+ is fast. With 95%+ accuracy in every case — 90 wpm at 85% accuracy is worse than 60 at 99%.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is my speed lower here than on another site?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Different tests use different passages and, crucially, some report gross WPM. A test that ignores your errors always gives a bigger number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long until I improve?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With 10–15 focused minutes daily, most people gain 10–20 wpm over a couple of months. Fixing accuracy usually produces the first jump.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work on a phone?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It runs, but thumb typing measures a different skill. Use a physical keyboard for a meaningful score.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla JavaScript, client-side timing and per-keystroke comparison — no data sent anywhere.&lt;/li&gt;
&lt;li&gt;Net WPM computed from the standard 5-character word definition with uncorrected errors subtracted.&lt;/li&gt;
&lt;li&gt;Instant restart with fresh passages to prevent memorisation inflating your score.&lt;/li&gt;
&lt;li&gt;Works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/typing-speed-test.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Typing Speed Test runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>privacy</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>🎬 Online Teleprompter: A real teleprompter in a browser tab — nothing to download</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Mon, 14 Sep 2026 10:03:12 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/online-teleprompter-a-real-teleprompter-in-a-browser-tab-nothing-to-download-oa8</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/online-teleprompter-a-real-teleprompter-in-a-browser-tab-nothing-to-download-oa8</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Paste your script into &lt;strong&gt;&lt;a href="https://tooladda.online/online-teleprompter.html" rel="noopener noreferrer"&gt;tooladda.online/online-teleprompter.html&lt;/a&gt;&lt;/strong&gt;, set the speed, hit play, and read while looking straight at the lens. No app install, no account, no watermark burned into your recording.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Scripts are often unreleased announcements, client work or personal messages. Nothing is uploaded here — the script stays in your browser tab.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎙️ Get the speed right with arithmetic, not guesswork
&lt;/h2&gt;

&lt;p&gt;The commonest teleprompter failure is scrolling at a speed that doesn't match your natural delivery, which makes you either race or stall. You can calculate it instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comfortable spoken delivery is roughly 130–150 words per minute.&lt;/strong&gt; Below 120 sounds sluggish; above 170 loses your audience.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Script length&lt;/th&gt;
&lt;th&gt;At 140 wpm&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;150 words&lt;/td&gt;
&lt;td&gt;~1 minute&lt;/td&gt;
&lt;td&gt;A short social clip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;350 words&lt;/td&gt;
&lt;td&gt;~2.5 minutes&lt;/td&gt;
&lt;td&gt;A product explainer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;700 words&lt;/td&gt;
&lt;td&gt;~5 minutes&lt;/td&gt;
&lt;td&gt;A tutorial segment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1,400 words&lt;/td&gt;
&lt;td&gt;~10 minutes&lt;/td&gt;
&lt;td&gt;A conference talk section&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2,100 words&lt;/td&gt;
&lt;td&gt;~15 minutes&lt;/td&gt;
&lt;td&gt;A long-form piece&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Working backwards:&lt;/strong&gt; need a 60-second video? Write &lt;strong&gt;about 140 words&lt;/strong&gt;. Not 300. This one calculation saves more re-shoots than any other piece of advice on this page.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Read your script aloud once at natural pace and time it, then set the scroll speed to match &lt;em&gt;your&lt;/em&gt; rate rather than an average. Some people are comfortable at 120, some at 165. Tune it to yourself and the delivery stops sounding read.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Mirror mode: what it's actually for
&lt;/h3&gt;

&lt;p&gt;A professional teleprompter is a &lt;strong&gt;beam splitter&lt;/strong&gt; — a sheet of half-silvered glass at 45° in front of the lens. You see the reflected text; the camera looks straight through. Because the image is reflected, the text must be &lt;strong&gt;flipped horizontally&lt;/strong&gt; before it hits the glass, or you'd be reading it backwards.&lt;/p&gt;

&lt;p&gt;That's what mirror mode does. If you're just reading off a laptop next to the camera, leave it &lt;strong&gt;off&lt;/strong&gt; — flipping text you're reading directly is the mistake that wastes ten minutes at the start of a shoot.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk50gUGFzdGUgc2NyaXB0XCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQiAtLT4gQ1tcIlNldCBzcGVlZDxici8-bWF0Y2ggeW91ciB3cG1cIl1cbiAgICBDIC0tPiBEW1wiRm9udCBzaXplIMK3PGJyLz5jb2xvdXJzIMK3IG1hcmdpbnNcIl1cbiAgICBEIC0tPiBFe1wiUmlnP1wifVxuICAgIEUgLS0-fFwiYmVhbSBzcGxpdHRlclwifCBGW1wi8J-qniBNaXJyb3IgT05cIl1cbiAgICBFIC0tPnxcImxhcHRvcCBiZXNpZGUgY2FtZXJhXCJ8IEdbXCJNaXJyb3IgT0ZGXCJdXG4gICAgRiAtLT4gSFtcIuKWtu-4jyBTY3JvbGwgKyByZWFkPGJyLz5rZXlib2FyZCBjb250cm9sXCJdXG4gICAgRyAtLT4gSFxuICAgIEIgLS4tPnxcIvCfmqsgc2NyaXB0IG5ldmVyIHVwbG9hZGVkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojODMxODQzLHN0cm9rZTojNTAwNzI0LGNvbG9yOiNmZmZcbiAgICBzdHlsZSBGIGZpbGw6I2Y0NzJiNixzdHJva2U6I2RiMjc3Nyxjb2xvcjojZmZmXG4gICAgc3R5bGUgSCBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCfk50gUGFzdGUgc2NyaXB0XCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQiAtLT4gQ1tcIlNldCBzcGVlZDxici8-bWF0Y2ggeW91ciB3cG1cIl1cbiAgICBDIC0tPiBEW1wiRm9udCBzaXplIMK3PGJyLz5jb2xvdXJzIMK3IG1hcmdpbnNcIl1cbiAgICBEIC0tPiBFe1wiUmlnP1wifVxuICAgIEUgLS0-fFwiYmVhbSBzcGxpdHRlclwifCBGW1wi8J-qniBNaXJyb3IgT05cIl1cbiAgICBFIC0tPnxcImxhcHRvcCBiZXNpZGUgY2FtZXJhXCJ8IEdbXCJNaXJyb3IgT0ZGXCJdXG4gICAgRiAtLT4gSFtcIuKWtu-4jyBTY3JvbGwgKyByZWFkPGJyLz5rZXlib2FyZCBjb250cm9sXCJdXG4gICAgRyAtLT4gSFxuICAgIEIgLS4tPnxcIvCfmqsgc2NyaXB0IG5ldmVyIHVwbG9hZGVkXCJ8IFgoKFwiU2VydmVyXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojODMxODQzLHN0cm9rZTojNTAwNzI0LGNvbG9yOiNmZmZcbiAgICBzdHlsZSBGIGZpbGw6I2Y0NzJiNixzdHJva2U6I2RiMjc3Nyxjb2xvcjojZmZmXG4gICAgc3R5bGUgSCBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" alt="Diagram" width="1741" height="246"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🎚️ Live speed control
Adjust mid-take without stopping. Real delivery isn't uniform — you'll slow down for a complex sentence and speed up through a list.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🪞 Mirror mode
Horizontal flip for beam-splitter rigs. Toggleable, so the same script works on a professional rig and on a laptop.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔤 Big, readable typography
Font size, line height, colour and margins all adjustable. At two metres from the screen you need much larger text than feels sensible up close.

&lt;/td&gt;
&lt;td width="50%"&gt;

### ⌨️ Keyboard &amp;amp; remote control
Space to start/stop, arrows for speed. A cheap Bluetooth presentation clicker maps to those keys, giving you a hands-free remote.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Who uses it
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🎥 &lt;strong&gt;YouTube / Reels scripts&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Hit the exact word count for a duration and stop re-shooting.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💼 &lt;strong&gt;Recorded presentations&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Look at the camera instead of down at notes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📞 &lt;strong&gt;Client calls and demos&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Keep your key points on screen without shuffling paper.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎓 &lt;strong&gt;Online teaching&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Deliver a prepared explanation while facing the class.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📰 &lt;strong&gt;News-style pieces&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The original use case, on a laptop instead of a studio rig.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎤 &lt;strong&gt;Rehearsing a talk&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Read at your target pace until you no longer need the prompter.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Five steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Write  →  ~140 words per minute of finished video
2.  Open   →  tooladda.online/online-teleprompter.html
3.  Paste  →  your script
4.  Tune   →  font size for your distance, speed to your natural pace
5.  Mirror →  ON for a beam splitter, OFF for a plain screen → record
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Start now — tooladda.online/online-teleprompter.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Place the script window &lt;strong&gt;as close to the lens as physically possible&lt;/strong&gt; — directly beneath or above it. Reading off a second monitor to the side is instantly visible to your audience as "eyes drifting off camera", and no amount of scroll tuning hides it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Watermark?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, no watermark, no time limit on a session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need to install anything?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. It's a web page — it works on a laptop, tablet or phone browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is my script uploaded?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. It stays in your browser tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What speed should I use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start around 140 wpm, then adjust to your own natural pace. Time yourself reading aloud once and match that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When do I turn mirror mode on?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only with a beam-splitter teleprompter rig. For a screen you read directly, leave it off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I control it hands-free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — a Bluetooth presentation clicker sends the same keys as your keyboard, so it works as a remote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work on a tablet?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, and a tablet mounted near the lens is a very good budget prompter.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla JavaScript, single page; smooth scrolling driven by &lt;code&gt;requestAnimationFrame&lt;/code&gt; so it doesn't stutter while you're recording.&lt;/li&gt;
&lt;li&gt;Mirror mode is a CSS transform — no re-render, no quality loss.&lt;/li&gt;
&lt;li&gt;Keyboard handlers map to standard presentation-remote keycodes.&lt;/li&gt;
&lt;li&gt;Works offline once loaded; nothing about your script leaves the browser.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/online-teleprompter.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Online Teleprompter runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>📝 Online Notepad: Auto-save, Markdown preview, version history — no login, ever</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Sun, 13 Sep 2026 09:40:28 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/online-notepad-auto-save-markdown-preview-version-history-no-login-ever-2kh6</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/online-notepad-auto-save-markdown-preview-version-history-no-login-ever-2kh6</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Open &lt;strong&gt;&lt;a href="https://tooladda.online/online-notepad.html" rel="noopener noreferrer"&gt;tooladda.online/online-notepad.html&lt;/a&gt;&lt;/strong&gt; and type. It saves as you go, keeps a version history, renders Markdown live, and works with the Wi-Fi off. There is no sign-up screen because there is no account.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your notes live in &lt;strong&gt;your browser's storage&lt;/strong&gt;, on your device. Not in someone's database, not attached to an email address, not readable by a support engineer. That's what "local-first" means, and it's the entire design.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🗄️ Local-first: what you gain, and the one thing to know
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;
&lt;strong&gt;This notepad&lt;/strong&gt; (local)&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Cloud note app&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sign-up&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Email + password&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works offline&lt;/td&gt;
&lt;td&gt;✅ Fully&lt;/td&gt;
&lt;td&gt;Partially, at best&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Who can read your notes&lt;/td&gt;
&lt;td&gt;Only you&lt;/td&gt;
&lt;td&gt;You, the company, anyone who breaches it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Instant — no network in the loop&lt;/td&gt;
&lt;td&gt;Depends on your connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Survives the service shutting down&lt;/td&gt;
&lt;td&gt;✅ It's on your disk&lt;/td&gt;
&lt;td&gt;❌ Export-or-lose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Syncs across your devices&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Survives clearing browser data&lt;/td&gt;
&lt;td&gt;❌ &lt;strong&gt;No&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Those last two rows are the honest trade-off, and it's worth stating plainly rather than burying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Notes are stored in your browser's local storage for &lt;strong&gt;this browser, on this device&lt;/strong&gt;. They will be lost if you clear site data, use "Clear browsing history → cookies and site data", or open the notepad in a different browser or a private window. &lt;strong&gt;Export anything you'd be upset to lose&lt;/strong&gt; — that's what the MD/ZIP export is for.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Browser storage per site is finite (typically a handful of megabytes for &lt;code&gt;localStorage&lt;/code&gt;). That's tens of thousands of words — enormous for notes, and not where you should keep a novel. For a long manuscript, export to Markdown and keep the file.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIuKMqO-4jyBZb3UgdHlwZVwiXSAtLT4gQntcIllvdXIgYnJvd3NlclwifVxuICAgIEIgLS0-IENbXCLwn5K-IEF1dG8tc2F2ZTxici8-KGxvY2FsIHN0b3JhZ2UpXCJdXG4gICAgQyAtLT4gRFtcIvCflZggVmVyc2lvbiBoaXN0b3J5XCJdXG4gICAgQiAtLT4gRVtcIvCfkYHvuI8gTGl2ZSBNYXJrZG93bjxici8-cHJldmlld1wiXVxuICAgIEIgLS0-IEZbXCLwn5eC77iPIE11bHRpLW5vdGUgc2lkZWJhcjxici8-KyB0YWdzXCJdXG4gICAgQyAtLT4gR1tcIvCfk6QgRXhwb3J0PGJyLz5NRCDCtyBIVE1MIMK3IFBERiDCtyBET0NYIMK3IFpJUFwiXVxuICAgIEIgLS4tPnxcIvCfmqsgbm8gYWNjb3VudCwgbm8gc3luYyw8YnIvPm5vIHNlcnZlclwifCBYKChcIkNsb3VkXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojNzgzNTBmLHN0cm9rZTojNDUxYTAzLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBDIGZpbGw6I2ZiYmYyNCxzdHJva2U6I2Q5NzcwNixjb2xvcjojMDAwXG4gICAgc3R5bGUgRyBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIuKMqO-4jyBZb3UgdHlwZVwiXSAtLT4gQntcIllvdXIgYnJvd3NlclwifVxuICAgIEIgLS0-IENbXCLwn5K-IEF1dG8tc2F2ZTxici8-KGxvY2FsIHN0b3JhZ2UpXCJdXG4gICAgQyAtLT4gRFtcIvCflZggVmVyc2lvbiBoaXN0b3J5XCJdXG4gICAgQiAtLT4gRVtcIvCfkYHvuI8gTGl2ZSBNYXJrZG93bjxici8-cHJldmlld1wiXVxuICAgIEIgLS0-IEZbXCLwn5eC77iPIE11bHRpLW5vdGUgc2lkZWJhcjxici8-KyB0YWdzXCJdXG4gICAgQyAtLT4gR1tcIvCfk6QgRXhwb3J0PGJyLz5NRCDCtyBIVE1MIMK3IFBERiDCtyBET0NYIMK3IFpJUFwiXVxuICAgIEIgLS4tPnxcIvCfmqsgbm8gYWNjb3VudCwgbm8gc3luYyw8YnIvPm5vIHNlcnZlclwifCBYKChcIkNsb3VkXCIpKVxuXG4gICAgc3R5bGUgQSBmaWxsOiMwZWE1ZTksc3Ryb2tlOiMwMzY5YTEsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEIgZmlsbDojNzgzNTBmLHN0cm9rZTojNDUxYTAzLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBDIGZpbGw6I2ZiYmYyNCxzdHJva2U6I2Q5NzcwNixjb2xvcjojMDAwXG4gICAgc3R5bGUgRyBmaWxsOiMyMmM1NWUsc3Ryb2tlOiMxNTgwM2QsY29sb3I6I2ZmZlxuICAgIHN0eWxlIFggZmlsbDojM2YzZjQ2LHN0cm9rZTojNzE3MTdhLGNvbG9yOiNmZmYsc3Ryb2tlLWRhc2hhcnJheTogNSA1IiwibWVybWFpZCI6eyJ0aGVtZSI6ImRhcmsifX0%3Ftype%3Dpng" alt="Diagram" width="1102" height="509"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 💾 Auto-save as you type
No save button, no "unsaved changes" dialog. Close the tab mid-sentence and the sentence is still there tomorrow.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🕘 Version history
Roll back to an earlier state of a note. The safety net that makes an editor without a save button trustworthy.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 👁️ Live Markdown preview
Write in Markdown, see it rendered beside you. Headings, lists, code blocks, links, tables.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🗂️ Multiple notes with tags
A real sidebar, not one endless text box. Tag notes and find them again.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 📤 Five export formats
Markdown, HTML, PDF, DOCX, or a ZIP of everything. Your notes are never locked in a format only this tool can read.

&lt;/td&gt;
&lt;td width="50%"&gt;

### ✈️ Installable PWA
Add to your home screen or desktop and it opens offline like a native app — because nothing about it needs a network.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;Why this one&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;📋 &lt;strong&gt;Scratchpad on a work machine&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;No install, no admin rights, no corporate app-approval process.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎓 &lt;strong&gt;Lecture notes&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Markdown is fast to type; export to PDF to share.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧑‍💻 &lt;strong&gt;Snippets and command lines&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Code blocks with proper monospace formatting.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🗒️ &lt;strong&gt;Drafting a message before sending&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Type it out, reread it, then paste.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✍️ &lt;strong&gt;Journalling&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Genuinely private — nothing syncs anywhere.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;✈️ &lt;strong&gt;Writing on a flight&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Offline PWA, no connection needed.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Getting started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open    →  tooladda.online/online-notepad.html
2.  Type    →  it's already saving
3.  Organise→  new notes in the sidebar, add tags
4.  Install →  browser menu → Install (for offline + desktop icon)
5.  EXPORT  →  ZIP backup of anything you can't afford to lose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Start writing — tooladda.online/online-notepad.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Make an export part of your habit — a ZIP backup once a week takes five seconds. Local-first storage is fast, private and yours; it is not a backup strategy on its own.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Do I need an account?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, and there's no account at all — no email, no password, no verification step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where are my notes stored?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your browser's local storage, on your device. Not on a server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I lose my notes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — if you clear browser site data, or use a different browser or device. Export regularly. This is the honest cost of not having an account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I sync between my phone and laptop?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No automatic sync, because there's no server. Export and move the file, or use the same device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it work offline?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, fully. Install it as a PWA and it behaves like a local app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can anyone else read my notes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not remotely — there's nothing transmitted. Anyone with access to your unlocked device and this browser profile can, so treat it like a file on your desktop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much can I write?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Browser storage is typically a few megabytes per site — tens of thousands of words. Plenty for notes; export long-form work to files.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla JavaScript, no framework; storage via the browser's local storage APIs.&lt;/li&gt;
&lt;li&gt;Markdown rendered client-side; PDF and DOCX generated client-side too.&lt;/li&gt;
&lt;li&gt;Service worker + web manifest for genuine offline operation.&lt;/li&gt;
&lt;li&gt;No backend, no analytics on note content, no account system.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/online-notepad.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Online Notepad runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>privacy</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>⏰ Cron Expression Generator: Build it visually, read it in plain English, preview the next runs</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Sat, 12 Sep 2026 08:45:02 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/cron-expression-generator-build-it-visually-read-it-in-plain-english-preview-the-next-runs-3mfp</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/cron-expression-generator-build-it-visually-read-it-in-plain-english-preview-the-next-runs-3mfp</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;Nobody reads &lt;code&gt;*/15 3 * * 1-5&lt;/code&gt; correctly on the first try. Paste it into &lt;strong&gt;&lt;a href="https://tooladda.online/cron-expression-generator.html" rel="noopener noreferrer"&gt;tooladda.online/cron-expression-generator.html&lt;/a&gt;&lt;/strong&gt; and get a sentence plus the next ten actual run times — or build the schedule from dropdowns and get the expression.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A cron typo doesn't error. It runs — just at the wrong time, silently, possibly a thousand times more often than you intended. Previewing the &lt;strong&gt;next run times&lt;/strong&gt; is the only reliable way to know you got it right.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚨 The day-of-month / day-of-week trap
&lt;/h2&gt;

&lt;p&gt;This is the one genuine landmine in cron, it bites experienced people, and it's in the manual where nobody looks.&lt;/p&gt;

&lt;p&gt;The five fields are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────── minute        0-59
│ ┌─────────── hour          0-23
│ │ ┌───────── day of month  1-31
│ │ │ ┌─────── month         1-12
│ │ │ │ ┌───── day of week   0-6  (Sunday = 0)
│ │ │ │ │
*  *  *  *  *
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally all fields must match — an AND. &lt;strong&gt;But if both day-of-month and day-of-week are restricted (neither is &lt;code&gt;*&lt;/code&gt;), cron switches to OR.&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;What people expect&lt;/th&gt;
&lt;th&gt;What actually happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0 0 1 * 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Midnight on the 1st, but only if it's a Monday&lt;/td&gt;
&lt;td&gt;🚨 &lt;strong&gt;Midnight on the 1st of every month, AND every Monday&lt;/strong&gt; — roughly 16 runs a month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0 0 13 * 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Friday the 13th only&lt;/td&gt;
&lt;td&gt;Every 13th &lt;strong&gt;and&lt;/strong&gt; every Friday&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0 0 1 * *&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1st of the month&lt;/td&gt;
&lt;td&gt;✅ Correct — day-of-week is &lt;code&gt;*&lt;/code&gt;, so AND applies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0 0 * * 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every Monday&lt;/td&gt;
&lt;td&gt;✅ Correct&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;If you actually want "the 1st only when it's a Monday",&lt;/strong&gt; cron can't express it. Schedule it for every Monday and check the date inside your script.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other things that catch people
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Means&lt;/th&gt;
&lt;th&gt;Common misreading&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*/15 * * * *&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;:00, :15, :30, :45&lt;/td&gt;
&lt;td&gt;"every 15 minutes from when I saved it" — no, it's aligned to the clock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*/20 * * * *&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;:00, :20, :40&lt;/td&gt;
&lt;td&gt;Fine&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*/40 * * * *&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;:00, :40 — then a &lt;strong&gt;20-minute gap&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;"every 40 minutes" — the step resets each hour, it does not wrap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0 */5 * * *&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every 5 &lt;strong&gt;hours&lt;/strong&gt; at :00&lt;/td&gt;
&lt;td&gt;Confused with every 5 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0 0 * * 7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sunday (7 is accepted alongside 0)&lt;/td&gt;
&lt;td&gt;Thinking 7 means Monday&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Warning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Cron uses the &lt;strong&gt;system's&lt;/strong&gt; time zone unless the scheduler explicitly supports one. A job set for 02:30 daily will be skipped or run twice on DST transition days. For anything that must not double-run, schedule outside 01:00–03:00 local, or run in UTC.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIuKPsCBQYXN0ZSBhbiBleHByZXNzaW9uXCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQTJbXCLwn46b77iPIE9yIGJ1aWxkIHdpdGg8YnIvPmRyb3Bkb3duc1wiXSAtLT4gQlxuICAgIEIgLS0-IENbXCJQYXJzZSA1IGZpZWxkc1wiXVxuICAgIEMgLS0-IERbXCLwn5OWIFBsYWluLUVuZ2xpc2g8YnIvPmRlc2NyaXB0aW9uXCJdXG4gICAgQyAtLT4gRVtcIvCfl5PvuI8gTmV4dCAxMCBydW4gdGltZXM8YnIvPmluIHlvdXIgY2hvc2VuIHpvbmVcIl1cbiAgICBDIC0tPiBGW1wi8J-aqCBXYXJuIG9uIERPTStET1c8YnIvPk9SIGJlaGF2aW91clwiXVxuICAgIEQgLS0-IEdbXCLwn5OLIENvcHkgdGhlIGV4cHJlc3Npb25cIl1cbiAgICBFIC0tPiBHXG5cbiAgICBzdHlsZSBBIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQTIgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzdjMmQxMixzdHJva2U6IzQzMTQwNyxjb2xvcjojZmZmXG4gICAgc3R5bGUgRiBmaWxsOiNlZjQ0NDQsc3Ryb2tlOiNiOTFjMWMsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEcgZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmYiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIuKPsCBQYXN0ZSBhbiBleHByZXNzaW9uXCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQTJbXCLwn46b77iPIE9yIGJ1aWxkIHdpdGg8YnIvPmRyb3Bkb3duc1wiXSAtLT4gQlxuICAgIEIgLS0-IENbXCJQYXJzZSA1IGZpZWxkc1wiXVxuICAgIEMgLS0-IERbXCLwn5OWIFBsYWluLUVuZ2xpc2g8YnIvPmRlc2NyaXB0aW9uXCJdXG4gICAgQyAtLT4gRVtcIvCfl5PvuI8gTmV4dCAxMCBydW4gdGltZXM8YnIvPmluIHlvdXIgY2hvc2VuIHpvbmVcIl1cbiAgICBDIC0tPiBGW1wi8J-aqCBXYXJuIG9uIERPTStET1c8YnIvPk9SIGJlaGF2aW91clwiXVxuICAgIEQgLS0-IEdbXCLwn5OLIENvcHkgdGhlIGV4cHJlc3Npb25cIl1cbiAgICBFIC0tPiBHXG5cbiAgICBzdHlsZSBBIGZpbGw6IzBlYTVlOSxzdHJva2U6IzAzNjlhMSxjb2xvcjojZmZmXG4gICAgc3R5bGUgQTIgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzdjMmQxMixzdHJva2U6IzQzMTQwNyxjb2xvcjojZmZmXG4gICAgc3R5bGUgRiBmaWxsOiNlZjQ0NDQsc3Ryb2tlOiNiOTFjMWMsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEcgZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmYiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ%3Ftype%3Dpng" alt="Diagram" width="1215" height="350"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 📖 Both directions
Expression → English, and dropdowns → expression. Most tools do one; you need the other one exactly when you're debugging someone else's crontab.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🗓️ Next run preview
Ten concrete dates and times. This is the feature that catches the DOM/DOW trap before production does.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🌍 Time zone aware
See the schedule in the zone your server actually runs in, not just your laptop's.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🎯 Common presets
Hourly, nightly, weekdays-only, first-of-month, every 15 minutes — starting points you then adjust.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What you check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;💾 &lt;strong&gt;Nightly backup&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;That it runs once a night, not once a minute.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧹 &lt;strong&gt;Cleanup job&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;That "every 40 minutes" isn't leaving a 20-minute gap each hour.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📧 &lt;strong&gt;Weekly report email&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;The right weekday, in the right zone.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;☸️ &lt;strong&gt;Kubernetes CronJob&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Same syntax, and the same DOM/DOW trap.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔍 &lt;strong&gt;Auditing an inherited crontab&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Read what each line actually does before you touch it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚀 &lt;strong&gt;CI scheduled pipeline&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;GitHub Actions &lt;code&gt;schedule&lt;/code&gt; uses cron — and runs in &lt;strong&gt;UTC&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Four steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/cron-expression-generator.html
2.  Enter  →  paste an expression, or build one with dropdowns
3.  Read   →  the English description
4.  VERIFY →  the next 10 run times — this is the step that matters
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Open it — tooladda.online/cron-expression-generator.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Don't schedule everything at &lt;code&gt;0 0 * * *&lt;/code&gt;. Every job on the box firing at exactly midnight creates a CPU and I/O spike, and staggering them (&lt;code&gt;7 0&lt;/code&gt;, &lt;code&gt;23 0&lt;/code&gt;, &lt;code&gt;41 0&lt;/code&gt;) costs nothing and prevents a class of mysterious nightly slowdowns.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, and it runs entirely in your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does &lt;code&gt;*/15 * * * *&lt;/code&gt; mean?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every 15 minutes on the clock — :00, :15, :30, :45. Not "15 minutes after I installed it".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does my "1st of the month AND Monday" job run so often?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because with both day fields restricted, cron uses OR, not AND. It runs on every 1st and every Monday. Cron cannot express the AND version — check the date inside your script instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is Sunday 0 or 7?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Both are accepted by most implementations. 1 is always Monday.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does cron support seconds?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Standard Unix cron does not — one minute is the finest granularity. Some schedulers (Quartz, Spring) add a leading seconds field, making six.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What time zone does it use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The system's, unless your scheduler lets you set one. GitHub Actions schedules always run in UTC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I schedule "last day of the month"?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not in standard cron. Some implementations support &lt;code&gt;L&lt;/code&gt;; otherwise run daily and exit early unless it's the last day.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cron parser and next-run calculator in vanilla JavaScript, running client-side.&lt;/li&gt;
&lt;li&gt;Implements standard 5-field Vixie cron semantics — including the DOM/DOW OR rule, which is why it can warn you about it.&lt;/li&gt;
&lt;li&gt;Time zone handling via the &lt;code&gt;Intl&lt;/code&gt; API.&lt;/li&gt;
&lt;li&gt;Covered by unit tests; works offline once loaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/cron-expression-generator.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Cron Expression Generator runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
    <item>
      <title>⏱️ Epoch Converter: Unix timestamps ↔ human time, in any time zone, offline</title>
      <dc:creator>Tomaz</dc:creator>
      <pubDate>Fri, 11 Sep 2026 09:02:17 +0000</pubDate>
      <link>https://dev.to/tomaz_8a7b374c4dc1136233b/epoch-converter-unix-timestamps-human-time-in-any-time-zone-offline-5fkk</link>
      <guid>https://dev.to/tomaz_8a7b374c4dc1136233b/epoch-converter-unix-timestamps-human-time-in-any-time-zone-offline-5fkk</guid>
      <description>&lt;h2&gt;
  
  
  ⚡ 10-second version
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;1754784000&lt;/code&gt; means nothing to a human and everything to your database. Paste it into &lt;strong&gt;&lt;a href="https://tooladda.online/epoch-converter.html" rel="noopener noreferrer"&gt;tooladda.online/epoch-converter.html&lt;/a&gt;&lt;/strong&gt; and read the date — in UTC, in your zone, or in whichever zone your user was actually in.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;❗ Important&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Installable as a PWA, so it converts with the network off. Handy when you're reading logs on a machine with no internet, which is exactly when you need a timestamp decoded.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔢 Count the digits before you convert anything
&lt;/h2&gt;

&lt;p&gt;The most common timestamp bug isn't the time zone — it's the &lt;strong&gt;unit&lt;/strong&gt;. Same instant, three different numbers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Digits&lt;/th&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Reads as&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;seconds&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1754784000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10 Aug 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;13&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;milliseconds&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1754784000000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10 Aug 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;16&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;microseconds&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1754784000000000&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10 Aug 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Feed a 13-digit millisecond value into something expecting seconds and you land &lt;strong&gt;~53,000 years in the future&lt;/strong&gt;. Do the reverse and you get 1970. Both failures look absurd, which is the good news — you spot them instantly, once you know to count the digits.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who uses what:&lt;/strong&gt; Unix/C, PostgreSQL and most REST APIs use &lt;strong&gt;seconds&lt;/strong&gt;. JavaScript's &lt;code&gt;Date.now()&lt;/code&gt;, Java and Android use &lt;strong&gt;milliseconds&lt;/strong&gt;. This tool detects the unit from the digit count and shows you which it assumed.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 2038 problem is real and it's dated
&lt;/h3&gt;

&lt;p&gt;A signed 32-bit integer maxes out at &lt;code&gt;2147483647&lt;/code&gt;. As a Unix timestamp that is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2038-01-19T03:14:07Z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One second later it overflows to negative — &lt;strong&gt;13 December 1901&lt;/strong&gt;. Any system still storing time in a signed 32-bit field will do this. It sounds like 1999-era trivia until you remember how much embedded firmware, how many filesystem timestamps, and how many old database columns are still in service. Use 64-bit time. Check your legacy columns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two more things that surprise people
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Fact&lt;/th&gt;
&lt;th&gt;Consequence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Unix time ignores leap seconds&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;It's not a true count of elapsed SI seconds since 1970. A leap second is absorbed rather than counted, so Unix time and atomic time drift apart by the leap-second total.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;A timestamp has no time zone&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;An epoch value is an absolute instant — always UTC-based. The time zone only exists when you &lt;em&gt;format&lt;/em&gt; it for a human. Half of all "the date is off by 5:30" bugs come from formatting in the server's zone instead of the user's.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧭 How it works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCflKIgMTc1NDc4NDAwMDxici8-b3IgYSBkYXRlXCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQiAtLT4gQ1tcIkNvdW50IGRpZ2l0czxici8-4oaSIHMgLyBtcyAvIMK1c1wiXVxuICAgIEMgLS0-IERbXCJBYnNvbHV0ZSBpbnN0YW50PGJyLz4oVVRDKVwiXVxuICAgIEQgLS0-IEVbXCLwn4yNIFVUQ1wiXVxuICAgIEQgLS0-IEZbXCLwn4-gIFlvdXIgbG9jYWwgem9uZVwiXVxuICAgIEQgLS0-IEdbXCLwn5e677iPIEFueSBjaG9zZW4gem9uZVwiXVxuICAgIEQgLS0-IEhbXCLwn5OLIElTTyA4NjAxIC8gUkZDIGZvcm1hdHNcIl1cbiAgICBCIC0tPiBJW1wi8J-VkCBMaXZlIGN1cnJlbnQgZXBvY2hcIl1cblxuICAgIHN0eWxlIEEgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzFlM2E4YSxzdHJva2U6IzE3MjU1NCxjb2xvcjojZmZmXG4gICAgc3R5bGUgQyBmaWxsOiM2MGE1ZmEsc3Ryb2tlOiMyNTYzZWIsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEggZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmYiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ%3Ftype%3Dpng" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2FeyJjb2RlIjoiZmxvd2NoYXJ0IExSXG4gICAgQVtcIvCflKIgMTc1NDc4NDAwMDxici8-b3IgYSBkYXRlXCJdIC0tPiBCe1wiWW91ciBicm93c2VyXCJ9XG4gICAgQiAtLT4gQ1tcIkNvdW50IGRpZ2l0czxici8-4oaSIHMgLyBtcyAvIMK1c1wiXVxuICAgIEMgLS0-IERbXCJBYnNvbHV0ZSBpbnN0YW50PGJyLz4oVVRDKVwiXVxuICAgIEQgLS0-IEVbXCLwn4yNIFVUQ1wiXVxuICAgIEQgLS0-IEZbXCLwn4-gIFlvdXIgbG9jYWwgem9uZVwiXVxuICAgIEQgLS0-IEdbXCLwn5e677iPIEFueSBjaG9zZW4gem9uZVwiXVxuICAgIEQgLS0-IEhbXCLwn5OLIElTTyA4NjAxIC8gUkZDIGZvcm1hdHNcIl1cbiAgICBCIC0tPiBJW1wi8J-VkCBMaXZlIGN1cnJlbnQgZXBvY2hcIl1cblxuICAgIHN0eWxlIEEgZmlsbDojMGVhNWU5LHN0cm9rZTojMDM2OWExLGNvbG9yOiNmZmZcbiAgICBzdHlsZSBCIGZpbGw6IzFlM2E4YSxzdHJva2U6IzE3MjU1NCxjb2xvcjojZmZmXG4gICAgc3R5bGUgQyBmaWxsOiM2MGE1ZmEsc3Ryb2tlOiMyNTYzZWIsY29sb3I6I2ZmZlxuICAgIHN0eWxlIEggZmlsbDojMjJjNTVlLHN0cm9rZTojMTU4MDNkLGNvbG9yOiNmZmYiLCJtZXJtYWlkIjp7InRoZW1lIjoiZGFyayJ9fQ%3Ftype%3Dpng" alt="Diagram" width="1183" height="382"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What's inside
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🔍 Automatic unit detection
Seconds, milliseconds or microseconds identified from the digit count — and it tells you which it picked, so a wrong guess is visible rather than silent.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 🌍 Any time zone, both directions
Convert to a chosen zone, or from a local wall-clock time in some other zone back into an epoch. DST handled properly.

&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width="50%"&gt;

### 🕐 Live epoch clock
The current timestamp, ticking. Useful for sanity-checking whether a value is in the past or the future at a glance.

&lt;/td&gt;
&lt;td width="50%"&gt;

### 📋 Every format you need
ISO 8601, RFC 2822, plain readable text, and relative ("3 hours ago") — copyable straight into a bug report or a test fixture.

&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🛠️ Real jobs
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situation&lt;/th&gt;
&lt;th&gt;What you do&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🐛 &lt;strong&gt;Reading a log line&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Turn a raw epoch into "yesterday 14:32" and correlate with the incident.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🎫 &lt;strong&gt;Debugging a JWT&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Decode &lt;code&gt;exp&lt;/code&gt; and &lt;code&gt;iat&lt;/code&gt; to see whether the token is genuinely expired.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🗄️ &lt;strong&gt;Inspecting a DB row&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Convert a stored timestamp column to a readable date.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🌏 &lt;strong&gt;A user reports the wrong date&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Check the same instant in their zone versus your server's.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⏲️ &lt;strong&gt;Building a test fixture&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Get the epoch for a specific date and time.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📅 &lt;strong&gt;Scheduling / cache expiry&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Compute the epoch for "24 hours from now".&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📖 Three steps
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1.  Open   →  tooladda.online/epoch-converter.html
2.  Paste  →  the timestamp (or pick a date to go the other way)
3.  Read   →  UTC · your zone · any zone — and confirm the unit it detected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;▶ Convert now — tooladda.online/epoch-converter.html&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Store timestamps in &lt;strong&gt;UTC&lt;/strong&gt;, always. Convert to a local zone only at the moment you display them to a person. Storing local time is how you end up with an hour of duplicated or missing records every time the clocks change.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is it free? Does it work offline?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Free, no signup, and yes — install it as a PWA and it converts with no connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the Unix epoch?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Midnight UTC on 1 January 1970. A Unix timestamp counts the seconds since that instant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Seconds or milliseconds — how do I tell?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Count the digits: 10 = seconds, 13 = milliseconds, 16 = microseconds. Getting it wrong throws the date off by tens of thousands of years, so it's obvious once you look.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can a timestamp be negative?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes — negative values are dates before 1970. Perfectly valid, and worth knowing before you add a "must be positive" validation rule.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the 2038 problem?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Signed 32-bit time overflows at 2038-01-19T03:14:07Z and wraps to 1901. Anything still using a 32-bit time field will break. Use 64-bit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does Unix time include leap seconds?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. It absorbs them rather than counting them, so it isn't a strict count of elapsed SI seconds since 1970.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is my date off by 5 hours 30 minutes?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Classic time-zone formatting bug — the epoch is being rendered in the wrong zone (IST is UTC+5:30). The timestamp itself carries no zone; only the formatting does.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔬 Under the hood
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Vanilla JavaScript with the &lt;code&gt;Intl&lt;/code&gt; API for correct, DST-aware time zone handling.&lt;/li&gt;
&lt;li&gt;Unit detection from magnitude, with the assumption shown rather than hidden.&lt;/li&gt;
&lt;li&gt;Service worker + manifest for real offline use.&lt;/li&gt;
&lt;li&gt;Nothing you paste is transmitted anywhere.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://tooladda.online/epoch-converter.html" rel="noopener noreferrer"&gt;ToolAdda&lt;/a&gt;, where Epoch Converter runs free in your browser — nothing is uploaded, nothing leaves your device.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>privacy</category>
      <category>webdev</category>
      <category>tools</category>
    </item>
  </channel>
</rss>
