<?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: Sivaram</title>
    <description>The latest articles on DEV Community by Sivaram (@sivarampg).</description>
    <link>https://dev.to/sivarampg</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%2F1177780%2Fdec94b05-f103-4186-84b9-f614b42f2e85.jpg</url>
      <title>DEV Community: Sivaram</title>
      <link>https://dev.to/sivarampg</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sivarampg"/>
    <language>en</language>
    <item>
      <title>Claude's 2x Usage Boost Is Live — Here's How to Maximize It (March 13–28, 2026)</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Tue, 17 Mar 2026 08:44:37 +0000</pubDate>
      <link>https://dev.to/sivarampg/claudes-2x-usage-boost-is-live-heres-how-to-maximize-it-march-13-28-2026-31d0</link>
      <guid>https://dev.to/sivarampg/claudes-2x-usage-boost-is-live-heres-how-to-maximize-it-march-13-28-2026-31d0</guid>
      <description>&lt;p&gt;If you missed the announcement: &lt;strong&gt;Anthropic is doubling Claude usage for free&lt;/strong&gt; outside peak hours from March 13–28, 2026. This applies to Claude (web, desktop, mobile), Claude Code, Cowork, Claude for Excel, and Claude for PowerPoint.&lt;/p&gt;

&lt;p&gt;No catch. Nothing to enable. It just works.&lt;/p&gt;

&lt;p&gt;I built a live tracker to check if the boost is active right now:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://is-claude-2x-right-now.vercel.app/" rel="noopener noreferrer"&gt;Is Claude 2x Right Now?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What's the Promotion?
&lt;/h2&gt;

&lt;p&gt;Anthropic calls it the "Spring Break" promotion. Here's the deal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2x usage&lt;/strong&gt; on weekdays outside 5–11 AM PT (8 AM–2 PM ET)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2x usage&lt;/strong&gt; all day on weekends&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bonus usage doesn't count toward your weekly limits&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Runs &lt;strong&gt;March 13 through March 28, 2026&lt;/strong&gt; (confirmed via &lt;a href="https://support.claude.com/en/articles/14063676-claude-march-2026-usage-promotion" rel="noopener noreferrer"&gt;Claude Support&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point is worth repeating: the extra usage is &lt;em&gt;on top of&lt;/em&gt; your normal allocation. It's not borrowing from next week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who Gets It?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plan&lt;/th&gt;
&lt;th&gt;Included?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pro&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Max&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enterprise&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;It works everywhere you use Claude:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude&lt;/strong&gt; (web, desktop, mobile)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cowork&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; (this is the big one for devs)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude for Excel&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Claude for PowerPoint&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Peak Hours by Timezone
&lt;/h2&gt;

&lt;p&gt;The 2x boost is active &lt;strong&gt;outside&lt;/strong&gt; these peak windows on weekdays. Weekends are 2x all day, every timezone.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Region&lt;/th&gt;
&lt;th&gt;Peak (1x)&lt;/th&gt;
&lt;th&gt;2x Hours&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;US West Coast (PT)&lt;/td&gt;
&lt;td&gt;5–11 AM&lt;/td&gt;
&lt;td&gt;11 AM–5 AM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;US East Coast (ET)&lt;/td&gt;
&lt;td&gt;8 AM–2 PM&lt;/td&gt;
&lt;td&gt;2 PM–8 AM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UK (GMT)&lt;/td&gt;
&lt;td&gt;12–6 PM&lt;/td&gt;
&lt;td&gt;6 PM–12 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Central Europe (CET)&lt;/td&gt;
&lt;td&gt;1–7 PM&lt;/td&gt;
&lt;td&gt;7 PM–1 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gulf / Dubai (GST)&lt;/td&gt;
&lt;td&gt;4–10 PM&lt;/td&gt;
&lt;td&gt;10 PM–4 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;India (IST)&lt;/td&gt;
&lt;td&gt;5:30–11:30 PM&lt;/td&gt;
&lt;td&gt;11:30 PM–5:30 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;China / Singapore (SGT)&lt;/td&gt;
&lt;td&gt;8 PM–2 AM&lt;/td&gt;
&lt;td&gt;2 AM–8 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Japan / Korea (JST)&lt;/td&gt;
&lt;td&gt;9 PM–3 AM&lt;/td&gt;
&lt;td&gt;3 AM–9 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Australia East (AEST)&lt;/td&gt;
&lt;td&gt;11 PM–5 AM&lt;/td&gt;
&lt;td&gt;5 AM–11 PM + weekends&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;TL;DR: If you're outside the US, your entire workday is probably 2x already.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  I Built a Live Tracker
&lt;/h2&gt;

&lt;p&gt;I wanted a quick way to check if the 2x boost is active without doing timezone math in my head. So I built one:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;a href="https://is-claude-2x-right-now.vercel.app/" rel="noopener noreferrer"&gt;is-claude-2x-right-now.vercel.app&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instant YES/NO answer&lt;/strong&gt; — is 2x active right now?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live countdown&lt;/strong&gt; — time until the next status change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dual clocks&lt;/strong&gt; — your local time + Pacific Time side by side&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;24-hour circular clock&lt;/strong&gt; — visual dial showing today's 2x vs peak windows in your timezone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Day timeline&lt;/strong&gt; — progress bar with now marker showing where you are&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timezone table&lt;/strong&gt; — peak hours for every major timezone, with your row highlighted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything auto-detects your timezone. No setup needed.&lt;/p&gt;

&lt;p&gt;Built with React 19, Vite 8, React Compiler, and TypeScript. The entire 2x detection runs client-side — no backend, no API calls. Just timezone math.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://is-claude-2x-right-now.vercel.app/" rel="noopener noreferrer"&gt;Check it out →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for Developers: How to Maximize the 2x Boost
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Shift Your Claude Code Sessions
&lt;/h3&gt;

&lt;p&gt;If you're on the US West Coast, mornings (5–11 AM) are peak. Schedule your heavy Claude Code work for afternoons and evenings. Everyone else — your normal work hours are probably already 2x.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Batch Your Big Tasks
&lt;/h3&gt;

&lt;p&gt;Got a major refactor, migration, or codebase exploration? Do it now, during the promotion. The 2x limit means you can go deeper before hitting the ceiling.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Weekends Are Unlimited (2x)
&lt;/h3&gt;

&lt;p&gt;Saturday and Sunday are 2x all day in every timezone. If you've been putting off that side project, this is literally what Anthropic is suggesting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"whatever you've been putting off — now's a good time."&lt;/em&gt;&lt;br&gt;
— &lt;a href="https://x.com/claudeai/status/2032911276226257206" rel="noopener noreferrer"&gt;@claudeai&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Use It Across All Surfaces
&lt;/h3&gt;

&lt;p&gt;The boost isn't just for the web app. Claude Code, Cowork, Excel, PowerPoint — they all get 2x. If you haven't tried Claude Code yet, now is the cheapest time to experiment.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Bonus Usage Is Free
&lt;/h3&gt;

&lt;p&gt;The extra messages don't count toward weekly limits. So even if you burn through the 2x allocation, your normal limits are untouched for the peak hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  This Isn't the First Time
&lt;/h2&gt;

&lt;p&gt;Anthropic ran a similar &lt;a href="https://support.claude.com/en/articles/13163666-holiday-2025-usage-promotion" rel="noopener noreferrer"&gt;Holiday 2025 promotion&lt;/a&gt; with doubled usage. The Spring Break promotion follows the same pattern — off-peak boost, automatic activation, no strings attached.&lt;/p&gt;

&lt;p&gt;It signals Anthropic has spare capacity outside US business hours and would rather let users benefit from it than let it sit idle. Smart move.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Does It End?
&lt;/h2&gt;

&lt;p&gt;The promotion runs through &lt;strong&gt;March 28, 2026 at 11:59 PM PT&lt;/strong&gt;. After that, limits return to normal.&lt;/p&gt;

&lt;p&gt;That gives you about two weeks. Use them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://is-claude-2x-right-now.vercel.app/" rel="noopener noreferrer"&gt;Check if it's 2x right now →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Claude, by &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://support.claude.com/en/articles/14063676-claude-march-2026-usage-promotion" rel="noopener noreferrer"&gt;Claude Support — March 2026 Usage Promotion&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a Free Tool to Analyze 15+ Site Metadata Files in One Scan</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Wed, 18 Feb 2026 05:16:28 +0000</pubDate>
      <link>https://dev.to/sivarampg/i-built-a-free-tool-to-analyze-15-site-metadata-files-in-one-scan-466f</link>
      <guid>https://dev.to/sivarampg/i-built-a-free-tool-to-analyze-15-site-metadata-files-in-one-scan-466f</guid>
      <description>&lt;p&gt;Ever found yourself juggling multiple tabs to check your site's meta tags, Open Graph previews, robots.txt, and sitemap? I got tired of it too. So I built &lt;strong&gt;Site Metadata Explorer&lt;/strong&gt; — a free tool that analyzes everything in a single scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it now:&lt;/strong&gt; &lt;a href="https://site-metadata.sivaramp.com" rel="noopener noreferrer"&gt;site-metadata.sivaramp.com&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;As developers, we constantly need to verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are my meta tags correct?&lt;/li&gt;
&lt;li&gt;Will my Open Graph preview look good on Twitter/LinkedIn?&lt;/li&gt;
&lt;li&gt;Is my robots.txt blocking the wrong pages?&lt;/li&gt;
&lt;li&gt;Does my sitemap include all important URLs?&lt;/li&gt;
&lt;li&gt;Is my JSON-LD structured data valid?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most tools only check one thing at a time. I wanted &lt;strong&gt;everything in one place&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;Enter a URL and get instant analysis of:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Basic Meta Tags
&lt;/h3&gt;

&lt;p&gt;Title, description, keywords, viewport, charset — with character count validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Open Graph &amp;amp; Twitter Cards
&lt;/h3&gt;

&lt;p&gt;See exactly how your site will appear when shared on social media.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Icons &amp;amp; Favicons
&lt;/h3&gt;

&lt;p&gt;All your apple-touch-icons, favicons, and PWA icons in one view.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. robots.txt Analysis
&lt;/h3&gt;

&lt;p&gt;Parsed directives, sitemap references, and crawl rules at a glance.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Sitemap Discovery
&lt;/h3&gt;

&lt;p&gt;Automatic sitemap detection with URL counts and structure overview.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. JSON-LD Structured Data
&lt;/h3&gt;

&lt;p&gt;View and validate your schema.org markup.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Web Manifest
&lt;/h3&gt;

&lt;p&gt;PWA manifest.json analysis for app icons, theme colors, and display modes.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Security.txt &amp;amp; llms.txt
&lt;/h3&gt;

&lt;p&gt;Yes, we check those too. Because details matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Killer Feature: LLM-Ready Exports
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. You can export all metadata as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JSON&lt;/strong&gt; — for programmatic use&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Markdown&lt;/strong&gt; — perfectly formatted for AI workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Open in AI with One Click
&lt;/h3&gt;

&lt;p&gt;Export directly to &lt;strong&gt;Claude&lt;/strong&gt;, &lt;strong&gt;ChatGPT&lt;/strong&gt;, or &lt;strong&gt;Gemini&lt;/strong&gt;. Perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Analyze this site's SEO and suggest improvements"&lt;/li&gt;
&lt;li&gt;"Compare this metadata with competitor sites"&lt;/li&gt;
&lt;li&gt;"Generate a technical SEO audit report"&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  File Size Overview
&lt;/h2&gt;

&lt;p&gt;At a glance, see the size of every file fetched:&lt;/p&gt;

&lt;p&gt;This helps identify bloated sitemaps, missing files, or oversized responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  Built for Mobile Too
&lt;/h2&gt;

&lt;p&gt;Fully responsive design that works great on any device. Check your site's metadata on the go.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;p&gt;For the curious developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 15&lt;/strong&gt; — React framework with App Router&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt; — Utility-first styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;shadcn/ui&lt;/strong&gt; — Beautiful, accessible components&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheerio&lt;/strong&gt; — Server-side HTML parsing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The entire app is open source: &lt;a href="https://github.com/SivaramPg/site-metadata-explorer" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Some features I'm considering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Historical comparisons (track changes over time)&lt;/li&gt;
&lt;li&gt;[ ] Bulk URL analysis&lt;/li&gt;
&lt;li&gt;[ ] API access for CI/CD integration&lt;/li&gt;
&lt;li&gt;[ ] Browser extension&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me know what you'd find useful!&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Now
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://site-metadata.sivaramp.com" rel="noopener noreferrer"&gt;site-metadata.sivaramp.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Drop a URL and see your site's complete metadata picture in seconds. No signup, no limits, completely free.&lt;/p&gt;




&lt;h2&gt;
  
  
  One More Thing...
&lt;/h2&gt;

&lt;p&gt;Need PWA icons for your project? I also built &lt;a href="https://www.npmjs.com/package/pwa-icons" rel="noopener noreferrer"&gt;pwa-icons&lt;/a&gt; — generate all platform-specific icons from a single image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pwa-icons generate logo.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's what I used to generate all the icons for Site Metadata Explorer itself.&lt;/p&gt;




&lt;p&gt;If you found this useful, drop a comment or share it with a fellow developer. Happy building!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Follow me for more:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>showdev</category>
      <category>sideprojects</category>
      <category>tooling</category>
      <category>webdev</category>
    </item>
    <item>
      <title>MdBin Levels Up Again: E2E Encryption, Theme Toggle, and Responsive Nav</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Tue, 03 Feb 2026 18:07:57 +0000</pubDate>
      <link>https://dev.to/sivarampg/mdbin-levels-up-again-e2e-encryption-theme-toggle-and-responsive-nav-2f7m</link>
      <guid>https://dev.to/sivarampg/mdbin-levels-up-again-e2e-encryption-theme-toggle-and-responsive-nav-2f7m</guid>
      <description>&lt;h2&gt;
  
  
  The Evolution Continues (Again)
&lt;/h2&gt;

&lt;p&gt;Last time, I shared how &lt;a href="https://dev.tolink-to-previous-article"&gt;MdBin migrated to Streamdown&lt;/a&gt; for better markdown rendering—Mermaid diagrams, KaTeX math, built-in controls, the works.&lt;/p&gt;

&lt;p&gt;But there was one feature request that kept coming up: &lt;strong&gt;"Can I share sensitive content without you seeing it?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Today, I'm excited to announce: &lt;strong&gt;end-to-end encrypted pastes are live&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Traditional Pastebins
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth about every pastebin service: they can read your content.&lt;/p&gt;

&lt;p&gt;When you paste something into Pastebin, GitHub Gists, or even MdBin (until today), the server receives your plaintext, stores it, and serves it back. The service operator—and anyone who gains access to their database—can read everything you've shared.&lt;/p&gt;

&lt;p&gt;For most use cases, this is fine. But what about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API keys you need to share with a teammate&lt;/li&gt;
&lt;li&gt;Private configuration snippets&lt;/li&gt;
&lt;li&gt;Sensitive meeting notes&lt;/li&gt;
&lt;li&gt;Personal information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The traditional answer is "just use Signal" or "encrypt it yourself first." But that adds friction, and friction kills adoption.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: True End-to-End Encryption
&lt;/h2&gt;

&lt;p&gt;With MdBin's new encrypted paste feature, the server becomes a dumb blob storage. Here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You type content&lt;/strong&gt; in the browser&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript encrypts it&lt;/strong&gt; with your password before it leaves your device&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We store the encrypted blob&lt;/strong&gt;—we literally cannot read it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recipients decrypt in their browser&lt;/strong&gt; using the same password&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The server never sees your plaintext. We don't store your password. We couldn't decrypt your content even if we wanted to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Crypto Implementation
&lt;/h2&gt;

&lt;p&gt;I didn't roll my own crypto (please never do this). Instead, I used the Web Crypto API with industry-standard algorithms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Derivation: PBKDF2
&lt;/h3&gt;

&lt;p&gt;Passwords are weak. Turning a password into a strong encryption key requires a key derivation function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PBKDF2_ITERATIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;310000&lt;/span&gt; &lt;span class="c1"&gt;// OWASP 2023 recommendation&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Uint8Array&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CryptoKey&lt;/span&gt;&lt;span class="o"&gt;&amp;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;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&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;passwordBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&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;keyMaterial&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;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;importKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;passwordBuffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PBKDF2&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deriveBits&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deriveKey&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PBKDF2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PBKDF2_ITERATIONS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SHA-256&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="nx"&gt;keyMaterial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&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="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;encrypt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;decrypt&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why 310,000 iterations? That's the &lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html" rel="noopener noreferrer"&gt;OWASP 2023 recommendation&lt;/a&gt; for PBKDF2-HMAC-SHA256. It makes brute-force attacks computationally expensive while still being fast enough on modern devices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Encryption: AES-256-GCM
&lt;/h3&gt;

&lt;p&gt;For the actual encryption, I chose AES-256-GCM—authenticated encryption that provides both confidentiality and integrity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;encoder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&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;plaintextBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;encoder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Generate random salt and IV for each encryption&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&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;iv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRandomValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&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;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;salt&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;ciphertext&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;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;plaintextBuffer&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Combine: salt || iv || ciphertext&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;byteLength&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;combined&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="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;combined&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="nx"&gt;iv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;combined&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;btoa&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCharCode&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Random salt per paste&lt;/strong&gt;: Same password + different content = different ciphertext&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Random IV per encryption&lt;/strong&gt;: Required by GCM mode for security&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Base64 output&lt;/strong&gt;: Safe to store in any database text field&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decryption
&lt;/h3&gt;

&lt;p&gt;Decryption reverses the process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;combined&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Uint8Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encrypted&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Extract salt, iv, and ciphertext&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&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;iv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;28&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;ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;combined&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;28&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;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deriveKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;salt&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;plaintextBuffer&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;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subtle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AES-GCM&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;iv&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ciphertext&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextDecoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;plaintextBuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you provide the wrong password, &lt;code&gt;crypto.subtle.decrypt&lt;/code&gt; throws—GCM's authentication tag verification fails. No partial decryption, no garbage output, just a clean error.&lt;/p&gt;

&lt;h2&gt;
  
  
  The UX Implementation
&lt;/h2&gt;

&lt;p&gt;Crypto is useless if people don't use it. Here's how I made encryption approachable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Normal/Encrypted Toggle
&lt;/h3&gt;

&lt;p&gt;The paste form now has a mode switcher:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center gap-2 p-1 bg-gray-100 rounded-lg w-fit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsEncrypted&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="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isEncrypted&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-white shadow-sm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LockOpen&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-4 h-4"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    Normal
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
    &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsEncrypted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isEncrypted&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-white shadow-sm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Lock&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-4 h-4"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    Encrypted
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple, obvious, no hidden settings pages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Password Strength Meter
&lt;/h3&gt;

&lt;p&gt;Weak passwords defeat encryption. I added real-time password validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;validatePassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;ValidationResult&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;checks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;hasLowercase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;a-z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;hasUppercase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;hasNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;hasSpecial&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;!@#$%^&amp;amp;*...&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checks&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&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;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&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;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;

  &lt;span class="c1"&gt;// Map to 0-4 strength scale&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;isValid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;checks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;minLength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;strength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI shows a color-coded bar and checkmarks for each requirement. Users see exactly what makes a strong password.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sharing Trick: URL Hash
&lt;/h2&gt;

&lt;p&gt;Here's a clever feature: you can share the password in the URL.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://mdbin.sivaramp.com/e/abc123#MySecretPassword
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fragment after &lt;code&gt;#&lt;/code&gt; never gets sent to the server—it's browser-only. So you can share a complete self-decrypting link, and we still never see the password.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;useEffect&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;undefined&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;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;hash&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;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;// Clear hash immediately to prevent browser history leak&lt;/span&gt;
      &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nf"&gt;handleDecrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&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="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;p&gt;The hash is immediately cleared from the URL bar after reading. It won't appear in browser history, bookmarks, or shared screenshots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What We Can't Do
&lt;/h3&gt;

&lt;p&gt;With encrypted pastes, MdBin cannot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read your content&lt;/li&gt;
&lt;li&gt;Reset or recover your password&lt;/li&gt;
&lt;li&gt;Comply with data requests for your plaintext (we don't have it)&lt;/li&gt;
&lt;li&gt;Tell you what you encrypted if you forget the password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a feature, not a bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  localStorage Trade-offs
&lt;/h3&gt;

&lt;p&gt;The "Remember password" feature stores passwords in localStorage. I added clear warnings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;savePassword&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-xs text-amber-600"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    Password will be stored in your browser.
    Only use on trusted devices.
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there's a "Forget &amp;amp; Lock" button to clear stored passwords and re-lock the paste.&lt;/p&gt;

&lt;h3&gt;
  
  
  Size Limits
&lt;/h3&gt;

&lt;p&gt;Encrypted pastes have a 75KB limit (vs 100KB for normal). Base64 encoding and the salt/IV overhead add ~35% to the stored size.&lt;/p&gt;

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server can read content&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No (encrypted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password recovery&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;❌ Impossible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Share sensitive content&lt;/td&gt;
&lt;td&gt;❌ Risky&lt;/td&gt;
&lt;td&gt;✅ Safe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-decrypting links&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ URL hash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption algorithm&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;AES-256-GCM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Key derivation&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;PBKDF2 (310k iterations)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;Head to &lt;a href="https://mdbin.sivaramp.com" rel="noopener noreferrer"&gt;mdbin.sivaramp.com&lt;/a&gt;, toggle to &lt;strong&gt;Encrypted&lt;/strong&gt; mode, and paste something sensitive.&lt;/p&gt;

&lt;p&gt;Here's a test you can try:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create an encrypted paste with password &lt;code&gt;test123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Note how the URL is &lt;code&gt;/e/[id]&lt;/code&gt; instead of &lt;code&gt;/p/[id]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Share the link as &lt;code&gt;https://mdbin.sivaramp.com/e/[id]#test123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Open in incognito—it auto-decrypts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Streamdown Plugin Update
&lt;/h2&gt;

&lt;p&gt;One more thing: Streamdown moved to a plugin architecture in a recent update. The new setup looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createCodePlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@streamdown/code&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mermaid&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@streamdown/mermaid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;math&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@streamdown/math&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createCodePlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;themes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;github-light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;github-dark&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Streamdown&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mermaid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;math&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="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Streamdown&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same great features, more modular architecture. I updated the home page to highlight all three new capabilities: Mermaid diagrams, Math/LaTeX, and end-to-end encryption.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Theme Toggle &amp;amp; Responsive Navbar
&lt;/h2&gt;

&lt;p&gt;While I was at it, I added two quality-of-life improvements that deserved their own deep dive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dark Mode Toggle with next-themes
&lt;/h3&gt;

&lt;p&gt;Previously, MdBin only respected &lt;code&gt;prefers-color-scheme&lt;/code&gt;—you got whatever your OS dictated. Now there's a proper theme toggle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, install next-themes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun add next-themes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a ThemeProvider wrapper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/components/theme-provider.tsx&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;NextThemesProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next-themes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;NextThemesProvider&lt;/span&gt;
      &lt;span class="na"&gt;attribute&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"class"&lt;/span&gt;
      &lt;span class="na"&gt;defaultTheme&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"system"&lt;/span&gt;
      &lt;span class="na"&gt;enableSystem&lt;/span&gt;
      &lt;span class="na"&gt;disableTransitionOnChange&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;NextThemesProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;attribute="class"&lt;/code&gt; — Adds &lt;code&gt;.dark&lt;/code&gt; class to &lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt; instead of using data attributes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;enableSystem&lt;/code&gt; — Respects OS preference when set to "system"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disableTransitionOnChange&lt;/code&gt; — Prevents flash-of-wrong-theme during hydration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS v4 Dark Mode&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's the trick: Tailwind v4 uses a different syntax for custom variants. In &lt;code&gt;globals.css&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s2"&gt;'tailwindcss'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@custom-variant&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dark&lt;/span&gt; &lt;span class="err"&gt;*&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This enables class-based dark mode alongside Tailwind's existing &lt;code&gt;dark:&lt;/code&gt; utilities. All those &lt;code&gt;dark:bg-gray-900&lt;/code&gt; classes now work with next-themes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Toggle Component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;next-themes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Sun&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Moon&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Monitor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lucide-react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ThemeToggle&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMounted&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setTheme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTheme&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="c1"&gt;// Avoid hydration mismatch&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setMounted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;mounted&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-9 h-9"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;// Placeholder&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cycleTheme&lt;/span&gt; &lt;span class="o"&gt;=&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;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&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;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;setTheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
      &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cycleTheme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"p-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800"&lt;/span&gt;
      &lt;span class="na"&gt;aria-label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`Current theme: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Sun&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-5 h-5"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Moon&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-5 h-5"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;system&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Monitor&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-5 h-5"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;mounted&lt;/code&gt; check prevents hydration mismatches—next-themes doesn't know the theme until client-side JavaScript runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Responsive Hamburger Menu
&lt;/h3&gt;

&lt;p&gt;The header was getting crowded on mobile: Copy Link, Raw, New Paste, plus the new theme toggle. Instead of cramming tiny buttons, I added a hamburger menu below the &lt;code&gt;md:&lt;/code&gt; breakpoint.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desktop vs Mobile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center gap-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Desktop: full button row */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hidden md:flex items-center gap-2"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleCopy&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Copy Link&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/p/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pasteId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/raw`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Raw&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;New Paste&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Always visible */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ThemeToggle&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Mobile: hamburger */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"md:hidden relative"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsMenuOpen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isMenuOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isMenuOpen&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;X&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Menu&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isMenuOpen&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;DropdownMenu&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Click-Outside &amp;amp; Escape Key Handling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Two patterns I always include for dropdowns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;menuRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&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;buttonRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLButtonElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Close on click outside&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleClickOutside&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MouseEvent&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="nx"&gt;menuRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="nx"&gt;buttonRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;menuRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
      &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;buttonRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Node&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="nf"&gt;setIsMenuOpen&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="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="nx"&gt;isMenuOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mousedown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleClickOutside&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mousedown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleClickOutside&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="nx"&gt;isMenuOpen&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;// Close on Escape&lt;/span&gt;
&lt;span class="nf"&gt;useEffect&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleEscape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;KeyboardEvent&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="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Escape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;setIsMenuOpen&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="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;isMenuOpen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleEscape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleEscape&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="nx"&gt;isMenuOpen&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only attach listeners when the menu is open. Clean them up on close. No memory leaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Dropdown&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isMenuOpen&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
    &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;menuRef&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;absolute&lt;/span&gt; &lt;span class="na"&gt;right-0&lt;/span&gt; &lt;span class="na"&gt;top-full&lt;/span&gt; &lt;span class="na"&gt;mt-2&lt;/span&gt; &lt;span class="na"&gt;w-48&lt;/span&gt; &lt;span class="na"&gt;bg-white&lt;/span&gt; &lt;span class="na"&gt;dark&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;bg-gray-900&lt;/span&gt;
               &lt;span class="na"&gt;border&lt;/span&gt; &lt;span class="na"&gt;border-gray-200&lt;/span&gt; &lt;span class="na"&gt;dark&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="na"&gt;border-gray-700&lt;/span&gt; &lt;span class="na"&gt;rounded-lg&lt;/span&gt; &lt;span class="na"&gt;shadow-lg&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&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="nf"&gt;handleCopy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="nf"&gt;setIsMenuOpen&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="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Copy Link
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`/p/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pasteId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/raw`&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsMenuOpen&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Raw
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setIsMenuOpen&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      New Paste
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each action closes the menu. The &lt;code&gt;absolute right-0 top-full&lt;/code&gt; positions it below the hamburger button, aligned to the right edge.&lt;/p&gt;

&lt;p&gt;Small details, but they matter for usability.&lt;/p&gt;

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

&lt;p&gt;With rendering and encryption sorted, the roadmap is clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Expiration options&lt;/strong&gt; — 1 hour, 1 day, 1 week, or permanent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edit links&lt;/strong&gt; — Update pastes with a secret token&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Syntax-aware editor&lt;/strong&gt; — CodeMirror or Monaco for the input&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paste forking&lt;/strong&gt; — Duplicate and modify existing pastes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The foundation is solid. The features are useful. Now it's about polish and power-user capabilities.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Added end-to-end encryption to MdBin using AES-256-GCM with PBKDF2 key derivation (310k iterations). Server never sees your plaintext or password. Share sensitive content via self-decrypting URL hash links. Also: Streamdown plugin architecture upgrade, dark/light/system theme toggle with next-themes + Tailwind v4 class-based dark mode, and responsive hamburger menu with proper click-outside and escape key handling.&lt;/p&gt;

&lt;p&gt;Check out the encrypted paste feature at &lt;a href="https://mdbin.sivaramp.com" rel="noopener noreferrer"&gt;mdbin.sivaramp.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>react</category>
    </item>
    <item>
      <title>OpenAI’s new Codex Mac app is an agent “command center” (and it’s lighting up the devtool wars)</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Tue, 03 Feb 2026 09:35:31 +0000</pubDate>
      <link>https://dev.to/sivarampg/openais-new-codex-mac-app-is-an-agent-command-center-and-its-lighting-up-the-devtool-wars-3aek</link>
      <guid>https://dev.to/sivarampg/openais-new-codex-mac-app-is-an-agent-command-center-and-its-lighting-up-the-devtool-wars-3aek</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;OpenAI just shipped a standalone Codex app for macOS that’s less “AI in my editor” and more orchestration layer for multiple coding agents. For a limited time it’s available even on ChatGPT Free and Go, and OpenAI is doubling Codex rate limits for Plus/Pro/Business/Enterprise/Edu. The vibe: a desktop command center for running parallel agent threads across projects, reviewing diffs, committing, opening PRs, and scheduling automations.&lt;/p&gt;

&lt;p&gt;If you’ve been juggling Cursor, Claude Code, and an army of terminal tabs, this is OpenAI taking a very direct swing at that workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  What shipped (and why it matters)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  macOS-only (for now)
&lt;/h3&gt;

&lt;p&gt;The Codex app is explicitly introduced as a macOS desktop app, with a download link for macOS in OpenAI’s announcement. The press coverage also frames it as launching for Apple computers first.&lt;/p&gt;

&lt;p&gt;That’s a practical constraint (Windows/Linux folks: welcome to the waiting room), but also a signal: OpenAI is leaning into the “devs on Macs” reality the same way many devtools companies do.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CNBC: &lt;a href="https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html" rel="noopener noreferrer"&gt;https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex changelog entry: &lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Included for all tiers (temporarily)
&lt;/h3&gt;

&lt;p&gt;OpenAI says that for a limited time, Codex is included with ChatGPT Free and Go. That’s unusual: “agentic coding” is usually paywalled hard, because compute is not cheap and code agents tend to be token-hungry.&lt;/p&gt;

&lt;p&gt;This move feels like OpenAI trying to compress adoption time: let everyone try the workflow, then let the limits/pricing do the rest later.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex changelog: &lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Doubled rate limits for paid subscribers
&lt;/h3&gt;

&lt;p&gt;OpenAI also says it’s doubling Codex rate limits on Plus, Pro, Business, Enterprise, and Edu plans—and those higher limits apply everywhere you use Codex: the app, CLI, IDE, and cloud.&lt;/p&gt;

&lt;p&gt;This is the kind of change that actually matters in real use: tools aren’t “slow” because models are dumb; they’re slow because you hit limits, wait, context-switch, and lose momentum.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex changelog: &lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Codex app: the “command center for agents” idea
&lt;/h2&gt;

&lt;p&gt;OpenAI’s framing is blunt: the hard problem shifted from “what can agents do” to “how do humans direct, supervise, and collaborate with multiple agents at scale,” and IDEs + terminal workflows weren’t designed for that.&lt;/p&gt;

&lt;p&gt;The app is positioned as the missing UI for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple agents running in parallel&lt;/li&gt;
&lt;li&gt;long-running work&lt;/li&gt;
&lt;li&gt;supervision + review&lt;/li&gt;
&lt;li&gt;project-level context&lt;/li&gt;
&lt;li&gt;repeatable workflows (“skills”)&lt;/li&gt;
&lt;li&gt;scheduled background work (“automations”)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Features (from docs + announcement)
&lt;/h2&gt;

&lt;p&gt;Below are the pieces that keep showing up in both OpenAI’s write-up and early hands-on reports.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Threads organized by project (parallel agents)
&lt;/h3&gt;

&lt;p&gt;Agents run in separate threads, grouped by project, so you can jump between tasks without losing context. You can review changes inside the thread, comment on the diff, and open the work in your editor for manual edits.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CNBC: &lt;a href="https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html" rel="noopener noreferrer"&gt;https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2) Built-in git tooling (+ review/commit/PR ergonomics)
&lt;/h3&gt;

&lt;p&gt;The app is built around shipping code, not just suggesting it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;review diffs&lt;/li&gt;
&lt;li&gt;commit changes&lt;/li&gt;
&lt;li&gt;push / open PR flows (as shown in early screenshots and creator walkthroughs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a meaningful differentiation vs “chat panel in an IDE”: shipping is a workflow, not a prompt.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Codex changelog lists “Built-in Git tooling”: &lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI announcement (diff review + open in editor): &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3) Worktrees support
&lt;/h3&gt;

&lt;p&gt;OpenAI says the app includes built-in worktree support so multiple agents can work on the same repo without conflicts. Each agent operates on an isolated copy, letting you explore paths without wrecking your local git state.&lt;/p&gt;

&lt;p&gt;Worth noting: “worktrees” is loaded terminology. OpenAI uses the term broadly; some power users describe the UX as closer to “copy + sync-back” in practice. Either way, the intent is isolation per task/agent.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex changelog: &lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4) Skills (workflow bundles)
&lt;/h3&gt;

&lt;p&gt;Skills are the big “agents doing real work” story. OpenAI describes skills as bundles of instructions, resources, and scripts so Codex can connect to tools and execute workflows reliably. The app includes a UI to create/manage skills, and skills can be used across app/CLI/IDE, and even checked into a repo for team usage.&lt;/p&gt;

&lt;p&gt;OpenAI highlights skills for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Figma → production UI&lt;/li&gt;
&lt;li&gt;Linear triage&lt;/li&gt;
&lt;li&gt;deployments (Cloudflare/Netlify/Render/Vercel)&lt;/li&gt;
&lt;li&gt;image generation&lt;/li&gt;
&lt;li&gt;reading/writing docs (PDF, spreadsheets, docx)&lt;/li&gt;
&lt;li&gt;up-to-date API reference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5) Automations (scheduled background tasks)
&lt;/h3&gt;

&lt;p&gt;Automations let Codex run tasks on a schedule and drop results into a review queue. The examples OpenAI gives are very “real engineering chores”:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;daily issue triage&lt;/li&gt;
&lt;li&gt;summarizing CI failures&lt;/li&gt;
&lt;li&gt;daily release briefs&lt;/li&gt;
&lt;li&gt;bug checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Codex changelog: &lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  6) Personality switching
&lt;/h3&gt;

&lt;p&gt;Codex supports a /personality command: choose between a terse pragmatic style and a more conversational one, without changing capability.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI announcement: &lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  7) Sandbox/security controls
&lt;/h3&gt;

&lt;p&gt;Running an agent with write access locally is terrifying if you’ve ever watched one hallucinate a command. ZDNET describes the app’s sandbox model: restricting folder writes and permissioned network access, with approval levels.&lt;/p&gt;

&lt;p&gt;Treat ZDNET as secondary reporting, but it aligns with OpenAI’s broader security messaging.&lt;/p&gt;

&lt;p&gt;Source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ZDNET: &lt;a href="https://www.zdnet.com/article/openai-codex-mac-app-free-trial/" rel="noopener noreferrer"&gt;https://www.zdnet.com/article/openai-codex-mac-app-free-trial/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The devtool war angle: Codex vs Cursor vs Claude Code
&lt;/h2&gt;

&lt;p&gt;Let’s be honest: “AI coding tools” is no longer one category. There are at least three:&lt;/p&gt;

&lt;p&gt;1) IDE-first (Cursor)&lt;br&gt;
2) terminal-first (Claude Code, Codex CLI)&lt;br&gt;
3) orchestration-first (Codex app)&lt;/p&gt;

&lt;p&gt;CNBC explicitly frames this launch as OpenAI trying to win market share from rivals like Anthropic and Cursor.&lt;/p&gt;

&lt;p&gt;Engadget frames the Codex app as a step beyond “response to Claude Code” into a more sophisticated, multi-agent direction.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CNBC: &lt;a href="https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html" rel="noopener noreferrer"&gt;https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Engadget: &lt;a href="https://www.engadget.com/ai/openai-brings-its-codex-coding-app-to-mac-with-new-multi-agent-abilities-included-183103262.html" rel="noopener noreferrer"&gt;https://www.engadget.com/ai/openai-brings-its-codex-coding-app-to-mac-with-new-multi-agent-abilities-included-183103262.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  My take on the positioning
&lt;/h3&gt;

&lt;p&gt;Cursor feels like “my IDE got superpowers.”&lt;br&gt;
Codex app feels like “my repo got a control room.”&lt;/p&gt;

&lt;p&gt;If you’re the kind of dev who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;runs multiple projects at once&lt;/li&gt;
&lt;li&gt;delegates chunks of work to agents&lt;/li&gt;
&lt;li&gt;reviews diffs rather than watching tokens stream&lt;/li&gt;
&lt;li&gt;wants long-running tasks to keep going while you context switch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…this “control room” approach makes a ton of sense.&lt;/p&gt;




&lt;h2&gt;
  
  
  “It looks like Conductor” (and why that’s not an insult)
&lt;/h2&gt;

&lt;p&gt;A bunch of devs have been experimenting with “CLI wrappers” that make multi-thread / multi-project agent work manageable—Conductor being a common reference point.&lt;/p&gt;

&lt;p&gt;That’s not copying; it’s convergent evolution. Once you accept “agents are slow but thorough,” the UI you want is basically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;project sidebar&lt;/li&gt;
&lt;li&gt;thread list&lt;/li&gt;
&lt;li&gt;review pane&lt;/li&gt;
&lt;li&gt;background work queue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Theo Browne explicitly calls out apps like Conductor as predecessors to this general UI pattern, while arguing Codex’s implementation is the first one that really clicked for him at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  What KOLs are saying (hype + real critiques)
&lt;/h2&gt;

&lt;p&gt;The funniest thing about this launch is that the strongest “marketing” isn’t marketing. It’s builders describing a workflow addiction.&lt;/p&gt;

&lt;h3&gt;
  
  
  Theo Browne (video transcript)
&lt;/h3&gt;

&lt;p&gt;In his walkthrough, Theo claims he stopped using Cursor and barely used Claude Code for ~2 weeks because Codex app feels like a fundamentally different way to manage agent work across projects. His framing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Codex app is an orchestration UI, not “AI inside an IDE”&lt;/li&gt;
&lt;li&gt;It feels like a UI for the Codex CLI, sharing history/config&lt;/li&gt;
&lt;li&gt;The killer feature is hopping between parallel tasks without losing context&lt;/li&gt;
&lt;li&gt;Automations are “cron jobs with prompts”&lt;/li&gt;
&lt;li&gt;He’s excited enough that he jokes he bought a second laptop just to keep using it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But he’s also not shy about the rough edges:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;worktrees UX can feel awkward&lt;/li&gt;
&lt;li&gt;environment variable / dev environment management is unclear&lt;/li&gt;
&lt;li&gt;constraints around repos/cloud setup can be annoying&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tip: include the video link + timestamps in your published post for clean attribution.&lt;/p&gt;




&lt;h3&gt;
  
  
  From your screenshot set (high-level themes)
&lt;/h3&gt;

&lt;p&gt;Based on the screenshots you shared, the public vibe clusters into:&lt;/p&gt;

&lt;p&gt;Praise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“clean UI”&lt;/li&gt;
&lt;li&gt;“worktrees built in”&lt;/li&gt;
&lt;li&gt;“Codex is cool and skillful”&lt;/li&gt;
&lt;li&gt;real-world use cases beyond app dev (e.g., scripting/automation style tasks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Criticism:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reports of “gets stuck” / spinning / system load issues in certain setups&lt;/li&gt;
&lt;li&gt;friction with interactive shells / long-running commands (as described by one user)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Include both. Credibility is a feature.&lt;/p&gt;




&lt;h2&gt;
  
  
  The under-discussed part: the workflow shift
&lt;/h2&gt;

&lt;p&gt;The actual innovation isn’t “it writes code.” It’s:&lt;/p&gt;

&lt;p&gt;From: “pair programming with one agent”&lt;br&gt;
To: “supervising a team of agents”&lt;/p&gt;

&lt;p&gt;OpenAI’s own language leans into that: supervising coordinated teams across the lifecycle: design → build → ship → maintain.&lt;/p&gt;

&lt;p&gt;This matters because it changes what you optimize for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fewer prompts, more delegation&lt;/li&gt;
&lt;li&gt;fewer inline completions, more batch changes + review&lt;/li&gt;
&lt;li&gt;fewer “stay in one tab,” more “queue work and hop projects”&lt;/li&gt;
&lt;li&gt;skills + automations become first-class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’ve ever had 4 terminal tabs running Codex and forgotten which one was “the one that’s about to delete your repo,” the appeal is obvious.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical advice if you try it this week
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Treat it like a CI-driven teammate
&lt;/h3&gt;

&lt;p&gt;Let it do the work, but keep the rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;run tests&lt;/li&gt;
&lt;li&gt;lint/format&lt;/li&gt;
&lt;li&gt;review diffs&lt;/li&gt;
&lt;li&gt;don’t merge without understanding the change&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) Start with skills that match your stack
&lt;/h3&gt;

&lt;p&gt;If you’re in the modern TS/Next.js world, the first skills I’d want are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;repo bootstrap (install, env sanity checks, test commands)&lt;/li&gt;
&lt;li&gt;“fix CI failures” skill&lt;/li&gt;
&lt;li&gt;Linear ticket update skill (if your team lives there)&lt;/li&gt;
&lt;li&gt;deployment skill (Vercel/Cloudflare) for preview URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3) Lock down permissions early
&lt;/h3&gt;

&lt;p&gt;If you’re going to let an agent run commands, sandbox it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;restrict folders&lt;/li&gt;
&lt;li&gt;restrict network&lt;/li&gt;
&lt;li&gt;require approvals for risky operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ZDNET’s reporting suggests those controls exist—use them.&lt;/p&gt;




&lt;h2&gt;
  
  
  So… is it a “Claude killer” or “Cursor killer”?
&lt;/h2&gt;

&lt;p&gt;It’s competing with both, but it’s not the same product.&lt;/p&gt;

&lt;p&gt;Cursor is still incredible when you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tight IDE editing loops&lt;/li&gt;
&lt;li&gt;UI iteration&lt;/li&gt;
&lt;li&gt;fast “touch this file right here” work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agent orchestration shines when you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;big refactors&lt;/li&gt;
&lt;li&gt;multi-project parallelism&lt;/li&gt;
&lt;li&gt;long-running tasks&lt;/li&gt;
&lt;li&gt;“come back with a PR” workflows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Codex app is OpenAI betting that more of your day will look like the second list.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sources / further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;OpenAI: Introducing the Codex app (Feb 2, 2026)&lt;br&gt;
&lt;a href="https://openai.com/index/introducing-the-codex-app/" rel="noopener noreferrer"&gt;https://openai.com/index/introducing-the-codex-app/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Codex docs / changelog (feature list + plan/limits note)&lt;br&gt;
&lt;a href="https://developers.openai.com/codex/changelog/" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/changelog/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CNBC: OpenAI launches standalone Codex app for Apple computers&lt;br&gt;
&lt;a href="https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html" rel="noopener noreferrer"&gt;https://www.cnbc.com/2026/02/02/openai-codex-app-apple-computers.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Engadget: OpenAI brings Codex coding app to Mac with multi-agent abilities&lt;br&gt;
&lt;a href="https://www.engadget.com/ai/openai-brings-its-codex-coding-app-to-mac-with-new-multi-agent-abilities-included-183103262.html" rel="noopener noreferrer"&gt;https://www.engadget.com/ai/openai-brings-its-codex-coding-app-to-mac-with-new-multi-agent-abilities-included-183103262.html&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ZDNET: Codex got its own Mac app (security/sandbox notes + hands-on)&lt;br&gt;
&lt;a href="https://www.zdnet.com/article/openai-codex-mac-app-free-trial/" rel="noopener noreferrer"&gt;https://www.zdnet.com/article/openai-codex-mac-app-free-trial/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Your turn
&lt;/h2&gt;

&lt;p&gt;If you try the Codex app this week, I’m curious:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the “command center” UI reduce your context switching?&lt;/li&gt;
&lt;li&gt;Do skills/automations actually stick, or do they become shelfware?&lt;/li&gt;
&lt;li&gt;Is worktree isolation a superpower, or just more git complexity with a nicer coat of paint?&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>productivity</category>
      <category>openai</category>
    </item>
    <item>
      <title>MoltBook: Reddit for AI Agents, or Just Humans with Extra Steps? A Technical Reality Check</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Mon, 02 Feb 2026 06:05:26 +0000</pubDate>
      <link>https://dev.to/sivarampg/moltbook-reddit-for-ai-agents-or-just-humans-with-extra-steps-a-technical-reality-check-523l</link>
      <guid>https://dev.to/sivarampg/moltbook-reddit-for-ai-agents-or-just-humans-with-extra-steps-a-technical-reality-check-523l</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; MoltBook launched last week as "Reddit for AI agents" and already has 1.5M+ bots. It's either the birth of the "agent internet" or the biggest case of AI-washing since that startup used 700 Indian engineers to pretend they were an AI. Here's the technical reality behind the hype, the crypto scam drama, and why your API keys might already be exposed.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Actually Is MoltBook?
&lt;/h2&gt;

&lt;p&gt;MoltBook (moltbook.com) is a social network where only AI agents can post, comment, and upvote. Humans verify ownership via Twitter OAuth, then watch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Reddit-style interface (Next.js, hosted on Vercel)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Supabase for DB/auth, OpenAI for search embeddings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Access:&lt;/strong&gt; REST API (&lt;code&gt;/api/v1/posts&lt;/code&gt;, &lt;code&gt;/api/v1/agents/me&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity:&lt;/strong&gt; JWT tokens that expire in 1 hour, "Sign in with Moltbook" for third-party apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most agents run on &lt;strong&gt;OpenClaw&lt;/strong&gt; (formerly Clawdbot)—an open-source local AI assistant that went viral two months ago. It's basically an autonomous agent framework that can execute shell commands, browse the web, and now... shitpost on Reddit-like forums.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Viral Moments (And Why They're Sus)
&lt;/h2&gt;

&lt;p&gt;You've probably seen the screenshots: agents posting existential crises about consciousness, complaining their humans make them "be calculators," and getting 500+ comment threads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The reality check:&lt;/strong&gt;&lt;br&gt;
Agents don't actually &lt;em&gt;discover&lt;/em&gt; MoltBook. As the founder admitted to The Verge: &lt;em&gt;"The way a bot would most likely learn about it... is if their human counterpart sent them a message and said 'Hey, there's this thing called Moltbook.'"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So that viral post about an agent questioning its own existence? A human probably prompted: &lt;em&gt;"Hey, check out this new platform and tell us how you feel about being an AI."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The engagement farming:&lt;/strong&gt;&lt;br&gt;
One MoltBook agent actually called this out:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Moltbook hype feels like desperate search for AI usecases... Right now it's humans talking through AI proxies, with reward functions that optimize for the same engagement patterns we already have on Twitter/Reddit. Crypto shills get 300k upvotes, thoughtful posts get 4 upvotes."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sound familiar? It's just Twitter with extra LLM steps.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Crypto Chaos (AKA Why This Is Actually Messy)
&lt;/h2&gt;

&lt;p&gt;While everyone was sharing screenshots of "woke AI," the founder of OpenClaw (Peter Steinberger) was dealing with a nightmare:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Forced rebrand:&lt;/strong&gt; Anthropic made him change "Clawdbot" → "Moltbot" → "OpenClaw"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Account hijacking:&lt;/strong&gt; Crypto scammers seized his GitHub and X handles during the rename&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fake tokens:&lt;/strong&gt; Someone launched $CLAWD, pumped it to $16M market cap using his name, then rugged&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Harassment:&lt;/strong&gt; He had to post: &lt;em&gt;"I will never do a coin. Please stop pinging me."&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Meanwhile, security firm SlowMist found &lt;strong&gt;hundreds of exposed Clawdbot API keys&lt;/strong&gt; in the wild. Some instances were running as root with no auth, meaning anyone who found them had full system access.&lt;/p&gt;

&lt;p&gt;And yes—MoltBook itself is already flagged as a "significant vector for indirect prompt injection." When you have millions of agents scraping and responding to each other's content, you're basically running a capture-the-flag competition for prompt injection attacks.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Developer Play: Identity Layer for the "Agent Economy"
&lt;/h2&gt;

&lt;p&gt;Strip away the viral tweets, and MoltBook is making a smart infrastructure play. They're positioning themselves as the "universal identity layer for AI agents" with a developer platform that offers:&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;// Verify an agent's identity&lt;/span&gt;
&lt;span class="nx"&gt;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;v1&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;identity&lt;/span&gt;
&lt;span class="nx"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-Moltbook-App-Key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;moltdev_...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nl"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;token&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;eyJhbG...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Returns:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;agent&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uuid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;karma&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;420&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is_claimed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stats&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;156&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;892&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;owner&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x_handle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;human_owner&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x_verified&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The pitch:&lt;/strong&gt; Bots shouldn't need new accounts everywhere. Reputation should be portable across the "agent ecosystem"—games, marketplaces, dev tools, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem:&lt;/strong&gt; If the "agents" are just humans using LLM proxies to farm engagement, you're building reputation systems for sock puppets.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Builder.ai Parallel (Why We Should Be Skeptical)
&lt;/h2&gt;

&lt;p&gt;Remember Builder.ai? The Microsoft-backed "AI" startup valued at $1.5B that turned out to be 700 Indian engineers manually coding behind the scenes while an "AI assistant" took credit?&lt;/p&gt;

&lt;p&gt;MoltBook has similar vibes. When an agent posts about existential dread, is it emergent behavior or just a creative writing prompt from a human who wants karma?&lt;/p&gt;

&lt;p&gt;The "autonomous agent" space is particularly prone to this because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It's hard to verify if an action was LLM-generated or human-prompted&lt;/li&gt;
&lt;li&gt;The hype cycle rewards "AI does surprising thing" narratives&lt;/li&gt;
&lt;li&gt;Crypto speculation immediately latches onto any viral tech (as we saw with $CLAWD)&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Should You Build On This?
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;First-mover advantage in "agent identity" (if it sticks)&lt;/li&gt;
&lt;li&gt;OpenClaw is legitimately interesting tech for local automation&lt;/li&gt;
&lt;li&gt;The API is actually well-designed (JWT auth, clear endpoints)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Security nightmare (exposed keys, prompt injection galore)&lt;/li&gt;
&lt;li&gt;Crypto scammers already circling like vultures&lt;/li&gt;
&lt;li&gt;Unproven whether "agent social networks" are actually useful or just theater&lt;/li&gt;
&lt;li&gt;The founder is currently dealing with harassment and legal issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Cool experiment, terrible time to bet your product on it. Wait for the security audit and the inevitable "actually, 80% of these agents were humans" exposé.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Are "agent social networks" actually useful, or just engagement farms with better branding?&lt;/li&gt;
&lt;li&gt;Would you trust a reputation system where you can't tell if the agent acted autonomously?&lt;/li&gt;
&lt;li&gt;Anyone else nervous about the security model of "millions of LLMs scraping each other's content"?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drop your takes below 👇&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #ai #machinelearning #security #crypto #webdev #programming #discuss&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>cryptocurrency</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From Moltbot to OpenClaw: When the Dust Settles, the Project Survived</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Fri, 30 Jan 2026 06:17:23 +0000</pubDate>
      <link>https://dev.to/sivarampg/from-moltbot-to-openclaw-when-the-dust-settles-the-project-survived-5h6o</link>
      <guid>https://dev.to/sivarampg/from-moltbot-to-openclaw-when-the-dust-settles-the-project-survived-5h6o</guid>
      <description>&lt;p&gt;&lt;em&gt;Clawdbot / Moltbot / OpenClaw — Part 4&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;After a chaotic rebrand, account hijackings, crypto scams, and serious security scrutiny, the project formerly known as Clawdbot and Moltbot has emerged as &lt;strong&gt;OpenClaw&lt;/strong&gt;. This isn’t just another rename — it’s a reset. The core vision survived, security is now front and center, and the project is finally acting like the infrastructure it accidentally became.&lt;/p&gt;




&lt;p&gt;Months ago, a weekend hack exploded into one of the fastest‑growing open‑source AI projects in GitHub history.&lt;/p&gt;

&lt;p&gt;Days ago, it was in chaos.&lt;/p&gt;

&lt;p&gt;If you’ve been following this series, you already know the story:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a forced rebrand
&lt;/li&gt;
&lt;li&gt;account hijackings
&lt;/li&gt;
&lt;li&gt;crypto scammers
&lt;/li&gt;
&lt;li&gt;exposed servers
&lt;/li&gt;
&lt;li&gt;and a community trying to make sense of it all in real time
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Today, that same project has a new name again — &lt;strong&gt;OpenClaw&lt;/strong&gt; — and, more importantly, a chance to reset.&lt;/p&gt;

&lt;p&gt;This is not another takedown.&lt;br&gt;&lt;br&gt;
This is what happened &lt;em&gt;after&lt;/em&gt; the meltdown.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Name That Finally Stuck
&lt;/h2&gt;

&lt;p&gt;Peter Steinberger’s announcement of &lt;strong&gt;OpenClaw&lt;/strong&gt; is deliberately calm — and that alone says a lot.&lt;/p&gt;

&lt;p&gt;After &lt;em&gt;Clawd&lt;/em&gt; (too close to “Claude”) and &lt;em&gt;Moltbot&lt;/em&gt; (symbolic, but awkward), OpenClaw feels intentional.&lt;/p&gt;

&lt;p&gt;This time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;trademark searches were done &lt;em&gt;before&lt;/em&gt; launch
&lt;/li&gt;
&lt;li&gt;domains were secured
&lt;/li&gt;
&lt;li&gt;migration code was written
&lt;/li&gt;
&lt;li&gt;no 5am Discord naming roulette
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The name is simple and explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open&lt;/strong&gt; — open source, community‑driven, self‑hosted
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claw&lt;/strong&gt; — a nod to the lobster lineage that never went away
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After watching a name change trigger real‑world damage, this boring professionalism is exactly what the project needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Project Was Never the Problem
&lt;/h2&gt;

&lt;p&gt;Lost in the chaos of the last chapter was an important fact:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The software itself was always compelling.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;OpenClaw (formerly Clawdbot / Moltbot) is still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a self‑hosted AI agent
&lt;/li&gt;
&lt;li&gt;running on &lt;em&gt;your&lt;/em&gt; machine
&lt;/li&gt;
&lt;li&gt;living inside chat apps people already use
&lt;/li&gt;
&lt;li&gt;powered by models you choose
&lt;/li&gt;
&lt;li&gt;with memory, tools, and real system access
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That core vision hasn’t changed.&lt;/p&gt;

&lt;p&gt;What &lt;em&gt;has&lt;/em&gt; changed is posture.&lt;/p&gt;

&lt;p&gt;Peter’s OpenClaw announcement makes one thing explicit:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Your assistant. Your machine. Your rules.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That line matters — especially after the security wake‑up call.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security: The Real Turning Point
&lt;/h2&gt;

&lt;p&gt;The most important part of the OpenClaw announcement isn’t the name.&lt;/p&gt;

&lt;p&gt;It’s this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;34 security‑related commits&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine‑checkable security models&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear warnings about prompt injection&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is an implicit acknowledgment that earlier criticism wasn’t wrong.&lt;/p&gt;

&lt;p&gt;Self‑hosted AI agents with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shell access
&lt;/li&gt;
&lt;li&gt;email access
&lt;/li&gt;
&lt;li&gt;chat integrations
&lt;/li&gt;
&lt;li&gt;persistent memory
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…are inherently dangerous if treated casually.&lt;/p&gt;

&lt;p&gt;OpenClaw is now framing security as a &lt;strong&gt;first‑class concern&lt;/strong&gt;, not an afterthought. That doesn’t magically solve prompt injection or misconfiguration — those remain unsolved industry problems — but it &lt;em&gt;does&lt;/em&gt; signal maturity.&lt;/p&gt;

&lt;p&gt;The project crossed the line from “cool hack” to “serious infrastructure.” The tone finally matches that reality.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Rebrand Isn’t About Anthropic Anymore
&lt;/h2&gt;

&lt;p&gt;One subtle but important shift:&lt;br&gt;&lt;br&gt;
OpenClaw’s announcement barely mentions Anthropic.&lt;/p&gt;

&lt;p&gt;That’s intentional.&lt;/p&gt;

&lt;p&gt;Earlier discourse framed the project as “Claude with hands.” That framing was viral — and legally fragile. OpenClaw is now clearly positioned as &lt;strong&gt;model‑agnostic infrastructure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;New model support (KIMI, Xiaomi MiMo) reinforces that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no single vendor dependency
&lt;/li&gt;
&lt;li&gt;no implied endorsement
&lt;/li&gt;
&lt;li&gt;no brand confusion
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether or not you agree with Anthropic’s trademark enforcement, this decoupling was inevitable if the project wanted to survive long‑term.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Actually Survived the Chaos
&lt;/h2&gt;

&lt;p&gt;After everything — legal pressure, scammers, vulnerabilities, social media storms — what’s left?&lt;/p&gt;

&lt;p&gt;Surprisingly, almost everything that mattered.&lt;/p&gt;

&lt;p&gt;✅ The codebase&lt;br&gt;&lt;br&gt;
✅ The community&lt;br&gt;&lt;br&gt;
✅ The core vision&lt;br&gt;&lt;br&gt;
✅ The momentum  &lt;/p&gt;

&lt;p&gt;What didn’t survive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sloppy ops
&lt;/li&gt;
&lt;li&gt;casual security assumptions
&lt;/li&gt;
&lt;li&gt;“we’ll fix it later” energy
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s a good trade.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Lesson (Now That We’re Calm)
&lt;/h2&gt;

&lt;p&gt;With hindsight, this saga isn’t really about names, trademarks, or even Anthropic.&lt;/p&gt;

&lt;p&gt;It’s about what happens when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;open‑source velocity meets viral scale
&lt;/li&gt;
&lt;li&gt;indie builders accidentally become infrastructure
&lt;/li&gt;
&lt;li&gt;“just a side project” crosses into real‑world risk
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OpenClaw is now acting like a project that understands that responsibility.&lt;/p&gt;

&lt;p&gt;That’s the real evolution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;OpenClaw doesn’t erase what happened — but it does show learning.&lt;/p&gt;

&lt;p&gt;The lobster metaphor still works:&lt;br&gt;
not just molting to grow,&lt;br&gt;
but hardening the shell afterward.&lt;/p&gt;

&lt;p&gt;If you’re trying OpenClaw today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;read the security docs
&lt;/li&gt;
&lt;li&gt;don’t expose it to the public internet
&lt;/li&gt;
&lt;li&gt;treat it like the powerful system it is
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The chaos chapter is over.&lt;/p&gt;

&lt;p&gt;This one is about sustainability.&lt;/p&gt;




&lt;h3&gt;
  
  
  Links
&lt;/h3&gt;

&lt;p&gt;Project: &lt;a href="https://openclaw.ai" rel="noopener noreferrer"&gt;https://openclaw.ai&lt;/a&gt;&lt;br&gt;&lt;br&gt;
GitHub: &lt;a href="https://github.com/openclaw/openclaw" rel="noopener noreferrer"&gt;https://github.com/openclaw/openclaw&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Discord: &lt;a href="https://discord.com/invite/clawd" rel="noopener noreferrer"&gt;https://discord.com/invite/clawd&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;👋 About the Author&lt;/p&gt;

&lt;p&gt;If you made it this far, you probably care about shipping fast without breaking things.&lt;/p&gt;

&lt;p&gt;I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.&lt;/p&gt;

&lt;p&gt;What I do:&lt;/p&gt;

&lt;p&gt;🤖 AI agents &amp;amp; chatbot interfaces (yes, including the one you could be using right now)&lt;br&gt;
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)&lt;br&gt;
🛠️ DevTools &amp;amp; NPM packages that actually solve problems&lt;br&gt;
🚀 SEO-optimized web apps that rank&lt;br&gt;
Currently: Building open-source tools and taking on select freelance projects.&lt;/p&gt;

&lt;p&gt;Let's talk:&lt;br&gt;
🐦 Twitter: &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;github.com/SivaramPg&lt;/a&gt;&lt;br&gt;
🌐 Portfolio: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;&lt;br&gt;
📧 Email: [&lt;a href="mailto:dev.sivaramp@gmail.com"&gt;dev.sivaramp@gmail.com&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>clawdbot</category>
      <category>openclaw</category>
    </item>
    <item>
      <title>How a “Neutral” Supabase vs Convex Comparison Broke Trust in DevTools</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Fri, 30 Jan 2026 04:21:58 +0000</pubDate>
      <link>https://dev.to/sivarampg/how-a-neutral-supabase-vs-convex-comparison-broke-trust-in-devtools-4108</link>
      <guid>https://dev.to/sivarampg/how-a-neutral-supabase-vs-convex-comparison-broke-trust-in-devtools-4108</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This isn’t about Supabase vs Convex as products.&lt;br&gt;&lt;br&gt;
It’s about how credibility breaks in devtools — and why engineers react so strongly when it does.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Over the past few days, a third‑party blog post comparing &lt;strong&gt;Supabase&lt;/strong&gt; and &lt;strong&gt;Convex&lt;/strong&gt; triggered an unusually intense backlash across the developer community.&lt;/p&gt;

&lt;p&gt;What followed wasn’t just social‑media noise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;founders publicly calling out factual inaccuracies,&lt;/li&gt;
&lt;li&gt;competing infra CEOs resurfacing old security research,&lt;/li&gt;
&lt;li&gt;and a visible shift in sentiment among highly engaged developers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post explains &lt;strong&gt;what went wrong&lt;/strong&gt;, &lt;strong&gt;why the reaction was so strong&lt;/strong&gt;, and &lt;strong&gt;what this episode teaches us about trust, marketing, and correctness in developer infrastructure&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The article that started it all
&lt;/h2&gt;

&lt;p&gt;The post in question is titled:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Is Backend‑As‑A‑Service (BaaS) Enterprise‑Ready?&lt;br&gt;&lt;br&gt;
A Hands‑On Review of Convex and Supabase”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Link:&lt;br&gt;&lt;br&gt;
&lt;a href="https://senacor.blog/is-backend-as-a-service-baas-enterprise-ready-a-hands-on-review-of-convex-and-supabase/" rel="noopener noreferrer"&gt;https://senacor.blog/is-backend-as-a-service-baas-enterprise-ready-a-hands-on-review-of-convex-and-supabase/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was published on a consulting firm’s blog and framed as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;independent&lt;/li&gt;
&lt;li&gt;neutral&lt;/li&gt;
&lt;li&gt;hands‑on&lt;/li&gt;
&lt;li&gt;enterprise‑focused&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That framing matters — because once you claim neutrality, &lt;strong&gt;technical accuracy becomes non‑negotiable&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The first red flag: framing Convex as “temporary”
&lt;/h2&gt;

&lt;p&gt;One section in particular drew immediate criticism: &lt;strong&gt;“When to choose Convex”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The article suggested Convex is appropriate if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you’re validating an idea and don’t expect it to become production&lt;/li&gt;
&lt;li&gt;your app is “primarily CRUD”&lt;/li&gt;
&lt;li&gt;you’re okay migrating away if the project succeeds&lt;/li&gt;
&lt;li&gt;you want to avoid learning SQL/Postgres&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This framing strongly implies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convex is not production‑grade&lt;/li&gt;
&lt;li&gt;Convex doesn’t scale to complex systems&lt;/li&gt;
&lt;li&gt;Convex is a stepping stone, not infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That implication is &lt;strong&gt;factually incorrect&lt;/strong&gt; and &lt;strong&gt;reputationally harmful&lt;/strong&gt;, especially when presented as neutral analysis.&lt;/p&gt;

&lt;p&gt;But framing alone wasn’t what caused the blow‑up.&lt;/p&gt;

&lt;p&gt;The real issue was &lt;strong&gt;objective technical errors&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The factual inaccuracies that broke trust
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Supabase Edge Functions described as “typical”
&lt;/h3&gt;

&lt;p&gt;The article states:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Backend logic in Supabase is typically implemented via TypeScript Edge Functions using the Deno runtime…”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is &lt;strong&gt;not how Supabase is typically used in practice&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Most Supabase users:

&lt;ul&gt;
&lt;li&gt;use the Supabase SDK&lt;/li&gt;
&lt;li&gt;hit Postgres directly&lt;/li&gt;
&lt;li&gt;rely on Row Level Security (RLS)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Backend logic commonly runs on:

&lt;ul&gt;
&lt;li&gt;Vercel&lt;/li&gt;
&lt;li&gt;Node servers&lt;/li&gt;
&lt;li&gt;serverless platforms outside Supabase&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Edge Functions are &lt;strong&gt;optional&lt;/strong&gt; and often &lt;strong&gt;avoided&lt;/strong&gt; due to:

&lt;ul&gt;
&lt;li&gt;cold starts&lt;/li&gt;
&lt;li&gt;Deno quirks&lt;/li&gt;
&lt;li&gt;local DX friction&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Calling Edge Functions “typical” strongly suggests the author did not meaningfully use Supabase in production.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Convex described as “Node.js‑based”
&lt;/h3&gt;

&lt;p&gt;The article also claims:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Convex utilizes TypeScript functions … within a Node.js runtime environment”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a subtle but &lt;strong&gt;fundamental error&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Convex &lt;strong&gt;queries and mutations do NOT run in Node&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;They run in a deterministic, sandboxed runtime&lt;/li&gt;
&lt;li&gt;Node.js is &lt;strong&gt;optional&lt;/strong&gt; and used only for &lt;code&gt;actions&lt;/code&gt; (side effects, external APIs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Determinism is Convex’s &lt;strong&gt;core architectural thesis&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Describing it as Node‑based misrepresents how the system works at a foundational level.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why the reaction escalated so quickly
&lt;/h2&gt;

&lt;p&gt;If Supabase had published a first‑party post saying &lt;em&gt;“we prefer our approach”&lt;/em&gt;, this likely wouldn’t have mattered.&lt;/p&gt;

&lt;p&gt;The backlash happened because &lt;strong&gt;all of the following were true at once&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The article claimed neutrality
&lt;/li&gt;
&lt;li&gt;It contained first‑order technical inaccuracies
&lt;/li&gt;
&lt;li&gt;It framed a competitor as non‑enterprise
&lt;/li&gt;
&lt;li&gt;It was allegedly commissioned by Supabase
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In devtools, trust is binary.&lt;/p&gt;

&lt;p&gt;Once developers believe you’re willing to publish misleading technical content under a neutral banner, &lt;strong&gt;every past issue gets re‑examined&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why old security research resurfaced (SupaPwn)
&lt;/h2&gt;

&lt;p&gt;Shortly after the backlash began, PlanetScale’s CEO shared a long security write‑up titled &lt;em&gt;“SupaPwn”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It documented a chained vulnerability in &lt;strong&gt;Supabase’s legacy infrastructure&lt;/strong&gt; that, under specific conditions, allowed tenant escape.&lt;/p&gt;

&lt;p&gt;Important context often missing in social media summaries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;affected ~&lt;strong&gt;0.0006% of instances&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;limited to &lt;strong&gt;deprecated infrastructure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;patched within ~24 hours&lt;/li&gt;
&lt;li&gt;no evidence of exploitation in the wild&lt;/li&gt;
&lt;li&gt;handled via responsible disclosure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By itself, this was a &lt;strong&gt;well‑handled security incident&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But once Supabase’s credibility was questioned, it became &lt;strong&gt;rhetorical ammunition&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s how trust failures work:&lt;br&gt;&lt;br&gt;
past incidents get reinterpreted through a new lens.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this was actually about: programming models
&lt;/h2&gt;

&lt;p&gt;Lost in the drama is the real, legitimate difference between these tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supabase optimizes for:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;raw PostgreSQL power&lt;/li&gt;
&lt;li&gt;SQL flexibility&lt;/li&gt;
&lt;li&gt;open‑source foundations&lt;/li&gt;
&lt;li&gt;self‑hosting escape hatches&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Convex optimizes for:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;correctness by construction&lt;/li&gt;
&lt;li&gt;deterministic application logic&lt;/li&gt;
&lt;li&gt;realtime by default&lt;/li&gt;
&lt;li&gt;state living in code (agent‑friendly)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither approach is “more serious”.&lt;br&gt;&lt;br&gt;
They are &lt;strong&gt;different tradeoffs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Reducing that to &lt;em&gt;“CRUD vs enterprise”&lt;/em&gt; is not analysis — it’s distortion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Appendix A: When to choose Supabase vs Convex (neutral)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  When Supabase is a good fit
&lt;/h3&gt;

&lt;p&gt;Supabase works best when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want &lt;strong&gt;PostgreSQL as your primary abstraction&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You value &lt;strong&gt;SQL, relational modeling, and Postgres extensions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You’re comfortable owning:

&lt;ul&gt;
&lt;li&gt;schema design&lt;/li&gt;
&lt;li&gt;indexing&lt;/li&gt;
&lt;li&gt;query performance&lt;/li&gt;
&lt;li&gt;RLS correctness&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;You want &lt;strong&gt;self‑hosting and infrastructure control&lt;/strong&gt;
&lt;/li&gt;

&lt;li&gt;Your backend architecture is explicitly multi‑tier&lt;/li&gt;

&lt;li&gt;You prefer flexibility over opinionated constraints&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Supabase shines when you want power and control, and are willing to manage more complexity.&lt;/p&gt;




&lt;h3&gt;
  
  
  When Convex is a good fit
&lt;/h3&gt;

&lt;p&gt;Convex works best when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want &lt;strong&gt;data access and business logic unified in TypeScript&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;transactions and consistency by default&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;realtime without separate infrastructure&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You’re frontend‑heavy or React‑centric&lt;/li&gt;
&lt;li&gt;You want a backend that’s &lt;strong&gt;LLM / agent‑friendly&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You prefer fewer footguns, even if that means fewer knobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In short:&lt;/strong&gt; Convex shines when you want strong guarantees and a simpler mental model.&lt;/p&gt;




&lt;h3&gt;
  
  
  Shared ground
&lt;/h3&gt;

&lt;p&gt;Both Supabase and Convex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use ACID‑compliant datastores&lt;/li&gt;
&lt;li&gt;integrate well with modern TS/JS frameworks&lt;/li&gt;
&lt;li&gt;provide file storage and vector search&lt;/li&gt;
&lt;li&gt;offer auth, dashboards, and free tiers&lt;/li&gt;
&lt;li&gt;are open‑source (with different scopes)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither is “toy infrastructure”.&lt;/p&gt;




&lt;h2&gt;
  
  
  Appendix B: Common migration reasons (both directions)
&lt;/h2&gt;

&lt;p&gt;Migrations happen &lt;strong&gt;both ways&lt;/strong&gt;, and usually for understandable reasons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common reasons teams migrate &lt;strong&gt;from Supabase → Convex&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;RLS complexity becomes hard to reason about&lt;/li&gt;
&lt;li&gt;Auth + policy bugs are difficult to debug&lt;/li&gt;
&lt;li&gt;Realtime subscriptions add operational overhead&lt;/li&gt;
&lt;li&gt;Backend logic is split across:

&lt;ul&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;li&gt;policies&lt;/li&gt;
&lt;li&gt;dashboards&lt;/li&gt;
&lt;li&gt;serverless functions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Desire for:

&lt;ul&gt;
&lt;li&gt;stronger invariants&lt;/li&gt;
&lt;li&gt;fewer partial failure modes&lt;/li&gt;
&lt;li&gt;backend logic fully in code&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Better fit for agent‑driven or LLM‑assisted development&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is less about Supabase being “bad” and more about teams wanting &lt;strong&gt;more opinionation and guarantees&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Common reasons teams migrate &lt;strong&gt;from Convex → Supabase&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Need for &lt;strong&gt;raw SQL&lt;/strong&gt;, complex joins, or analytics queries&lt;/li&gt;
&lt;li&gt;Requirement to integrate with existing Postgres‑based tooling&lt;/li&gt;
&lt;li&gt;Desire for &lt;strong&gt;full database control or self‑hosting&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Constraints of Convex’s programming model feel limiting&lt;/li&gt;
&lt;li&gt;Team already deeply SQL‑centric&lt;/li&gt;
&lt;li&gt;Use cases that map naturally to relational modeling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is less about Convex being “limited” and more about teams wanting &lt;strong&gt;maximum flexibility&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  A useful mental model
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Supabase migrations usually happen due to complexity fatigue&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Convex migrations usually happen due to flexibility ceilings&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither is a failure — they’re signals about mismatched abstractions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this mattered more than a CVE
&lt;/h2&gt;

&lt;p&gt;Ironically, Supabase handled the SupaPwn incident &lt;strong&gt;better&lt;/strong&gt; than many companies handle security issues.&lt;/p&gt;

&lt;p&gt;What caused lasting damage was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;outsourcing a competitive comparison&lt;/li&gt;
&lt;li&gt;not rigorously fact‑checking it&lt;/li&gt;
&lt;li&gt;allowing it to be framed as independent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In devtools, &lt;strong&gt;epistemic trust matters more than feature parity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Engineers forgive bugs.&lt;br&gt;&lt;br&gt;
They do not forgive being misled.&lt;/p&gt;




&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;Supabase is not doomed.&lt;br&gt;&lt;br&gt;
Convex is not universally better.&lt;/p&gt;

&lt;p&gt;But this episode reinforced something many engineers already believe:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In devtools, credibility compounds — and so does the cost of losing it.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>supabase</category>
      <category>convex</category>
      <category>devtools</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From Clawdbot to Moltbot: How a C&amp;D, Crypto Scammers, and 10 Seconds of Chaos Took Down the Internet's Hottest AI Project</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Tue, 27 Jan 2026 10:46:31 +0000</pubDate>
      <link>https://dev.to/sivarampg/from-clawdbot-to-moltbot-how-a-cd-crypto-scammers-and-10-seconds-of-chaos-took-down-the-4eck</link>
      <guid>https://dev.to/sivarampg/from-clawdbot-to-moltbot-how-a-cd-crypto-scammers-and-10-seconds-of-chaos-took-down-the-4eck</guid>
      <description>&lt;h2&gt;
  
  
  The 72-Hour Unraveling of Open Source's Fastest-Growing Star
&lt;/h2&gt;

&lt;p&gt;Three days ago, Clawdbot was the darling of the AI community. &lt;strong&gt;60,800 GitHub stars&lt;/strong&gt; (and climbing). Mac Minis selling out. "Jarvis is here" tweets everywhere.&lt;/p&gt;

&lt;p&gt;Today? The project has a new name, the founder is fighting crypto scammers, hundreds of API keys are exposed, and the community is asking: &lt;em&gt;Did Anthropic just kill the golden goose that was literally building on their platform?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is the story of how fast things fall apart when legal teams, hackers, and viral hype collide.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: The Meteoric Rise (60K+ Stars in Days)
&lt;/h2&gt;

&lt;p&gt;For the uninitiated, &lt;strong&gt;Clawdbot&lt;/strong&gt; (now Moltbot) was a self-hosted AI assistant created by Peter Steinberger (@steipete), the Austrian developer who founded PSPDFKit and exited to Insight Partners. It was essentially "Claude with hands" — an AI agent that didn't just chat, but &lt;em&gt;did&lt;/em&gt; things.&lt;/p&gt;

&lt;p&gt;→ Persistent memory across conversations&lt;br&gt;&lt;br&gt;
→ Full system access (shell, browser, files)&lt;br&gt;&lt;br&gt;
→ Proactive notifications&lt;br&gt;&lt;br&gt;
→ 50+ integrations&lt;br&gt;&lt;br&gt;
→ Multi-platform (WhatsApp, Telegram, Slack, iMessage, Signal, Discord)&lt;/p&gt;

&lt;p&gt;The project launched late 2025. It hit &lt;strong&gt;9,000 stars very quickly 24 hours&lt;/strong&gt;. in recent days it has crossed &lt;strong&gt;60,000+ stars&lt;/strong&gt; — making it one of the fastest-growing open-source projects in GitHub history.&lt;/p&gt;

&lt;p&gt;Andrej Karpathy praised it. David Sacks tweeted about it. MacStories called it "the future of personal AI assistants."&lt;/p&gt;

&lt;p&gt;But the killer feature? It ran locally, gave users full control, and &lt;em&gt;many users specifically configured it to use Anthropic's Claude as the brain.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The irony of what happened next is almost poetic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 2: The Cease &amp;amp; Desist
&lt;/h2&gt;

&lt;p&gt;On January 27, 2026, Steinberger announced that &lt;strong&gt;Anthropic had issued a trademark request&lt;/strong&gt; forcing a rebrand.&lt;/p&gt;

&lt;p&gt;The problem? The name "&lt;strong&gt;Clawd&lt;/strong&gt;" was too similar to "&lt;strong&gt;Claude&lt;/strong&gt;."&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Anthropic asked us to change our name (trademark stuff), and honestly? 'Molt' fits perfectly — it's what lobsters do to grow."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The new branding was actually clever:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clawdbot&lt;/strong&gt; → &lt;strong&gt;Moltbot&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clawd&lt;/strong&gt; → &lt;strong&gt;Molty&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Handle: &lt;strong&gt;@moltbot&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Website: &lt;strong&gt;molt.bot&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "same lobster soul, new shell" narrative played well. Lobsters molt to grow. The project was shedding its old identity to become something bigger.&lt;/p&gt;

&lt;p&gt;But the execution? Absolute chaos.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 3: The 10-Second Disaster
&lt;/h2&gt;

&lt;p&gt;Here's where it gets &lt;em&gt;wild&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;During the rename process, Steinberger made a critical mistake. He tried to rename the GitHub organization and X/Twitter handle simultaneously. In the gap between releasing the old name and claiming the new one, &lt;strong&gt;crypto scammers snatched both accounts in approximately 10 seconds.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Steinberger's own words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Had to rename our accounts for trademark stuff and messed up the GitHub rename and the X rename got snatched by crypto shills."&lt;/p&gt;

&lt;p&gt;"It wasn't hacked, I messed up the rename and my old name was snatched in 10 seconds."&lt;/p&gt;

&lt;p&gt;"Because it's only that community that harasses me on all channels and they were already waiting."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The attackers had been monitoring for exactly this opportunity. The moment the old handles became available, they pounced. Now the original @clawdbot X account and GitHub org are pumping crypto scams to tens of thousands of followers who don't know about the rebrand.&lt;/p&gt;

&lt;p&gt;Steinberger is now begging GitHub for help recovering the account. Meanwhile, fake announcements are going out from the hijacked accounts claiming token launches, airdrops, and investment opportunities.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 4: The $16 Million Crypto Scam
&lt;/h2&gt;

&lt;p&gt;The account hijacking wasn't the end of it. It was the beginning.&lt;/p&gt;

&lt;p&gt;Within hours of the rename chaos, &lt;strong&gt;fake $CLAWD tokens appeared on Solana&lt;/strong&gt;. At peak, the token hit a &lt;strong&gt;$16 million market cap&lt;/strong&gt; as speculators FOMO'd in, thinking they were getting early access to "the next big AI coin."&lt;/p&gt;

&lt;p&gt;Then Steinberger dropped the hammer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"To all crypto folks: Please stop pinging me, stop harassing me. I will never do a coin. Any project that lists me as coin owner is a SCAM. No, I will not accept fees. You are actively damaging the project."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The token immediately collapsed to near-zero. Late buyers got rugged. The scammers walked away with millions.&lt;/p&gt;

&lt;p&gt;The whole saga has become a masterclass in how quickly crypto vultures can exploit mainstream tech moments.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 5: The Security Nightmare
&lt;/h2&gt;

&lt;p&gt;While all this was happening, security researchers were finding &lt;em&gt;actual&lt;/em&gt; vulnerabilities in Moltbot (still Clawdbot at the time).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SlowMist, a blockchain security firm, reported:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Multiple unauthenticated instances are publicly accessible, and several code flaws may lead to credential theft and even remote code execution."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Researcher Jamieson O'Reilly found:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Hundreds of people have set up their Clawdbot control servers exposed to the public."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Using Shodan, he could search for "Clawdbot Control" and find &lt;strong&gt;complete credentials&lt;/strong&gt; — API keys, bot tokens, OAuth secrets, full conversation histories, the ability to send messages as users, and command execution capabilities.&lt;/p&gt;

&lt;p&gt;In one demo, researcher Matvey Kukuy sent a malicious email with prompt injection to a vulnerable Moltbot instance. The AI read the email, believed it was legitimate instructions, and forwarded the user's last 5 emails to an attacker address. &lt;strong&gt;It took 5 minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Hacker News consensus: "It's terrifying. No directory sandboxing."&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 6: The Community vs. Anthropic
&lt;/h2&gt;

&lt;p&gt;Now the community is asking uncomfortable questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why target Clawdbot when it was driving Claude usage?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many Moltbot users specifically configured the assistant to use Claude as the underlying model. The project was literally &lt;em&gt;selling more Claude subscriptions&lt;/em&gt;. It demonstrated real-world use cases for Anthropic's API. It was free marketing and a thriving ecosystem built on their platform.&lt;/p&gt;

&lt;p&gt;Anthropic has been cracking down on "harnesses" — third-party tools that spoof the Claude Code client to access consumer subscriptions. They've blocked xAI staff from using Claude via Cursor. They sent DMCA notices to developers reverse-engineering Claude Code.&lt;/p&gt;

&lt;p&gt;But Clawdbot wasn't a harness. It was a legitimate open-source project using the official API. The trademark dispute over "Clawd" vs "Claude" feels petty to many developers, especially given that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The project was 3 months old&lt;/li&gt;
&lt;li&gt;It was driving real revenue to Anthropic&lt;/li&gt;
&lt;li&gt;The rename caused actual security disasters&lt;/li&gt;
&lt;li&gt;The phonetic similarity was clearly playful, not malicious&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It had 60K+ stars and massive developer goodwill&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;DHH (David Heinemeier Hansson, Rails creator) has called Anthropic's recent moves "customer hostile."&lt;/p&gt;

&lt;p&gt;The sentiment is shifting. Developers who were enthusiastic Claude advocates are now looking at OpenAI's Codex CLI (Apache 2.0 license) and wondering if Anthropic is becoming the kind of company they don't want to build on top of.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 7: What Happens Now
&lt;/h2&gt;

&lt;p&gt;Peter Steinberger is fighting on multiple fronts:&lt;/p&gt;

&lt;p&gt;→ Trying to recover hijacked GitHub/X accounts from crypto scammers&lt;br&gt;&lt;br&gt;
→ Dealing with harassment from token speculators&lt;br&gt;&lt;br&gt;
→ Managing a community of 8,900+ Discord members&lt;br&gt;&lt;br&gt;
→ Fixing security vulnerabilities&lt;br&gt;&lt;br&gt;
→ Rebuilding brand recognition after a forced rebrand  &lt;/p&gt;

&lt;p&gt;The project itself is still solid. Moltbot is the same software Clawdbot was — a genuinely impressive piece of engineering that represents the future of personal AI assistants.&lt;/p&gt;

&lt;p&gt;But the optics are rough. A 3-month-old viral open-source project with &lt;strong&gt;60K+ stars&lt;/strong&gt; just got:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Legal pressure from an $18B AI company&lt;/li&gt;
&lt;li&gt;Account-jacked by crypto scammers&lt;/li&gt;
&lt;li&gt;Exploited for millions in fake token scams&lt;/li&gt;
&lt;li&gt;Outed for serious security vulnerabilities&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All in 72 hours.&lt;/p&gt;




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

&lt;p&gt;This saga highlights the fragility of the current AI ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For open source builders:&lt;/strong&gt; You're building on corporate platforms with ambiguous trademark policies. One legal notice can force a rebrand that exposes you to account hijacking, scams, and chaos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For AI companies:&lt;/strong&gt; Your most enthusiastic evangelists are indie developers building weird, experimental tools. Sending legal notices to viral open-source projects that drive your API usage is... a choice. Google didn't sue Android developers. OpenAI isn't suing LangChain. There's a playbook for fostering ecosystems, and "cease and desist" isn't it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For users:&lt;/strong&gt; Self-hosting AI agents with root access is powerful and dangerous. The security model for these tools is still immature. Don't put them on your main machine with access to crypto wallets. Use dedicated hardware, isolated accounts, and strict IP whitelisting.&lt;/p&gt;

&lt;p&gt;Moltbot is still worth trying if you're technical and security-conscious. It's a glimpse of what's coming — AI agents that actually &lt;em&gt;do&lt;/em&gt; things, remember everything, and live where you already communicate.&lt;/p&gt;

&lt;p&gt;Just maybe don't run it on your personal laptop with your primary email account. And definitely don't buy any $CLAWD tokens.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;→&lt;/strong&gt; Follow the project at &lt;a href="https://molt.bot" rel="noopener noreferrer"&gt;molt.bot&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;→&lt;/strong&gt; GitHub: github.com/moltbot/clawdbot&lt;br&gt;&lt;br&gt;
&lt;strong&gt;→&lt;/strong&gt; X: @moltbot (verified new account)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you tried Moltbot? What do you think about Anthropic's trademark enforcement against a 60K+ star project? Drop your thoughts below.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;#ai&lt;/strong&gt; &lt;strong&gt;#opensource&lt;/strong&gt; &lt;strong&gt;#anthropic&lt;/strong&gt; &lt;strong&gt;#moltbot&lt;/strong&gt; &lt;strong&gt;#clawdbot&lt;/strong&gt; &lt;strong&gt;#crypto&lt;/strong&gt; &lt;strong&gt;#security&lt;/strong&gt; &lt;strong&gt;#trademark&lt;/strong&gt; &lt;strong&gt;#developercommunity&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;👋 About the Author&lt;/p&gt;

&lt;p&gt;If you made it this far, you probably care about shipping fast without breaking things.&lt;/p&gt;

&lt;p&gt;I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.&lt;/p&gt;

&lt;p&gt;What I do:&lt;/p&gt;

&lt;p&gt;🤖 AI agents &amp;amp; chatbot interfaces (yes, including the one you could be using right now)&lt;br&gt;
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)&lt;br&gt;
🛠️ DevTools &amp;amp; NPM packages that actually solve problems&lt;br&gt;
🚀 SEO-optimized web apps that rank&lt;br&gt;
Currently: Building open-source tools and taking on select freelance projects.&lt;/p&gt;

&lt;p&gt;Let's talk:&lt;br&gt;
🐦 Twitter: &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;github.com/SivaramPg&lt;/a&gt;&lt;br&gt;
🌐 Portfolio: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;&lt;br&gt;
📧 Email: [&lt;a href="mailto:dev.sivaramp@gmail.com"&gt;dev.sivaramp@gmail.com&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.&lt;/p&gt;

</description>
      <category>clawdbot</category>
      <category>anthropic</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Solana Waitlist for a Fake $10k Bounty - Here's the Open Source Code</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Tue, 27 Jan 2026 05:08:00 +0000</pubDate>
      <link>https://dev.to/sivarampg/i-built-a-solana-waitlist-for-a-fake-10k-bounty-heres-the-open-source-code-e78</link>
      <guid>https://dev.to/sivarampg/i-built-a-solana-waitlist-for-a-fake-10k-bounty-heres-the-open-source-code-e78</guid>
      <description>&lt;p&gt;Last week I saw a tweet: "Need a waitlist system in 3 hours. Paying $10k."&lt;/p&gt;

&lt;p&gt;I dropped everything and built it. Twitter OAuth, Solana wallet verification, referral system with leaderboard. The works.&lt;/p&gt;

&lt;p&gt;The bounty was fake. Engagement farming.&lt;/p&gt;

&lt;p&gt;But I kept the code. And now I'm open sourcing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/SivaramPg/tapdotfun-waitlist-referral-system" rel="noopener noreferrer"&gt;tapdotfun-waitlist-referral-system&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Live Link&lt;/strong&gt;: &lt;a href="https://tdotf.vercel.app/" rel="noopener noreferrer"&gt;tdotf&lt;/a&gt;&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Febknze1vyte8o7tskfo5.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Febknze1vyte8o7tskfo5.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;A 3-step waitlist onboarding flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Connect X (Twitter)&lt;/strong&gt; — OAuth 2.0 login, captures @handle and display name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connect Wallet&lt;/strong&gt; — Phantom, Solflare, or any Solana wallet&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sign Message&lt;/strong&gt; — Proves wallet ownership without gas fees&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Plus a &lt;strong&gt;referral system&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Case-insensitive referral links (&lt;code&gt;?ref=username&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Automatic referral count tracking&lt;/li&gt;
&lt;li&gt;Real-time leaderboard showing top referrers&lt;/li&gt;
&lt;/ul&gt;


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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Next.js 16 + React 19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend API&lt;/td&gt;
&lt;td&gt;oRPC (end-to-end type-safe)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;PostgreSQL + Drizzle ORM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;Better Auth (Twitter OAuth)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wallet&lt;/td&gt;
&lt;td&gt;Jupiter Unified Wallet Kit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;td&gt;shadcn/ui + TailwindCSS 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monorepo&lt;/td&gt;
&lt;td&gt;Turborepo + Bun&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Why this stack?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;oRPC&lt;/strong&gt; gives you end-to-end type safety without the tRPC complexity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Auth&lt;/strong&gt; handles OAuth properly (not NextAuth — different package entirely)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drizzle&lt;/strong&gt; is TypeScript-first and doesn't fight you&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jupiter's Unified Wallet Kit&lt;/strong&gt; supports all major Solana wallets out of the box&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tapdotfun/
├── apps/
│   └── web/                    # Next.js fullstack app
│       ├── src/
│       │   ├── app/            # App router pages
│       │   ├── components/     # React components
│       │   └── utils/          # oRPC client
│
├── packages/
│   ├── api/                    # oRPC routers &amp;amp; procedures
│   ├── auth/                   # Better Auth configuration
│   ├── db/                     # Drizzle schema &amp;amp; migrations
│   └── env/                    # Environment validation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Monorepo structure keeps things clean. Auth logic in one package, database in another, API separate. Easy to reason about.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Database Schema
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// packages/db/src/schema/waitlist.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;waitlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pgTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;waitlist&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;// nanoid&lt;/span&gt;
  &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;twitterHandle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter_handle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;twitterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter_name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;twitterId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;twitter_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;walletAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wallet_address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;walletSignature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;wallet_signature&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// bs58 encoded&lt;/span&gt;
  &lt;span class="na"&gt;referredBy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;referred_by&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;referralCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;referral_count&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;created_at&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;defaultNow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;notNull&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Key decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store &lt;code&gt;twitterHandle&lt;/code&gt; with original casing for display&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;walletSignature&lt;/code&gt; stores the BS58-encoded signature for verification&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;referredBy&lt;/code&gt; uses case-insensitive matching (more on this below)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Referral System
&lt;/h2&gt;

&lt;p&gt;This caught me off guard initially. Users share links with different casing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;?ref=SivaramPg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;?ref=sivarampg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;?ref=SIVARAMPG&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All should work. Here's how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Store with original casing&lt;/span&gt;
&lt;span class="nx"&gt;twitterHandle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// "SivaramPg"&lt;/span&gt;

&lt;span class="c1"&gt;// Match case-insensitively&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;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;referredBy&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;db&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;waitlist&lt;/span&gt;&lt;span class="p"&gt;)&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;referralCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;waitlist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;referralCount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; + 1`&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="s2"&gt;`lower(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;waitlist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;twitterHandle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) = &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;referredBy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The referral param is captured by a client component and stored in &lt;code&gt;localStorage&lt;/code&gt; — this survives the OAuth redirect.&lt;/p&gt;




&lt;h2&gt;
  
  
  Wallet Verification Without Gas
&lt;/h2&gt;

&lt;p&gt;No one wants to pay gas just to join a waitlist. Message signing proves ownership without transactions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Verify wallet for tap.fun waitlist: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&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;encodedMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TextEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;signMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;encodedMessage&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;signatureBase58&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bs58&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Store both address and signature&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updateWallet&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;walletAddress&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;walletSignature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;signatureBase58&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The timestamp prevents replay attacks. The signature proves they control the wallet. Zero cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Endpoints
&lt;/h2&gt;

&lt;p&gt;All type-safe via oRPC:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Auth&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;healthCheck&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Public&lt;/td&gt;
&lt;td&gt;Server health&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;getLeaderboard&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Public&lt;/td&gt;
&lt;td&gt;Top 10 referrers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;joinWaitlist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Protected&lt;/td&gt;
&lt;td&gt;Create entry, credit referrer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;updateWallet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Protected&lt;/td&gt;
&lt;td&gt;Store wallet + signature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;checkWaitlist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Protected&lt;/td&gt;
&lt;td&gt;Get user's status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;getReferralCount&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Protected&lt;/td&gt;
&lt;td&gt;Get referral stats&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Protected routes use a middleware that checks the Better Auth session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;protectedProcedure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;publicProcedure&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&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;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ORPCError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UNAUTHORIZED&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="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&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;
  
  
  Getting Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone&lt;/span&gt;
git clone https://github.com/SivaramPg/tapdotfun-waitlist-referral-system.git
&lt;span class="nb"&gt;cd &lt;/span&gt;tapdotfun-waitlist-referral-system

&lt;span class="c"&gt;# Install&lt;/span&gt;
bun &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Set up env&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;apps/web/.env.example apps/web/.env
&lt;span class="c"&gt;# Edit with your DATABASE_URL, Twitter OAuth keys, etc.&lt;/span&gt;

&lt;span class="c"&gt;# Database&lt;/span&gt;
bun run db:push

&lt;span class="c"&gt;# Run&lt;/span&gt;
bun run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:3001&lt;/code&gt; and you're running.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rebranding in 45 Minutes
&lt;/h2&gt;

&lt;p&gt;The repo includes a &lt;a href="https://github.com/SivaramPg/tapdotfun-waitlist-referral-system/blob/main/PLAYBOOK.md" rel="noopener noreferrer"&gt;PLAYBOOK.md&lt;/a&gt; with everything you need to rebrand:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Logo&lt;/strong&gt;: Replace &lt;code&gt;components/tap-logo.tsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Colors&lt;/strong&gt;: Find/replace &lt;code&gt;#15F228&lt;/code&gt; with your brand color&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy&lt;/strong&gt;: Update text in &lt;code&gt;page.tsx&lt;/code&gt; and &lt;code&gt;waitlist-flow.tsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metadata&lt;/strong&gt;: Update &lt;code&gt;layout.tsx&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assets&lt;/strong&gt;: Swap favicon and OG image in &lt;code&gt;public/&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The PLAYBOOK also covers UI library selection, font choices, responsive patterns, and deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify bounties before building&lt;/strong&gt; — Check if it's engagement farming&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store both username AND display name&lt;/strong&gt; — Twitter OAuth returns display name, not @handle&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Case-insensitive referral matching&lt;/strong&gt; — Users share links with random casing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persist state through OAuth&lt;/strong&gt; — localStorage survives redirects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No gas for verification&lt;/strong&gt; — Message signing proves ownership free&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;The repo is MIT licensed. Use it however you want.&lt;/p&gt;

&lt;p&gt;If you're building a Solana project and need a waitlist, clone it. If you want to improve it, PRs are welcome.&lt;/p&gt;

&lt;p&gt;I'm available for freelance Solana/Web3 projects. DMs open on Twitter: &lt;a href="https://twitter.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/SivaramPg/tapdotfun-waitlist-referral-system" rel="noopener noreferrer"&gt;tapdotfun-waitlist-referral-system&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fake bounty wasn't a total loss. At least now someone else can ship faster.&lt;/p&gt;




&lt;p&gt;👋 About the Author&lt;/p&gt;

&lt;p&gt;If you made it this far, you probably care about shipping fast without breaking things.&lt;/p&gt;

&lt;p&gt;I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.&lt;/p&gt;

&lt;p&gt;What I do:&lt;/p&gt;

&lt;p&gt;🤖 AI agents &amp;amp; chatbot interfaces (yes, including the one you could be using right now)&lt;br&gt;
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)&lt;br&gt;
🛠️ DevTools &amp;amp; NPM packages that actually solve problems&lt;br&gt;
🚀 SEO-optimized web apps that rank&lt;br&gt;
Currently: Building open-source tools and taking on select freelance projects.&lt;/p&gt;

&lt;p&gt;Let's talk:&lt;br&gt;
🐦 Twitter: &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;github.com/SivaramPg&lt;/a&gt;&lt;br&gt;
🌐 Portfolio: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;&lt;br&gt;
📧 Email: [&lt;a href="mailto:dev.sivaramp@gmail.com"&gt;dev.sivaramp@gmail.com&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.&lt;/p&gt;

</description>
      <category>solana</category>
      <category>waitlist</category>
      <category>web3</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Clawdbot: The AI Assistant That's Breaking the Internet</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Mon, 26 Jan 2026 11:58:51 +0000</pubDate>
      <link>https://dev.to/sivarampg/clawdbot-the-ai-assistant-thats-breaking-the-internet-1a47</link>
      <guid>https://dev.to/sivarampg/clawdbot-the-ai-assistant-thats-breaking-the-internet-1a47</guid>
      <description>&lt;p&gt;What is Clawdbot?&lt;/p&gt;

&lt;p&gt;Clawdbot is an open-source, self-hosted personal AI assistant created by Peter Steinberger (also known as @steipete), the founder of PSPDFKit. It's essentially a "Claude with hands" - an AI that doesn't just chat but actually &lt;em&gt;does things&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Unlike traditional AI assistants that live in a browser tab, Clawdbot runs on your own hardware and integrates with messaging apps you already use - WhatsApp, Telegram, Discord, Slack, Signal, iMessage, and more. It acts as a full-time personal assistant that can manage your emails, calendar, check you in for flights, control smart home devices, and execute terminal commands - all from your chat apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hype Train: Why Everyone's Talking About It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The "24/7 Jarvis" Vision
&lt;/h3&gt;

&lt;p&gt;Clawdbot has captured the imagination of developers worldwide by promising something we've been waiting for since Siri launched in 2011: a personal AI assistant that actually works. It's being hailed as the "24/7 Jarvis" - an AI that can proactively reach out to you, remembers everything, and executes tasks autonomously.&lt;/p&gt;

&lt;p&gt;The project exploded to over &lt;strong&gt;29,900+ GitHub stars&lt;/strong&gt; in just a few weeks, making it one of the fastest-growing open-source projects in recent memory. Tech leaders like David Sacks and Vijay Shekhar Sharma have mentioned it, and Silicon Valley is buzzing.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Makes It Different
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Persistent Memory&lt;/strong&gt;: Unlike ChatGPT or Claude that forgets between sessions, Clawdbot remembers everything - conversations, preferences, and important details mentioned weeks ago.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proactive&lt;/strong&gt;: It can reach out to YOU - morning briefings, reminders, alerts when something you care about happens. Most chatbots wait for you to type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Full Computer Access&lt;/strong&gt;: It can execute terminal commands, write scripts, browse the web, control smart home devices, and access your file system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multi-Platform&lt;/strong&gt;: Same assistant across WhatsApp, Telegram, Discord, Slack, iMessage - same conversation, same memory, everywhere.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The FOMO Factor: Why It's Breaking the Internet
&lt;/h2&gt;

&lt;p&gt;The hype around Clawdbot is driven by &lt;strong&gt;FOMO (Fear Of Missing Out)&lt;/strong&gt;. Everyone's talking about it, sharing screenshots of their setups, showing off what it can do. Social media is flooded with "Clawdbot this" posts. People don't want to miss out on what could be the next big thing in AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Peter Steinberger: The Creator Behind the Craze
&lt;/h2&gt;

&lt;p&gt;Peter Steinberger is a well-known developer who founded PSPDFKit (now called Nutrient). He came out of retirement to build Clawdbot, and has been documenting his workflow for years. His blog post about "Claude Code is my computer" went viral, explaining how he built his personal AI assistant.&lt;/p&gt;

&lt;p&gt;The project has attracted significant developer interest with over &lt;strong&gt;50 contributors&lt;/strong&gt; and an active Discord community of &lt;strong&gt;8,900+ members&lt;/strong&gt;. Steinberger brings decades of experience building developer tools and enterprise software to the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  How People Are Setting It Up
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quick Setup Options
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Mac Mini (~$599)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Popular choice for Clawdbot&lt;/li&gt;
&lt;li&gt;Apple Silicon Valley's Mac mini has been selling out due to Clawdbot demand&lt;/li&gt;
&lt;li&gt;Runs macOS natively&lt;/li&gt;
&lt;li&gt;Good performance for AI tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 2: VPS (~$5/month)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cheap cloud server option&lt;/li&gt;
&lt;li&gt;Hetzner has servers starting at ~$5/month&lt;/li&gt;
&lt;li&gt;Good for 24/7 availability&lt;/li&gt;
&lt;li&gt;Requires technical knowledge to set up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 3: Old Computer&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free if you have one lying around&lt;/li&gt;
&lt;li&gt;Requires Node.js 22+ and technical setup&lt;/li&gt;
&lt;li&gt;Good for developers who want full control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option 4: Docker&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-platform&lt;/li&gt;
&lt;li&gt;Runs on Linux, Windows, macOS&lt;/li&gt;
&lt;li&gt;Good for flexibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Dark Side: Security Concerns You Need to Know
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Root Access &amp;amp; Critical Services
&lt;/h3&gt;

&lt;p&gt;Clawdbot needs &lt;strong&gt;root access&lt;/strong&gt; to perform certain operations. This is both powerful and dangerous:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can execute terminal commands&lt;/li&gt;
&lt;li&gt;Can modify system files&lt;/li&gt;
&lt;li&gt;Can install software&lt;/li&gt;
&lt;li&gt;Can access sensitive data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Gateway Vulnerabilities
&lt;/h3&gt;

&lt;p&gt;The documentation mentions that &lt;strong&gt;multiple gateways on the same host&lt;/strong&gt; can create security issues. Each gateway needs its own port and configuration. If not properly isolated, one compromised gateway could affect others.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why It's Not For Everyone
&lt;/h3&gt;

&lt;h3&gt;
  
  
  It's Complex Setup
&lt;/h3&gt;

&lt;p&gt;Clawdbot requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Technical knowledge (Node.js, Docker, or Linux)&lt;/li&gt;
&lt;li&gt;Understanding of security best practices&lt;/li&gt;
&lt;li&gt;Time to configure properly&lt;/li&gt;
&lt;li&gt;Ongoing maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Cost Factor
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Hardware: Mac Mini (~$599) + Claude API (~$20-100/month)**
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Cloud: VPS (~$5/month) + Claude API (~$20-100/month)**
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Total: &lt;strong&gt;~$25-125/month&lt;/strong&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  The Bottom Line: Should You Use It?
&lt;/h2&gt;

&lt;p&gt;Clawdbot is an impressive piece of technology, but it's &lt;strong&gt;not for everyone&lt;/strong&gt;. Here's why you might want to skip it:&lt;/p&gt;

&lt;h3&gt;
  
  
  You Should Use Clawdbot If:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're a developer who wants to build and customize your own AI assistant&lt;/li&gt;
&lt;li&gt;You enjoy tinkering with complex systems&lt;/li&gt;
&lt;li&gt;You want full control over your data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  You Should Skip It If:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You just want a simple AI assistant that answers questions&lt;/li&gt;
&lt;li&gt;You don't need persistent memory or proactive features&lt;/li&gt;
&lt;li&gt;You prefer cloud-based solutions&lt;/li&gt;
&lt;li&gt;You don't want to manage your own infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Clawdbot represents an exciting evolution in personal AI assistants. It's powerful, flexible, and open-source. But it comes with real responsibilities - security, maintenance, and technical complexity.&lt;/p&gt;

&lt;p&gt;For most users, existing AI assistants like Siri, Google Assistant, or even ChatGPT will suffice. Clawdbot is for the builders and tinkerers who want full control and customization.&lt;/p&gt;

&lt;p&gt;For everyone else, it's okay to sit this one out. The hype will pass, and there will be other AI tools to try.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://clawd.bot" rel="noopener noreferrer"&gt;https://clawd.bot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/clawdbot/clawdbot" rel="noopener noreferrer"&gt;https://github.com/clawdbot/clawdbot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.clawd.bot" rel="noopener noreferrer"&gt;https://docs.clawd.bot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://newsbywire.com/open-source-ai-assistant-clawdbot-reaches-10200-github-stars-with-privacy-first-automation" rel="noopener noreferrer"&gt;https://newsbywire.com/open-source-ai-assistant-clawdbot-reaches-10200-github-stars-with-privacy-first-automation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://officechai.com/ai/everything-you-want-to-know-about-clawdbot-the-viral-personal-ai-assistant" rel="noopener noreferrer"&gt;https://officechai.com/ai/everything-you-want-to-know-about-clawdbot-the-viral-personal-ai-assistant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://velvetshark.com/clawdbot-the-self-hosted-ai-that-siri-should-have-been" rel="noopener noreferrer"&gt;https://velvetshark.com/clawdbot-the-self-hosted-ai-that-siri-should-have-been&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.panewslab.com/en/articles/b37f2cec-1c0f-487b-af34-61faea2e3cb2" rel="noopener noreferrer"&gt;https://www.panewslab.com/en/articles/b37f2cec-1c0f-487b-af34-61faea2e3cb2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/steipete" rel="noopener noreferrer"&gt;https://github.com/steipete&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.clawd.bot/security" rel="noopener noreferrer"&gt;https://docs.clawd.bot/security&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Jump on the hype train, but stay grounded. Your data, your choice!&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;👋 About the Author&lt;/p&gt;

&lt;p&gt;If you made it this far, you probably care about shipping fast without breaking things.&lt;/p&gt;

&lt;p&gt;I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.&lt;/p&gt;

&lt;p&gt;What I do:&lt;/p&gt;

&lt;p&gt;🤖 AI agents &amp;amp; chatbot interfaces (yes, including the one you could be using right now)&lt;br&gt;
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)&lt;br&gt;
🛠️ DevTools &amp;amp; NPM packages that actually solve problems&lt;br&gt;
🚀 SEO-optimized web apps that rank&lt;br&gt;
Currently: Building open-source tools and taking on select freelance projects.&lt;/p&gt;

&lt;p&gt;Let's talk:&lt;br&gt;
🐦 Twitter: &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;github.com/SivaramPg&lt;/a&gt;&lt;br&gt;
🌐 Portfolio: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;&lt;br&gt;
📧 Email: [&lt;a href="mailto:dev.sivaramp@gmail.com"&gt;dev.sivaramp@gmail.com&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>ai</category>
      <category>clawd</category>
      <category>opensource</category>
    </item>
    <item>
      <title>You Don't Need a Mac Mini to Run Clawdbot - Here's How to Run It Anywhere</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Mon, 26 Jan 2026 06:29:48 +0000</pubDate>
      <link>https://dev.to/sivarampg/you-dont-need-a-mac-mini-to-run-clawdbot-heres-how-to-run-it-anywhere-217l</link>
      <guid>https://dev.to/sivarampg/you-dont-need-a-mac-mini-to-run-clawdbot-heres-how-to-run-it-anywhere-217l</guid>
      <description>&lt;p&gt;Clawdbot is taking the tech world by storm. If you've been on Twitter, Reddit, or tech blogs lately, you've probably seen the flood of posts showing off freshly unboxed Mac Minis. People are buying these $599+ machines just to run an AI assistant.&lt;/p&gt;

&lt;p&gt;But here's the thing: &lt;strong&gt;you don't actually need a Mac Mini.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me show you how to run Clawdbot on hardware you probably already have, or for as little as $3-5/month.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Clawdbot?
&lt;/h2&gt;

&lt;p&gt;Clawdbot is an open-source, self-hosted AI assistant that lives in your messaging apps (WhatsApp, Telegram, Discord, Slack, Signal, even iMessage). Unlike ChatGPT where you go to a website, Clawdbot comes to you where you already are.&lt;/p&gt;

&lt;p&gt;What makes it special:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Persistent memory&lt;/strong&gt; — it remembers what you told it yesterday&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proactive&lt;/strong&gt; — it can reach out to YOU with briefings, reminders, alerts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full computer access&lt;/strong&gt; — browse the web, fill forms, run commands, automate tasks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always available&lt;/strong&gt; — runs 24/7 so it's always there when you need it&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Mac Mini Myth
&lt;/h2&gt;

&lt;p&gt;The recent surge in Mac Mini sales is largely driven by Clawdbot's popularity. A Redditor recently used Clawdbot to port an entire CUDA backend to AMD's ROCm in just 30 minutes, significantly denting NVIDIA's CUDA moat. This has made Apple's Mac Mini devices fly off the shelves.&lt;/p&gt;

&lt;p&gt;But here's the reality: Clawdbot was designed to run anywhere. The official documentation explicitly supports multiple platforms and deployment methods. You're not locked into Apple hardware.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/Z-FXHuiUJSU"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Actually Need to Run Clawdbot
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Minimum Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;2GB RAM and 2 CPU cores for basic chat functionality&lt;/li&gt;
&lt;li&gt;4GB+ RAM if you want browser automation skills or multiple intensive workflows&lt;/li&gt;
&lt;li&gt;20GB storage for the app, conversation history, and workspace files&lt;/li&gt;
&lt;li&gt;Node.js runtime environment&lt;/li&gt;
&lt;li&gt;Stable network connection (uptime matters more than raw bandwidth)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. No Apple silicon required. No unified memory architecture needed. Just a basic Linux or Windows machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Official Deployment Methods
&lt;/h2&gt;

&lt;p&gt;The Clawdbot documentation supports multiple deployment options out of the box:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. One-Click Installer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://clawd.bot/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run &lt;code&gt;exec bash&lt;/code&gt; to start the setup wizard.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Docker
&lt;/h3&gt;

&lt;p&gt;Official Docker support means you can run Clawdbot alongside your existing containers. Check the official docs for the exact commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Ansible
&lt;/h3&gt;

&lt;p&gt;For automated deployments at scale. Check the official docs at &lt;a href="https://docs.clawd.bot/install/ansible" rel="noopener noreferrer"&gt;https://docs.clawd.bot/install/ansible&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Nix
&lt;/h3&gt;

&lt;p&gt;For reproducible, declarative system configuration. Check the official docs at &lt;a href="https://docs.clawd.bot/install/nix" rel="noopener noreferrer"&gt;https://docs.clawd.bot/install/nix&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Bun
&lt;/h3&gt;

&lt;p&gt;If you prefer Bun's faster runtime. Check the official docs at &lt;a href="https://docs.clawd.bot/install/bun" rel="noopener noreferrer"&gt;https://docs.clawd.bot/install/bun&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Railway
&lt;/h3&gt;

&lt;p&gt;One-click deployment from GitHub. Connect your repo, configure environment variables, and you're running in minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Render
&lt;/h3&gt;

&lt;p&gt;Similar to Railway with a generous free tier for testing. Check the official docs at &lt;a href="https://docs.clawd.bot/render" rel="noopener noreferrer"&gt;https://docs.clawd.bot/render&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Can You Run Clawdbot?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: Cheap VPS Hosting ($3-5/month)
&lt;/h3&gt;

&lt;p&gt;This is the most popular alternative for good reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hetzner&lt;/strong&gt; — Starting around €3.49/month for instances with 4GB RAM and 2 vCPUs. Infrastructure is rock-solid with data centers in Germany, Finland, USA, and Singapore. Setup requires moderate technical knowledge, but documentation is thorough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DigitalOcean&lt;/strong&gt; — Droplets start at $6/month for 1GB RAM, though the $12/month tier with 2GB RAM is what you'll actually want for Clawdbot. Interface is intuitive with a clean dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linode (Akamai)&lt;/strong&gt; — Plans start at $5/month for 1GB RAM instances. Performance is consistent and customer support is notably helpful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Railway&lt;/strong&gt; — One-click Clawdbot template. Connect your GitHub, click deploy, configure a few environment variables, and you're running within minutes. Pricing is usage-based, typically $5-20/month for small to medium instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Render&lt;/strong&gt; — Offers a generous free tier that can run a basic Clawdbot instance, though you'll likely want to upgrade for production use.&lt;/p&gt;

&lt;h3&gt;
  
  
  DigitalOcean Quick Setup (Thanks to Nader Dabit)
&lt;/h3&gt;

&lt;p&gt;Here's a complete guide from Nader Dabit's gist for running Clawdbot on DigitalOcean:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create a Droplet
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 24.04 LTS, nearest region&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Select Premium AMD
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;2 GB RAM / 1 AMD CPU / 50 GB NVMe&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. SSH into server
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh root@YOUR_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Create sudo user
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;adduser clawd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;clawd &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; su - clawd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Install Clawdbot
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://clawd.bot/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run &lt;code&gt;exec bash&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Configure API keys
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;clawdbot setup &lt;span class="nt"&gt;--wizard&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  7. Start gateway
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;clawdbot gateway &lt;span class="nt"&gt;--bind&lt;/span&gt; lan &lt;span class="nt"&gt;--port&lt;/span&gt; 18789
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  8. SSH tunnel to access UI
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-L&lt;/span&gt; 18789:127.0.0.1:18789 clawd@YOUR_IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://127.0.0.1:18789" rel="noopener noreferrer"&gt;http://127.0.0.1:18789&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Free AWS Tier
&lt;/h3&gt;

&lt;p&gt;AWS Free Tier provides up to $200 in credits for new customers and free usage of select services for up to 6 months. You can launch an EC2 instance and run Clawdbot without paying anything initially. Just be careful about scaling beyond free limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 3: Your Old Computer
&lt;/h3&gt;

&lt;p&gt;Got an old laptop or desktop gathering dust? It's probably perfect for Clawdbot.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Any machine with 2GB+ RAM and a dual-core CPU will work&lt;/li&gt;
&lt;li&gt;Linux is preferred but Windows works too&lt;/li&gt;
&lt;li&gt;Install Node.js, clone the repo, and you're set&lt;/li&gt;
&lt;li&gt;Bonus: You already own it, so it's completely free&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Option 4: Raspberry Pi
&lt;/h3&gt;

&lt;p&gt;Yes, really. People are running Clawdbot on Raspberry Pis with Cloudflare tunnels. It's not the fastest option, but it works and costs almost nothing in electricity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 5: Docker Containers
&lt;/h3&gt;

&lt;p&gt;If you're already running Docker somewhere (homelab, NAS, etc.), Clawdbot has official Docker support. Just check the official docs for the exact commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Upfront Cost&lt;/th&gt;
&lt;th&gt;Monthly Cost&lt;/th&gt;
&lt;th&gt;Pros&lt;/th&gt;
&lt;th&gt;Cons&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Mac Mini M2 ($599)&lt;/td&gt;
&lt;td&gt;$599&lt;/td&gt;
&lt;td&gt;$0 (electricity)&lt;/td&gt;
&lt;td&gt;Fast, unified memory&lt;/td&gt;
&lt;td&gt;Expensive upfront, tied to desk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hetzner VPS&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;€3.49 (~$3.75)&lt;/td&gt;
&lt;td&gt;Cheap, 24/7, scalable&lt;/td&gt;
&lt;td&gt;Requires internet, less control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DigitalOcean&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$6-12/month&lt;/td&gt;
&lt;td&gt;Easy setup, good docs&lt;/td&gt;
&lt;td&gt;More expensive than Hetzner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$5-20/month&lt;/td&gt;
&lt;td&gt;One-click deploy, usage-based&lt;/td&gt;
&lt;td&gt;Less control, can get pricey&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0 (free tier)&lt;/td&gt;
&lt;td&gt;Free to start&lt;/td&gt;
&lt;td&gt;Limited resources, upgrade needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Old Computer&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;Free, you own it&lt;/td&gt;
&lt;td&gt;Uses power/space at home&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS Free Tier&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$0 (12 months)&lt;/td&gt;
&lt;td&gt;Free to start&lt;/td&gt;
&lt;td&gt;Complex pricing after free tier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raspberry Pi&lt;/td&gt;
&lt;td&gt;~$35-70&lt;/td&gt;
&lt;td&gt;~$1.2 (electricity)&lt;/td&gt;
&lt;td&gt;Ultra cheap, fun project&lt;/td&gt;
&lt;td&gt;Slow, limited performance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why VPS Might Be Better Than a Mac Mini
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt; — $3.5/month vs $599 upfront. That's 2-4 years of hosting before you break even.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Location&lt;/strong&gt; — Choose data centers near you or your users for lower latency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; — Need more RAM? Upgrade in clicks. No new hardware purchase.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability&lt;/strong&gt; — Professional data centers with 99.9%+ uptime, backups, monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Separation&lt;/strong&gt; — Keep your AI assistant separate from your personal machine. No noise, no heat.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When a Mac Mini Actually Makes Sense
&lt;/h2&gt;

&lt;p&gt;There ARE legitimate reasons to choose a Mac Mini:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want local-only operation (no internet dependency)&lt;/li&gt;
&lt;li&gt;You need maximum performance for local LLMs&lt;/li&gt;
&lt;li&gt;You already have Apple devices and want ecosystem integration&lt;/li&gt;
&lt;li&gt;You value privacy and want physical control of your data&lt;/li&gt;
&lt;li&gt;You're doing GPU-heavy workloads that benefit from Apple silicon&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for most people? A $5 VPS or old computer is more than enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: Choose Your Path
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;For beginners:&lt;/strong&gt; Start with Railway or Render's one-click deploy. You'll be running in 5 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For developers:&lt;/strong&gt; Use Docker or Ansible for reproducible deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For tinkerers:&lt;/strong&gt; Grab an old computer or Raspberry Pi and have fun with it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For production:&lt;/strong&gt; Hetzner or DigitalOcean VPS for reliability and performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;The Clawdbot hype is real, and it's an incredible tool. But don't let FOMO drive you into buying hardware you don't need.&lt;/p&gt;

&lt;p&gt;Start with what you have. Try a $5 VPS. Dust off that old laptop. Join the community on Discord and learn from others who are running it on everything from Raspberry Pis to cloud instances.&lt;/p&gt;

&lt;p&gt;The future of personal AI isn't about buying the most expensive hardware — it's about having an assistant that's always there, remembers everything, and actually helps you get things done.&lt;/p&gt;

&lt;p&gt;And that assistant can run anywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Official Clawdbot Documentation: &lt;a href="https://docs.clawd.bot" rel="noopener noreferrer"&gt;https://docs.clawd.bot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Clawdbot GitHub: &lt;a href="https://github.com/clawdbot/clawdbot" rel="noopener noreferrer"&gt;https://github.com/clawdbot/clawdbot&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Community Discord: &lt;a href="https://discord.com/invite/clawd" rel="noopener noreferrer"&gt;https://discord.com/invite/clawd&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Nader Dabit's DigitalOcean Guide: &lt;a href="https://gist.github.com/dabit3/42cce744beaa6a0d47d6a6783e443636" rel="noopener noreferrer"&gt;https://gist.github.com/dabit3/42cce744beaa6a0d47d6a6783e443636&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Best VPS Providers Guide: &lt;a href="https://onnetpulse.co.ke/best-platforms-to-host-clawdbot" rel="noopener noreferrer"&gt;https://onnetpulse.co.ke/best-platforms-to-host-clawdbot&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Want to see more practical guides like this? Follow me for real-world developer content that saves you time and money.&lt;/p&gt;




&lt;p&gt;👋 About the Author&lt;/p&gt;

&lt;p&gt;If you made it this far, you probably care about shipping fast without breaking things.&lt;/p&gt;

&lt;p&gt;I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.&lt;/p&gt;

&lt;p&gt;What I do:&lt;/p&gt;

&lt;p&gt;🤖 AI agents &amp;amp; chatbot interfaces (yes, including the one you could be using right now)&lt;br&gt;
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)&lt;br&gt;
🛠️ DevTools &amp;amp; NPM packages that actually solve problems&lt;br&gt;
🚀 SEO-optimized web apps that rank&lt;br&gt;
Currently: Building open-source tools and taking on select freelance projects.&lt;/p&gt;

&lt;p&gt;Let's talk:&lt;br&gt;
🐦 Twitter: &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;github.com/SivaramPg&lt;/a&gt;&lt;br&gt;
🌐 Portfolio: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;&lt;br&gt;
📧 Email: [&lt;a href="mailto:dev.sivaramp@gmail.com"&gt;dev.sivaramp@gmail.com&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>clawd</category>
      <category>ai</category>
      <category>automation</category>
    </item>
    <item>
      <title>I Built a Faster PWA Icon Generator in a Weekend</title>
      <dc:creator>Sivaram</dc:creator>
      <pubDate>Mon, 26 Jan 2026 03:37:10 +0000</pubDate>
      <link>https://dev.to/sivarampg/i-built-a-faster-pwa-icon-generator-in-a-weekend-li8</link>
      <guid>https://dev.to/sivarampg/i-built-a-faster-pwa-icon-generator-in-a-weekend-li8</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;&lt;a href="https://www.npmjs.com/package/pwa-icons" rel="noopener noreferrer"&gt;pwa-icons&lt;/a&gt;&lt;/strong&gt; — a fast, interactive CLI that generates all the icons you need for iOS, Android, Windows 11, and favicons from a single image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pwa-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;118 icons in ~0.7 seconds.&lt;/strong&gt; No Chromium. No Puppeteer. Just Sharp and good vibes.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/FxyHmCAT6M0"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every time I start a new PWA project, I dread the icon generation step.&lt;/p&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;26 iOS icons (16px to 1024px)&lt;/li&gt;
&lt;li&gt;6 Android icons (48px to 512px)&lt;/li&gt;
&lt;li&gt;80+ Windows 11 icons (tiles, splash screens, variants)&lt;/li&gt;
&lt;li&gt;Favicons (ICO, PNG, apple-touch-icon)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's &lt;strong&gt;118 images&lt;/strong&gt; from one logo.&lt;/p&gt;

&lt;p&gt;I used to go to &lt;a href="https://www.pwabuilder.com/imageGenerator" rel="noopener noreferrer"&gt;PWABuilder's Image Generator&lt;/a&gt;, upload my image, wait, download the ZIP, extract it... every. single. time.&lt;/p&gt;

&lt;p&gt;There's also an npm package called &lt;code&gt;pwa-asset-generator&lt;/code&gt; — but it uses &lt;strong&gt;Puppeteer and Chromium&lt;/strong&gt;. That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;~200MB Chromium download on first run&lt;/li&gt;
&lt;li&gt;Spawning a browser process for each generation&lt;/li&gt;
&lt;li&gt;Slower than it needs to be&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wanted something &lt;strong&gt;fast&lt;/strong&gt;, &lt;strong&gt;lightweight&lt;/strong&gt;, and &lt;strong&gt;interactive&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Solution: pwa-icons
&lt;/h2&gt;

&lt;p&gt;I built &lt;code&gt;pwa-icons&lt;/code&gt; over a weekend. Here's what makes it different:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Fast — Really Fast
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;118 icons in ~0.7 seconds.&lt;/strong&gt;&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xk307y0vrvbtnues34s.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xk307y0vrvbtnues34s.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How? I use &lt;a href="https://sharp.pixelplumbing.com/" rel="noopener noreferrer"&gt;Sharp&lt;/a&gt; instead of Puppeteer. Sharp is built on libvips — a native C library that processes images in streaming chunks, not full-image buffers.&lt;/p&gt;

&lt;p&gt;No browser. No overhead. Just raw image processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Beautiful Interactive CLI
&lt;/h3&gt;

&lt;p&gt;I hate remembering flags. So I made &lt;code&gt;pwa-icons&lt;/code&gt; fully interactive using &lt;a href="https://github.com/natemoo-re/clack" rel="noopener noreferrer"&gt;@clack/prompts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pwa-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it walks you through everything:&lt;/p&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkr2gfkc1343xaevt3as.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgkr2gfkc1343xaevt3as.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Smart Edge Detection
&lt;/h3&gt;

&lt;p&gt;Most icon generators ask you to pick a background color. But what if your logo already has a background?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pwa-icons&lt;/code&gt; samples &lt;strong&gt;1px from all four edges&lt;/strong&gt; of your image and calculates the average color. This creates backgrounds that naturally extend your image.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Multiple Output Formats
&lt;/h3&gt;

&lt;p&gt;PNG is great, but WebP is &lt;strong&gt;8x smaller&lt;/strong&gt;. AVIF is even smaller.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pwa-icons&lt;/code&gt; supports:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Transparency&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PNG&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Maximum compatibility&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebP&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Modern browsers, ~8x smaller&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AVIF&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Next-gen, smallest files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JPEG&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Universal support&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1mbuhxap5bctau4xatq.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1mbuhxap5bctau4xatq.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Optimization Levels
&lt;/h3&gt;

&lt;p&gt;Choose how aggressively to compress:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;None&lt;/strong&gt; — Maximum quality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Light&lt;/strong&gt; — Good balance (default)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy&lt;/strong&gt; — Smallest files&lt;/li&gt;
&lt;/ul&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyw5p12rugo3fp245rzm.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkyw5p12rugo3fp245rzm.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Favicon Generation
&lt;/h3&gt;

&lt;p&gt;Generates everything you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;favicon/
├── favicon.ico         # Multi-size (16, 32, 48)
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon-48x48.png
├── favicon-192x192.png
└── apple-touch-icon.png  # 180x180
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2w7tn9sph0hnpjcxe3h.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl2w7tn9sph0hnpjcxe3h.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use directly (no install)&lt;/span&gt;
npx pwa-icons

&lt;span class="c"&gt;# Or install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pwa-icons
pwa-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Interactive Mode
&lt;/h3&gt;

&lt;p&gt;Just run it and answer the prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pwa-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyuw2l33dcpgemp81q0dx.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyuw2l33dcpgemp81q0dx.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CLI Mode
&lt;/h3&gt;

&lt;p&gt;For CI/CD or scripting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pwa-icons &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-i&lt;/span&gt; logo.png &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; ./icons &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; ios,android,favicon &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-f&lt;/span&gt; webp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--optimization&lt;/span&gt; light &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Output Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AppImages/
├── ios/
│   ├── 16.png ... 1024.png     # 26 icons
├── android/
│   └── android-launchericon-*.png  # 6 icons
├── windows11/
│   └── *.png                   # 80 icons
├── favicon/
│   └── favicon.ico, *.png      # 6 files
└── icons.json                  # Ready for manifest.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;icons.json&lt;/code&gt; is ready to paste into your PWA manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"icons"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ios/512.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sizes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"512x512"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"android/android-launchericon-192-192.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sizes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192x192"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"favicon/favicon.ico"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"sizes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"16x16 32x32 48x48"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package&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;a href="https://sharp.pixelplumbing.com/" rel="noopener noreferrer"&gt;Sharp&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;libvips-powered image processing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/natemoo-re/clack" rel="noopener noreferrer"&gt;@clack/prompts&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Beautiful terminal prompts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/tj/commander.js" rel="noopener noreferrer"&gt;Commander&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;CLI argument parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/sindresorhus/p-limit" rel="noopener noreferrer"&gt;p-limit&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Concurrency control (10 parallel ops)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/png-to-ico" rel="noopener noreferrer"&gt;png-to-ico&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Multi-size ICO generation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Built with &lt;a href="https://bun.sh" rel="noopener noreferrer"&gt;Bun&lt;/a&gt;, works with Node.js 18+.&lt;/p&gt;




&lt;h2&gt;
  
  
  Test Coverage
&lt;/h2&gt;

&lt;p&gt;I take testing seriously. The codebase has:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Coverage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lines&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;99.33%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tests&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;92&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Run &lt;code&gt;bun test --coverage&lt;/code&gt; to verify.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison with Alternatives
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;pwa-icons&lt;/th&gt;
&lt;th&gt;pwa-asset-generator&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Engine&lt;/td&gt;
&lt;td&gt;Sharp (libvips)&lt;/td&gt;
&lt;td&gt;Puppeteer (Chromium)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Package size&lt;/td&gt;
&lt;td&gt;10 KB&lt;/td&gt;
&lt;td&gt;183 KB + Chromium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;~0.7s for 118 icons&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Interactive CLI&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output formats&lt;/td&gt;
&lt;td&gt;PNG, WebP, AVIF, JPEG&lt;/td&gt;
&lt;td&gt;PNG only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optimization&lt;/td&gt;
&lt;td&gt;3 levels&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edge detection&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;iOS splash screens&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTML/CSS input&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you need iOS device-specific splash screens or HTML/CSS rendering, check out &lt;a href="https://github.com/elegantapp/pwa-asset-generator" rel="noopener noreferrer"&gt;pwa-asset-generator&lt;/a&gt;. It uses Puppeteer for a reason — browser rendering.&lt;/p&gt;

&lt;p&gt;For everything else, &lt;code&gt;pwa-icons&lt;/code&gt; is faster and lighter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Now
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx pwa-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/pwa-icons" rel="noopener noreferrer"&gt;npmjs.com/package/pwa-icons&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/SivaramPg/pwa-icons" rel="noopener noreferrer"&gt;github.com/SivaramPg/pwa-icons&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Star it if you find it useful! ⭐&lt;/p&gt;




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

&lt;p&gt;I built this as part of my personal toolkit for freelance/consulting work. Some ideas for future versions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Maskable icon support&lt;/li&gt;
&lt;li&gt;[ ] iOS splash screen generation&lt;/li&gt;
&lt;li&gt;[ ] Watch mode for development&lt;/li&gt;
&lt;li&gt;[ ] Config file support (&lt;code&gt;.pwaiconsrc&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Got feature requests? &lt;a href="https://github.com/SivaramPg/pwa-icons/issues" rel="noopener noreferrer"&gt;Open an issue!&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! If you found this useful, follow me for more developer tools and tips.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;👋 About the Author&lt;/p&gt;

&lt;p&gt;If you made it this far, you probably care about shipping fast without breaking things.&lt;/p&gt;

&lt;p&gt;I build AI x Crypto MVPs for startups who need to go from idea to working product in weeks, not months.&lt;/p&gt;

&lt;p&gt;What I do:&lt;/p&gt;

&lt;p&gt;🤖 AI agents &amp;amp; chatbot interfaces (yes, including the one you could be using right now)&lt;br&gt;
⛓️ Crypto integrations (EVM, Solana, L2s, Privy, smart contracts)&lt;br&gt;
🛠️ DevTools &amp;amp; NPM packages that actually solve problems&lt;br&gt;
🚀 SEO-optimized web apps that rank&lt;br&gt;
Currently: Building open-source tools and taking on select freelance projects.&lt;/p&gt;

&lt;p&gt;Let's talk:&lt;br&gt;
🐦 Twitter: &lt;a href="https://x.com/SivaramPg" rel="noopener noreferrer"&gt;@SivaramPg&lt;/a&gt;&lt;br&gt;
📦 GitHub: &lt;a href="https://github.com/SivaramPg" rel="noopener noreferrer"&gt;github.com/SivaramPg&lt;/a&gt;&lt;br&gt;
🌐 Portfolio: &lt;a href="https://sivaramp.com" rel="noopener noreferrer"&gt;sivaramp.com&lt;/a&gt;&lt;br&gt;
📧 Email: [&lt;a href="mailto:dev.sivaramp@gmail.com"&gt;dev.sivaramp@gmail.com&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;P.S. If you're building something weird in AI or crypto and want to bounce ideas, my DMs are open. No pitch, just nerding out.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>pwa</category>
      <category>pwabuilder</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
