<?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: Alain Picard</title>
    <description>The latest articles on DEV Community by Alain Picard (@picarda27).</description>
    <link>https://dev.to/picarda27</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3842218%2Ff651b988-a489-4102-8f35-3f6863faffa3.png</url>
      <title>DEV Community: Alain Picard</title>
      <link>https://dev.to/picarda27</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/picarda27"/>
    <language>en</language>
    <item>
      <title>ChromeFlash</title>
      <dc:creator>Alain Picard</dc:creator>
      <pubDate>Tue, 07 Apr 2026 18:37:29 +0000</pubDate>
      <link>https://dev.to/picarda27/chromeflash-415a</link>
      <guid>https://dev.to/picarda27/chromeflash-415a</guid>
      <description>&lt;p&gt;&lt;strong&gt;I built a Chrome extension to track where Chrome's RAM actually goes.&lt;/strong&gt;&lt;br&gt;
Chrome uses a lot of memory. We all know this. But when I actually tried to figure out &lt;em&gt;which tabs&lt;/em&gt; were eating my RAM, I realized Chrome doesn't make it easy.&lt;/p&gt;

&lt;p&gt;Task Manager gives you raw process IDs. &lt;code&gt;chrome://memory-internals&lt;/code&gt; is a wall of text. Neither tells you "your 12 active tabs are using ~960 MB and your 2 YouTube tabs are using ~300 MB."&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://chromewebstore.google.com/detail/pfjfdmnjcignndpnlggbfngfciojjoeh?utm_source=item-share-cb" rel="noopener noreferrer"&gt;ChromeFlash&lt;/a&gt; — a Manifest V3 extension that estimates Chrome's memory by category and gives you tools to reclaim it.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it looks like
&lt;/h2&gt;

&lt;p&gt;The popup shows a breakdown of Chrome's estimated RAM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Browser Core&lt;/strong&gt; — ~250 MB for Chrome's internal processes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Tabs&lt;/strong&gt; — ~80 MB each&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pinned Tabs&lt;/strong&gt; — ~50 MB each (lighter footprint)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Media Tabs&lt;/strong&gt; — ~150 MB each (audio/video)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Suspended Tabs&lt;/strong&gt; — ~1 MB each&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensions&lt;/strong&gt; — estimated overhead&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A stacked color bar visualizes the proportions at a glance.&lt;/p&gt;
&lt;h2&gt;
  
  
  The honest caveat
&lt;/h2&gt;

&lt;p&gt;Chrome's extension APIs in Manifest V3 don't expose per-tab memory. The &lt;code&gt;chrome.processes&lt;/code&gt; API exists but is limited to dev channel. So these are &lt;strong&gt;estimates&lt;/strong&gt; based on real-world averages — not exact measurements.&lt;/p&gt;

&lt;p&gt;If you know a better approach, I'd genuinely love to hear it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tab suspension
&lt;/h2&gt;

&lt;p&gt;The biggest win. Calling &lt;code&gt;chrome.tabs.discard()&lt;/code&gt; on an inactive tab drops it from ~80 MB to ~1 MB. The tab stays in your tab bar, and when you click it, Chrome reloads it.&lt;/p&gt;

&lt;p&gt;ChromeFlash lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Suspend inactive tabs manually or on a timer (1–120 min)&lt;/li&gt;
&lt;li&gt;Protect pinned tabs and tabs playing audio&lt;/li&gt;
&lt;li&gt;Detect and close duplicate tabs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The auto-suspend runs via &lt;code&gt;chrome.alarms&lt;/code&gt; since MV3 service workers can't use &lt;code&gt;setInterval&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The core of tab suspension&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alarms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tab-audit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;periodInMinutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alarms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onAlarm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alarm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;alarm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tab-audit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({});&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;shouldDiscard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;discard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optimization profiles
&lt;/h2&gt;

&lt;p&gt;Four presets that configure tab suspension + Chrome settings in one click:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Profile&lt;/th&gt;
&lt;th&gt;Suspend&lt;/th&gt;
&lt;th&gt;Services Off&lt;/th&gt;
&lt;th&gt;Est. RAM Saved&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Gaming&lt;/td&gt;
&lt;td&gt;1 min&lt;/td&gt;
&lt;td&gt;5 (DNS, spell, translate, autofill, search)&lt;/td&gt;
&lt;td&gt;~500–2000 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Productivity&lt;/td&gt;
&lt;td&gt;15 min&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;~200–600 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery Saver&lt;/td&gt;
&lt;td&gt;5 min&lt;/td&gt;
&lt;td&gt;4 (DNS, spell, translate, search)&lt;/td&gt;
&lt;td&gt;~400–1500 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Privacy&lt;/td&gt;
&lt;td&gt;30 min&lt;/td&gt;
&lt;td&gt;7 (+ Topics, FLEDGE, Do Not Track ON)&lt;/td&gt;
&lt;td&gt;~150–400 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each profile shows the exact numbers and what changes — no vague "optimizes your browser" marketing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hidden settings via chrome.privacy
&lt;/h2&gt;

&lt;p&gt;Chrome exposes several settings through the &lt;code&gt;chrome.privacy&lt;/code&gt; API that most users never touch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Toggle DNS prefetching&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;networkPredictionEnabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Disable cloud spell check&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spellingServiceEnabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Disable Topics API (ad tracking)&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;websites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topicsEnabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Disable FLEDGE / Protected Audiences&lt;/span&gt;
&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;websites&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fledgeEnabled&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension exposes 8 of these as toggle switches. Disabling background services like spell check and translation reduces both network calls and CPU usage — not dramatically, but it adds up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chrome Flags guide
&lt;/h2&gt;

&lt;p&gt;Chrome flags (&lt;code&gt;chrome://flags&lt;/code&gt;) can meaningfully improve performance, but extensions can't modify them programmatically — Chrome blocks this for security reasons.&lt;/p&gt;

&lt;p&gt;So ChromeFlash includes a curated database of 21 performance-relevant flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rendering&lt;/strong&gt; — GPU Rasterization, Zero-Copy, Skia Graphite&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt; — QUIC Protocol, WebSocket over HTTP/2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt; — Automatic Tab Discarding, High Efficiency Mode&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript&lt;/strong&gt; — V8 Sparkplug, V8 Maglev compilers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loading&lt;/strong&gt; — Back/Forward Cache, Parallel Downloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each flag shows a risk level, impact rating, and a button that opens it directly in &lt;code&gt;chrome://flags/#flag-name&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ChromeFlash/
  manifest.json
  src/
    background/service-worker.js    # Alarms, tab audit, memory pressure
    modules/
      tab-manager.js                # Suspend, discard, duplicates
      memory-optimizer.js           # Chrome RAM breakdown
      network-optimizer.js          # DNS prefetch toggle
      privacy-optimizer.js          # 8 privacy setting toggles
      performance-monitor.js        # CPU/memory stats, score
      profiles.js                   # 4 profiles with detailed stats
      flags-database.js             # 21 curated flags
      settings.js / storage.js      # Persistence
    popup/                          # Main UI
    pages/                          # Dashboard + Flags Guide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No build step. No framework. No bundler. ES modules loaded natively by Chrome. The entire extension is under 50 KB.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;MV3 service workers are stateless.&lt;/strong&gt; Every alarm fires into a fresh context. You can't store state in module-level variables — it has to go in &lt;code&gt;chrome.storage&lt;/code&gt;. This tripped me up early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;chrome.tabs.discard()&lt;/code&gt; is underrated.&lt;/strong&gt; It's the single highest-impact thing an extension can do for memory. 85–92% reduction per tab with zero user friction — the tab just reloads when you click it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;chrome.privacy&lt;/code&gt; is powerful but underdiscovered.&lt;/strong&gt; Most developers don't know you can programmatically toggle DNS prefetching, Topics API, or FLEDGE from an extension. The API surface is small but useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Flags can't be automated.&lt;/strong&gt; I spent time looking for workarounds before accepting that &lt;code&gt;chrome://flags&lt;/code&gt; is intentionally walled off. The guide approach works well enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;ChromeFlash is free, open source, and collects zero data. No analytics, no remote servers, no tracking. Everything stays in &lt;code&gt;chrome.storage.local&lt;/code&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>browser</category>
    </item>
    <item>
      <title>Why I Built a PGP Encryption Layer for Gmail (And Open-Sourced the Chrome Extension)</title>
      <dc:creator>Alain Picard</dc:creator>
      <pubDate>Sun, 29 Mar 2026 21:43:22 +0000</pubDate>
      <link>https://dev.to/picarda27/why-i-built-a-pgp-encryption-layer-for-gmail-and-open-sourced-the-chrome-extension-1ho1</link>
      <guid>https://dev.to/picarda27/why-i-built-a-pgp-encryption-layer-for-gmail-and-open-sourced-the-chrome-extension-1ho1</guid>
      <description>&lt;p&gt;Why I Built a PGP Encryption Layer for Gmail (And Open-Sourced the Chrome Extension)&lt;br&gt;
I sent a contract over Gmail last year. Nothing fancy — just a freelance agreement with a client's banking details for direct deposit. Hit send, moved on with my day.&lt;/p&gt;

&lt;p&gt;Three weeks later, that client got a phishing email referencing exact dollar amounts from our agreement. Someone had scraped it. Maybe from a compromised inbox, maybe from a server breach, maybe from something else entirely. The point is: the email sat on Google's servers in plaintext the entire time.&lt;/p&gt;

&lt;p&gt;That's the moment I stopped assuming Gmail "encryption" meant what I thought it meant.&lt;/p&gt;

&lt;p&gt;What Gmail Actually Encrypts (And What It Doesn't)&lt;br&gt;
Here's the thing most developers don't realize until they dig into it. Gmail uses TLS — Transport Layer Security. Your email is encrypted while it's moving between servers. The little padlock icon in your browser? That's TLS doing its job.&lt;/p&gt;

&lt;p&gt;But once your email lands on Google's servers, it's stored in a format Google can read. Their systems scan it for spam filtering. Smart Reply reads it to suggest responses. Ads used to be targeted based on email content (Google says they stopped, but the infrastructure to do it never went away).&lt;/p&gt;

&lt;p&gt;TLS protects your email from a man-in-the-middle attack during transit. It does absolutely nothing if Google's servers get breached, if a government subpoena demands your data, or if a rogue employee decides to peek.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TLS encryption:
  You  ──[encrypted]──&amp;gt;  Google Server  ──[encrypted]──&amp;gt;  Recipient
                              │
                         [plaintext]
                         Google can read it here.

End-to-end encryption (PGP):
  You  ──[encrypted]──&amp;gt;  Google Server  ──[encrypted]──&amp;gt;  Recipient
                              │
                         [still encrypted]
                         Nobody reads it. Not even Google.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gap between "encrypted in transit" and "actually private" is what kept bugging me.&lt;/p&gt;

&lt;p&gt;So I Built GmailKrypt&lt;br&gt;
GmailKrypt is a Chrome extension that bolts PGP encryption directly onto Gmail's interface. No separate app. No copy-pasting into a terminal. You compose your email like you normally would, click encrypt, and send.&lt;/p&gt;

&lt;p&gt;The whole thing runs on OpenPGP.js — the same standard that's been protecting communications since Phil Zimmermann released PGP back in 1991. Except now you don't need to touch a command line to use it.&lt;/p&gt;

&lt;p&gt;How It Actually Works in Practice&lt;br&gt;
You install the extension. It generates a key pair for you — a public key and a private key. Your private key stays in Chrome's local storage. It never hits a server. Not mine. Not Google's. Nobody's.&lt;/p&gt;

&lt;p&gt;When you want to send an encrypted email:&lt;/p&gt;

&lt;p&gt;Compose your email in Gmail like normal&lt;br&gt;
Click the GmailKrypt encrypt button in the toolbar&lt;br&gt;
The extension encrypts the message body using the recipient's public key&lt;br&gt;
Gmail sends what looks like a block of gibberish&lt;br&gt;
What your recipient sees before decryption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-----BEGIN PGP MESSAGE-----

hQEMA7Vj8+t5rZ7aAQf+N2M7j8K2vF9xD3nE1yP4mR6sQ
8tA5bC7dF0gH3iK6lN9oR2sU5vX8yB1cE4fG7hJ0kL3mO
6pS9tW2xA5zC8dF1gI4jL7nQ0rU3vY6aD9eH2iK5lN8oR1
=x7Fp
-----END PGP MESSAGE-----

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the recipient has GmailKrypt installed, the extension detects the PGP block and decrypts it automatically. If they use any other PGP tool — Thunderbird, GPG Suite, Kleopatra — it works just the same. That's the beauty of open standards.&lt;/p&gt;

&lt;p&gt;The Architecture (For the Nerds)&lt;br&gt;
I know this is dev.to, so let's get into the guts of it.&lt;/p&gt;

&lt;p&gt;Zero-knowledge design. The extension uses chrome.storage.local for private keys. They're sandboxed by Chrome's extension security model. The API server I run at api.gmailkrypt.com handles licensing and Stripe subscriptions — it never touches keys, never sees message content, never stores anything it shouldn't.&lt;/p&gt;

&lt;p&gt;Content script injection. GmailKrypt injects into Gmail's DOM to add the encrypt/decrypt toolbar. It listens for compose window events and intercepts the message body before send. All the crypto happens client-side through OpenPGP.js.&lt;/p&gt;

&lt;p&gt;Key exchange. This was the UX challenge. PGP has always been powerful but painful to set up. GmailKrypt lets you attach your public key to any email with a single button click. The recipient imports it, sends theirs back, and you're set. First exchange takes maybe 30 seconds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Simplified flow&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;privateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;publicKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openpgp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateKey&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ecc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;curve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;curve25519&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;userIDs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;you@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Encrypt&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openpgp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;openpgp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;emailBody&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;encryptionKeys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;recipientPublicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;signingKeys&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;myPrivateKey&lt;/span&gt;  &lt;span class="c1"&gt;// also signs it&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Digital signatures come free with PGP. Every encrypted email is also signed, so the recipient can verify it actually came from you and wasn't tampered with in transit. Authentication, integrity, and non-repudiation — all in one operation.&lt;/p&gt;

&lt;p&gt;Who Is This Actually For?&lt;br&gt;
I built this scratching my own itch, but it turns out a lot of people have the same itch.&lt;/p&gt;

&lt;p&gt;Freelancers and contractors sending invoices with bank details over email. Lawyers who have attorney-client privilege to protect but keep using Gmail because their firm is on Google Workspace. Journalists communicating with sources — Snowden used PGP with Glenn Greenwald for a reason. Healthcare folks who technically violate HIPAA every time they email patient info through standard Gmail. Developers who want to practice what they preach about security.&lt;/p&gt;

&lt;p&gt;Or honestly? Anyone who's ever sent a password, a credit card number, or a social security number over email and felt that little twinge of "I probably shouldn't have done that."&lt;/p&gt;

&lt;p&gt;The Google Workspace Elephant in the Room&lt;br&gt;
Google does offer something called S/MIME encryption for Workspace Enterprise customers. It costs significantly more than standard Workspace, requires your IT admin to manage certificates, and only works between users whose organizations have both set up S/MIME correctly.&lt;/p&gt;

&lt;p&gt;For the other 1.8 billion Gmail users? Nothing.&lt;/p&gt;

&lt;p&gt;That's not an oversight. Google's business model fundamentally conflicts with end-to-end encryption. If they can't read your emails, they can't power Smart Compose, can't filter spam as effectively, can't build the profile that drives their ad ecosystem. I'm not saying that's evil — it's just the reality of a free product.&lt;/p&gt;

&lt;p&gt;GmailKrypt sidesteps all of that. It works with free Gmail, Google Workspace, any plan. You're adding encryption on top of Gmail, not asking Google to provide it.&lt;/p&gt;

&lt;p&gt;Free Tier, Pro Tier, No BS&lt;br&gt;
The extension is free to use — you get 5 encryptions per day, which covers most people's needs. If you're sending encrypted emails all day (lawyers, journalists, security teams), the Pro plan is $4.99/month for unlimited everything.&lt;/p&gt;

&lt;p&gt;I thought long and hard about pricing. I wanted it accessible enough that a student or activist could use it without paying, but sustainable enough that I can keep maintaining it. Five free encryptions felt like the right balance.&lt;/p&gt;

&lt;p&gt;Try It, Break It, Tell Me What's Wrong&lt;br&gt;
You can grab GmailKrypt from the Chrome Web Store or check out the landing page at gmailkrypt.com.&lt;/p&gt;

&lt;p&gt;If you're the type who reads source code before installing extensions (and you should be), the extension runs entirely client-side for all crypto operations. The only network calls are to the license API for Pro features.&lt;/p&gt;

&lt;p&gt;I'm genuinely curious what this community thinks. Is PGP email encryption still relevant in 2026? Are there UX improvements that would make you actually use this? Did I miss something obvious in the architecture?&lt;/p&gt;

&lt;p&gt;Drop a comment. I read all of them.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>google</category>
      <category>privacy</category>
      <category>anonymous</category>
    </item>
    <item>
      <title>I built Google Keep for Developers — here's why</title>
      <dc:creator>Alain Picard</dc:creator>
      <pubDate>Tue, 24 Mar 2026 21:31:40 +0000</pubDate>
      <link>https://dev.to/picarda27/i-built-google-keep-for-developers-heres-why-4k8b</link>
      <guid>https://dev.to/picarda27/i-built-google-keep-for-developers-heres-why-4k8b</guid>
      <description>&lt;p&gt;Every developer I know has the same problem: code snippets scattered across 15 different places.&lt;/p&gt;

&lt;p&gt;A regex you wrote six months ago? Somewhere in a Slack DM. That Docker Compose template you always reuse? Maybe in a Notion page. The SQL query that saved you three hours last quarter? Lost in a .txt file called &lt;code&gt;notes_final_v2.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I tried everything — GitHub Gists, Notion, Apple Notes, random text files, bookmarked Stack Overflow answers. None of them felt right. Gists are too heavy for a quick snippet. Notion doesn't understand code. Google Keep is perfect for quick capture, but try pasting a 20-line function in there — no syntax highlighting, no Markdown, no structure.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;&lt;a href="https://www.codeskeep.com" rel="noopener noreferrer"&gt;CodesKeep&lt;/a&gt;&lt;/strong&gt; — Google Keep, but designed from the ground up for developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;CodesKeep is a web app for saving, organizing, and finding your code snippets and Markdown notes. Think of it as the simplicity of Google Keep meets the developer-awareness of a code editor.&lt;/p&gt;

&lt;p&gt;Here's what makes it different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Markdown &amp;amp; code-first&lt;/strong&gt; — full Markdown support with syntax highlighting out of the box. Your notes look like they belong in a README, not a sticky note.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instant capture&lt;/strong&gt; — open it, paste your snippet, tag it, done. No friction, no folder hierarchies to navigate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search that actually works&lt;/strong&gt; — find that snippet by language, tag, keyword, or content. No more digging through 50 untitled notes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built for reuse&lt;/strong&gt; — snippets are meant to be grabbed and dropped into your project. Copy with one click.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I built it
&lt;/h2&gt;

&lt;p&gt;I'm an Android developer by day. I work in Kotlin, Jetpack Compose, and a bunch of other tools — and I was constantly losing useful code. Not big libraries or modules, but the &lt;em&gt;small&lt;/em&gt; stuff:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Compose modifier chain I always forget&lt;/li&gt;
&lt;li&gt;Environment variable configs for different projects&lt;/li&gt;
&lt;li&gt;Bash one-liners for Docker cleanup&lt;/li&gt;
&lt;li&gt;API response formats I reference weekly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are too small for a repo, too important for a sticky note, and too code-heavy for a regular notes app.&lt;/p&gt;

&lt;p&gt;I realized what I actually wanted was &lt;strong&gt;Google Keep with syntax highlighting and Markdown&lt;/strong&gt;. That's it. Not a full IDE, not a documentation platform, not a second brain. Just a fast, clean place to keep code notes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stack
&lt;/h2&gt;

&lt;p&gt;For those curious about the technical side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Modern web app, responsive and fast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Focus&lt;/strong&gt;: Speed of capture and retrieval — the two things that matter most for a snippet tool&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I intentionally kept the feature set tight. Every snippet manager I tried suffered from feature bloat — team workspaces, presentation modes, social sharing, marketplace integrations. Those are fine for some products, but they slow down the one thing I actually need: &lt;em&gt;save this code now, find it later.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I'm actively building and would love feedback from the community. Some things on the roadmap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Browser extension&lt;/strong&gt; — snip code blocks directly from Stack Overflow, GitHub, or docs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VS Code / JetBrains integration&lt;/strong&gt; — save and insert snippets without leaving your editor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team sharing&lt;/strong&gt; — share collections with your team (without the bloat)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API access&lt;/strong&gt; — for the automation-minded among us&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it out
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://www.codeskeep.com" rel="noopener noreferrer"&gt;www.codeskeep.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's live and ready to use. I'd genuinely appreciate any feedback — what works, what's missing, what would make you switch from your current setup.&lt;/p&gt;

&lt;p&gt;Drop a comment below or reach out — I read everything.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've ever lost a code snippet you spent 30 minutes writing, this is for you.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>productivity</category>
      <category>google</category>
    </item>
  </channel>
</rss>
