<?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: zhihu wu</title>
    <description>The latest articles on DEV Community by zhihu wu (@zhihu_wu_dea1d82af01a04d7).</description>
    <link>https://dev.to/zhihu_wu_dea1d82af01a04d7</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%2F3921997%2Fa775d61f-ed57-461b-ac46-ed108350189e.png</url>
      <title>DEV Community: zhihu wu</title>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zhihu_wu_dea1d82af01a04d7"/>
    <language>en</language>
    <item>
      <title>UUIDs in Practice — When Auto-Increment Falls Short</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Fri, 29 May 2026 13:05:09 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/uuids-in-practice-when-auto-increment-falls-short-5d6i</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/uuids-in-practice-when-auto-increment-falls-short-5d6i</guid>
      <description>&lt;p&gt;Most of us learned databases with auto-increment IDs. &lt;code&gt;id INT AUTO_INCREMENT&lt;/code&gt; is in every tutorial. It works — until it doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Case for Auto-Increment
&lt;/h2&gt;

&lt;p&gt;Auto-increment integers are fast, small (4 bytes), and naturally ordered. For a single-database app with one writer, they're perfect. But real systems rarely stay that simple.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Auto-Increment Fails
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Distributed writes.&lt;/strong&gt; When you have multiple API servers writing to the same database, auto-increment creates a bottleneck. Someone has to own the counter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-tenant databases.&lt;/strong&gt; Merging data from different shards or regions? Integer ID collisions are guaranteed. You'll spend days resolving conflicts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data exposure.&lt;/strong&gt; &lt;code&gt;/api/users/1&lt;/code&gt;, &lt;code&gt;/api/users/2&lt;/code&gt;... users and competitors can estimate your growth, user count, and order volume in minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Offline-first apps.&lt;/strong&gt; Can't generate IDs while disconnected if you need a central sequence. UUIDs work anywhere, anytime.&lt;/p&gt;

&lt;h2&gt;
  
  
  UUID v4: The Distributed-Friendly Default
&lt;/h2&gt;

&lt;p&gt;UUID v4 generates 122 random bits via a cryptographically secure PRNG — no coordination needed. The collision probability is astronomically low (1 in 2.7×10^18). PostgreSQL handles them natively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="n"&gt;UUID&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;gen_random_uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 16-byte storage overhead is negligible for modern systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trade-off
&lt;/h2&gt;

&lt;p&gt;UUIDs aren't sortable by insertion order and can fragment B-tree indexes. For write-heavy workloads, consider UUID v7 (time-ordered) or ULID. But for 95% of projects, v4 works fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Tip
&lt;/h2&gt;

&lt;p&gt;When setting up a new project, I generate a batch of UUIDs to copy into my seed files or test fixtures. There's a dead-simple generator at &lt;a href="https://codetoolbox.pro/tools/uuid-generator.html" rel="noopener noreferrer"&gt;codetoolbox.pro/tools/uuid-generator&lt;/a&gt; — no signup, no uploads, all browser-side. Just set the count and go.&lt;/p&gt;

&lt;p&gt;What do you use for primary keys in your projects?&lt;/p&gt;

</description>
      <category>database</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>How Loan Amortization Actually Works (and How to Save Thousands)</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Sun, 24 May 2026 13:03:25 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/how-loan-amortization-actually-works-and-how-to-save-thousands-i81</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/how-loan-amortization-actually-works-and-how-to-save-thousands-i81</guid>
      <description>&lt;p&gt;Most developers understand compound interest for investments. But with debt — mortgages, auto loans, student loans — the same math works against you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Formula Behind Every Loan Payment
&lt;/h2&gt;

&lt;p&gt;Every fixed-rate loan uses this amortization formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;M = P × [r(1+r)^n] / [(1+r)^n − 1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;M&lt;/strong&gt; = monthly payment, &lt;strong&gt;P&lt;/strong&gt; = principal, &lt;strong&gt;r&lt;/strong&gt; = monthly rate (annual ÷ 12), &lt;strong&gt;n&lt;/strong&gt; = total payments.&lt;/p&gt;

&lt;p&gt;The intuition: this exact amount drives your balance to zero by the final payment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Front-Loading Trap
&lt;/h2&gt;

&lt;p&gt;On a $250k mortgage at 6.5% over 30 years, your first payment is roughly &lt;strong&gt;85% interest, 15% principal&lt;/strong&gt;. By year 15 it's 50/50. In the final year, over 95% goes to principal.&lt;/p&gt;

&lt;p&gt;This means every extra dollar toward principal early has an outsized effect. That $100 extra in month 1 saves you 359 months of interest on that $100.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;$250k at 6.5% / 30yr:&lt;/strong&gt; $1,580/mo, total $568,861&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Same at 15yr:&lt;/strong&gt; $2,178/mo, total $392,069 → saves &lt;strong&gt;$176,792&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;$100/mo extra on 30yr:&lt;/strong&gt; Saves ~$49k, pays off 4.5 years early&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3 Simple Strategies
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bi-weekly payments:&lt;/strong&gt; 26 half-payments = 13 full payments/year. Knocks ~5 years off a 30yr mortgage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Round up:&lt;/strong&gt; Pay $1,600 instead of $1,580. The $20 extra compounds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refi but keep old payment:&lt;/strong&gt; When rates drop, keep paying the old amount. The difference is pure principal.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I built a &lt;a href="https://codetoolbox.pro/tools/loan-calculator.html" rel="noopener noreferrer"&gt;free loan calculator&lt;/a&gt; with full amortization schedules and visual breakdowns. Runs in your browser, no signup.&lt;/p&gt;

&lt;p&gt;Understanding amortization isn't just for homeowners — car loans, personal loans, any installment debt. The math is identical. The earlier you act, the more you save.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My 4-Step Regex Debugging Workflow (That Actually Saves Time)</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Thu, 21 May 2026 13:07:23 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/my-4-step-regex-debugging-workflow-that-actually-saves-time-58h5</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/my-4-step-regex-debugging-workflow-that-actually-saves-time-58h5</guid>
      <description>&lt;p&gt;I've written hundreds of regular expressions over the years, and I still get them wrong on the first try. Here's the debugging workflow I've settled on that consistently gets me from "why isn't this matching" to "oh, that's why" in under a minute.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Isolate One Pattern at a Time
&lt;/h2&gt;

&lt;p&gt;The most common mistake I see (and make) is testing a monster regex all at once. If you're validating an email with a complex pattern and it's not working, break it down: test just the local part, then the domain, then combine them. This alone has saved me hours of staring at a wall of backslashes and brackets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Check Your Quantifier Greediness
&lt;/h2&gt;

&lt;p&gt;This one bites everyone. A pattern like &lt;code&gt;&amp;lt;.*&amp;gt;&lt;/code&gt; against &lt;code&gt;"&amp;lt;div&amp;gt;hello&amp;lt;/div&amp;gt;"&lt;/code&gt; matches the &lt;em&gt;entire&lt;/em&gt; string, not just the opening tag. The fix: add &lt;code&gt;?&lt;/code&gt; to make it lazy — &lt;code&gt;&amp;lt;.*?&amp;gt;&lt;/code&gt;. I can't count how many "my regex is broken" posts on Stack Overflow boil down to this. Whenever a pattern matches too much, my first instinct is to check for greedy quantifiers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Toggle the Flags
&lt;/h2&gt;

&lt;p&gt;Flags change everything. &lt;code&gt;hello&lt;/code&gt; matches "hello" — but add the &lt;code&gt;i&lt;/code&gt; flag and &lt;code&gt;hello&lt;/code&gt; now matches "HELLO", "Hello", and "hElLo". The &lt;code&gt;^&lt;/code&gt; anchor matches the start of a string by default, but with the &lt;code&gt;m&lt;/code&gt; (multiline) flag, it matches the start of &lt;em&gt;each line&lt;/em&gt;. I often toggle the &lt;code&gt;g&lt;/code&gt; (global) flag off during debugging to focus on the first match, then turn it back on to check all occurrences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Use a Real-Time Tester
&lt;/h2&gt;

&lt;p&gt;This is the game-changer. Rather than write-test-rewrite cycles in my code editor, I use a live regex tester that highlights matches as I type. Seeing matches highlighted instantly — and seeing capture groups broken out individually — makes pattern bugs obvious in seconds. I use &lt;a href="https://codetoolbox.pro/tools/regex-tester.html" rel="noopener noreferrer"&gt;CodeToolbox Regex Tester&lt;/a&gt; because it runs entirely in the browser (no data uploads) and includes presets for common patterns like email, URL, and IPv4 to use as starting points.&lt;/p&gt;




&lt;p&gt;The complete workflow takes less than a minute once it becomes habit: isolate → check greediness → toggle flags → test live. These four steps have saved me more debugging time than any regex cheatsheet ever has.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What's your go-to regex debugging trick? I'd love to hear what works for you in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>regex</category>
      <category>javascript</category>
      <category>debugging</category>
      <category>webdev</category>
    </item>
    <item>
      <title>5 Markdown Tricks Every Developer Should Know (That Aren't in the Cheat Sheet)</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Tue, 19 May 2026 13:06:43 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/5-markdown-tricks-every-developer-should-know-that-arent-in-the-cheat-sheet-23bh</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/5-markdown-tricks-every-developer-should-know-that-arent-in-the-cheat-sheet-23bh</guid>
      <description>&lt;p&gt;We all know the basics: &lt;code&gt;**bold**&lt;/code&gt;, &lt;code&gt;*italic*&lt;/code&gt;, &lt;code&gt;# Headings&lt;/code&gt;. But Markdown (especially GitHub Flavored Markdown) has some lesser-known tricks that can make your READMEs, docs, and PR descriptions much more polished. Here are five I use constantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Collapsible Sections with &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Got a long README? Hide secondary content behind expandable sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;details&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Click to see the full changelog&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;

- v2.1: Added dark mode
- v2.0: Complete rewrite
- v1.0: Initial release

&lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This renders as a clickable toggle. Perfect for changelogs, setup instructions, or verbose examples you don't want cluttering the main view. GitHub, GitLab, and most static site generators support this.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Auto-Linking to Headings
&lt;/h2&gt;

&lt;p&gt;GitHub auto-generates anchor links for every heading. You can link to any section with a simple relative link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;See the &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;Installation&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;#installation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; section for setup instructions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The rule: lowercase everything, replace spaces with hyphens, remove punctuation. So &lt;code&gt;## API Reference (v2)&lt;/code&gt; becomes &lt;code&gt;#api-reference-v2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bonus:&lt;/strong&gt; This works across files too — &lt;code&gt;[See docs](docs/API.md#authentication)&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Task Lists in PR Descriptions
&lt;/h2&gt;

&lt;p&gt;GFM supports interactive checkboxes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; [x] Add unit tests
&lt;span class="p"&gt;-&lt;/span&gt; [x] Update documentation
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Bump version number
&lt;span class="p"&gt;-&lt;/span&gt; [ ] Deploy to staging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These render as actual checkboxes on GitHub Issues and PRs. Use them in PR templates to create a checklist the author can tick off before merging. They also show up in project boards as trackable items.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Escaping Backticks Inside Inline Code
&lt;/h2&gt;

&lt;p&gt;Sometimes you need to show a literal backtick character inside inline code. The trick? Use &lt;strong&gt;double backticks&lt;/strong&gt; as delimiters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;To display a variable, use &lt;span class="sb"&gt;`` `varname` ``&lt;/span&gt; in your template.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Renders as: To display a variable, use &lt;code&gt;`varname`&lt;/code&gt; in your template.&lt;/p&gt;

&lt;p&gt;The outer double-backtick pair lets you nest single backticks inside. Add a space before/after the inner backtick for readability.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Mermaid Diagrams in Fenced Code Blocks
&lt;/h2&gt;

&lt;p&gt;Many platforms (GitHub, GitLab, Notion) support Mermaid diagrams directly in Markdown. Just use &lt;code&gt;mermaid&lt;/code&gt; as the language tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;
&lt;/span&gt;
mermaid
graph TD
    A[User] --&amp;gt; B[Login Page]
    B --&amp;gt; C{Valid?}
    C --&amp;gt;|Yes| D[Dashboard]
    C --&amp;gt;|No| E[Error Message]


&lt;span class="p"&gt;```&lt;/span&gt;
&lt;span class="p"&gt;```&lt;/span&gt;&lt;span class="nl"&gt;
&lt;/span&gt;
`

This renders a flowchart directly in your README — no external tools, no image exports. Mermaid supports flowcharts, sequence diagrams, Gantt charts, class diagrams, and more.

---

## The Best Way to Learn? Preview in Real Time

The fastest way to get comfortable with Markdown is to see it render as you type. I use [CodeToolbox Markdown Preview](https://codetoolbox.pro/tools/markdown-preview.html) when drafting READMEs — it's free, runs entirely in the browser (nothing gets uploaded), and supports full GFM including tables, task lists, and syntax-highlighted code blocks.

What Markdown tricks do you use that aren't in the standard cheat sheet? Drop them in the comments 👇
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>markdown</category>
      <category>github</category>
      <category>documentation</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How Base64 Actually Works (And Why Every Developer Should Know)</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Sat, 16 May 2026 13:13:13 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/how-base64-actually-works-and-why-every-developer-should-know-k5c</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/how-base64-actually-works-and-why-every-developer-should-know-k5c</guid>
      <description>&lt;p&gt;Base64 encoding is one of those things every developer encounters but few bother to understand. You see it in JWT tokens, data URIs, email attachments — it's everywhere. But what actually happens when you encode something to Base64?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Base64 Exists
&lt;/h2&gt;

&lt;p&gt;Computers work with binary — raw bytes. But many systems (email, JSON, HTML) are text-based and can't handle arbitrary binary data safely. Try stuffing raw image bytes into a JSON payload and you'll get corrupted data or parser errors.&lt;/p&gt;

&lt;p&gt;Base64 solves this by converting &lt;strong&gt;any&lt;/strong&gt; binary data into a string of 64 safe ASCII characters: &lt;code&gt;A-Z&lt;/code&gt;, &lt;code&gt;a-z&lt;/code&gt;, &lt;code&gt;0-9&lt;/code&gt;, &lt;code&gt;+&lt;/code&gt;, and &lt;code&gt;/&lt;/code&gt;. Every character represents exactly 6 bits, which means 3 bytes (24 bits) become 4 Base64 characters. If the input isn't a multiple of 3 bytes, &lt;code&gt;=&lt;/code&gt; padding fills the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where You See It Every Day
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JWT tokens&lt;/strong&gt;: That long string after &lt;code&gt;eyJ...&lt;/code&gt;? Base64-encoded JSON. The payload between the two dots decodes right back to readable claims.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data URIs&lt;/strong&gt;: &lt;code&gt;data:image/png;base64,iVBORw0K...&lt;/code&gt; — inline images in CSS and HTML use Base64 to avoid extra HTTP requests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Basic Auth&lt;/strong&gt;: &lt;code&gt;Authorization: Basic dXNlcjpwYXNz&lt;/code&gt; — that's literally &lt;code&gt;username:password&lt;/code&gt; in Base64. (And no, it's not encryption — anyone can decode it.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email attachments (MIME)&lt;/strong&gt;: Every file attachment in email gets Base64-encoded for safe transport.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Gotcha: Base64 vs Base64URL
&lt;/h2&gt;

&lt;p&gt;If your Base64 string has &lt;code&gt;-&lt;/code&gt; and &lt;code&gt;_&lt;/code&gt; instead of &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt;, you're looking at &lt;strong&gt;Base64URL&lt;/strong&gt; — a variant used in URLs and JWT tokens where &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;/&lt;/code&gt; would cause problems. To decode Base64URL, swap &lt;code&gt;-&lt;/code&gt; → &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;_&lt;/code&gt; → &lt;code&gt;/&lt;/code&gt; first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Base64 Is NOT Encryption
&lt;/h2&gt;

&lt;p&gt;This trips up beginners constantly. Base64 provides &lt;strong&gt;zero security&lt;/strong&gt;. It's encoding, not encryption — anyone can decode it in milliseconds. If you're storing passwords as Base64, you're storing them as plain text. Use bcrypt or Argon2 for that.&lt;/p&gt;

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

&lt;p&gt;Understanding Base64 is one thing — being able to encode and decode it instantly is another. I built a &lt;a href="https://codetoolbox.pro/tools/base64.html" rel="noopener noreferrer"&gt;free Base64 encoder/decoder&lt;/a&gt; that runs entirely in your browser. Paste text or upload a file, and it encodes to Base64 instantly. Paste a Base64 string and it decodes back. It also handles Base64URL, data URIs, and JWT payloads automatically.&lt;/p&gt;

&lt;p&gt;No signup, no server uploads — everything stays on your machine. Give it a try next time you're debugging a JWT or embedding an icon in CSS.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>6 Regex Patterns Every Developer Should Have Bookmarked</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Mon, 11 May 2026 13:10:46 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/6-regex-patterns-every-developer-should-have-bookmarked-bc0</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/6-regex-patterns-every-developer-should-have-bookmarked-bc0</guid>
      <description>&lt;p&gt;I've lost count of how many times I've Googled "regex for email validation" at 11pm. So I finally wrote them down. Here are six patterns I use almost weekly — tested, commented, and ready to copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Extract URLs from text
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'&amp;lt;&amp;gt;]+/gi
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this when scraping, cleaning user input, or pulling links out of a Slack dump. The &lt;code&gt;[^\s"'&amp;lt;&amp;gt;]+&lt;/code&gt; stops at whitespace or HTML delimiters instead of eating the rest of the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Match a valid IPv4 address
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(?:(?:&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;]?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.){&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;}(?:&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="p"&gt;]?&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ugly, yes. But it actually validates the range (0-255) instead of just matching &lt;code&gt;\d+\.\d+\.\d+\.\d+&lt;/code&gt; which would accept 999.999.999.999. Parse config files, extract IPs from logs — this one pays rent.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Strip HTML tags
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&amp;lt;&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="o"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;g
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One-liner that removes everything between angle brackets. Not a full HTML parser (don't use it on nested malformed markup), but perfect for extracting plain text from simple HTML snippets or email bodies.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Match a CSS hex color
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;fA&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;F0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;fA&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;F0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Catches both &lt;code&gt;#FF5733&lt;/code&gt; and &lt;code&gt;#F53&lt;/code&gt;. I use this when auditing design tokens or writing a color-picker tool — it pulls every hex value out of a stylesheet in one pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Split a camelCase string into words
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;z0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;])([&lt;/span&gt;&lt;span class="nx"&gt;A&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Z&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;g&lt;/span&gt;  &lt;span class="err"&gt;→&lt;/span&gt;  &lt;span class="nx"&gt;replace&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;$1&lt;/span&gt; &lt;span class="nx"&gt;$2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;myVariableName&lt;/code&gt; becomes &lt;code&gt;my Variable Name&lt;/code&gt;. Useful for generating human-readable labels from code identifiers — I use it all the time when building admin panels from API field names.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Validate a reasonable email address
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/^&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;@]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="p"&gt;@[&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;@]&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="p"&gt;.[&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;@]{&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,}&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No, it doesn't implement RFC 5322. But it catches typos, missing @ signs, and empty domains — which is 99% of what you need on a signup form. For actual email verification, send a confirmation link.&lt;/p&gt;




&lt;p&gt;I test all my patterns in this &lt;a href="https://codetoolbox.pro/tools/regex-tester.html" rel="noopener noreferrer"&gt;free Regex Tester&lt;/a&gt; before committing them — it highlights matches, shows capture groups, and has common presets. Saves me from alt-tabbing to a Node REPL every five minutes.&lt;/p&gt;

&lt;p&gt;What's the one regex you keep copy-pasting? Drop it in the comments.&lt;/p&gt;

</description>
      <category>regex</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>URL Encoding: The Developer's Swiss Army Knife You're Probably Using Wrong</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Sun, 10 May 2026 13:52:00 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/url-encoding-the-developers-swiss-army-knife-youre-probably-using-wrong-11j7</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/url-encoding-the-developers-swiss-army-knife-youre-probably-using-wrong-11j7</guid>
      <description>&lt;p&gt;If you've built anything that touches the web, you've dealt with URL encoding. And if you're honest, you've probably Googled "encodeURI vs encodeURIComponent" at least five times this year. I know I have.&lt;/p&gt;

&lt;p&gt;Here's the mental model that finally made it stick for me:&lt;/p&gt;

&lt;h2&gt;
  
  
  The TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;encodeURI()&lt;/code&gt; = "I'm encoding a complete URL" → keeps structural chars like &lt;code&gt;/ ? &amp;amp; #&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;encodeURIComponent()&lt;/code&gt; = "I'm encoding ONE piece of data" → encodes EVERYTHING except &lt;code&gt;A-Z a-z 0-9 - _ . ! ~ * ' ( )&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Things Go Wrong
&lt;/h2&gt;

&lt;p&gt;Last week I spent an hour debugging a 500 error from a payment gateway. The culprit? I used &lt;code&gt;encodeURI()&lt;/code&gt; on a query parameter that contained a &lt;code&gt;#&lt;/code&gt; character. The browser interpreted everything after &lt;code&gt;#&lt;/code&gt; as a fragment identifier and never sent it to the server. &lt;code&gt;encodeURIComponent()&lt;/code&gt; would have caught it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 3 Rules I Now Live By
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Query string values&lt;/strong&gt; → ALWAYS &lt;code&gt;encodeURIComponent()&lt;/code&gt;. No exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full URLs&lt;/strong&gt; → &lt;code&gt;encodeURI()&lt;/code&gt;, but only if you're sure no component contains special chars.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When in doubt&lt;/strong&gt; → &lt;code&gt;encodeURIComponent()&lt;/code&gt;. Worst case: you encode too much. Best case: you avoid a bug.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Sometimes I just want to paste a gnarly URL and see what happens — especially when it's 200 characters long and I don't want to open DevTools. I built a free URL encoder/decoder that runs entirely in the browser. No uploads, no ads, no signup:&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://codetoolbox.pro/tools/url-encoder.html" rel="noopener noreferrer"&gt;Free URL Encoder/Decoder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What URL encoding footgun have you stepped on? I'd love to hear your war stories in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>URL Encoding: The Developer's Swiss Army Knife You're Probably Using Wrong</title>
      <dc:creator>zhihu wu</dc:creator>
      <pubDate>Sat, 09 May 2026 14:51:15 +0000</pubDate>
      <link>https://dev.to/zhihu_wu_dea1d82af01a04d7/url-encoding-the-developers-swiss-army-knife-youre-probably-using-wrong-1nnj</link>
      <guid>https://dev.to/zhihu_wu_dea1d82af01a04d7/url-encoding-the-developers-swiss-army-knife-youre-probably-using-wrong-1nnj</guid>
      <description>&lt;p&gt;URL Encoding: The Developer's Swiss Army Knife You're Probably Using Wrong&lt;/p&gt;

&lt;p&gt;If you've built anything that touches the web, you've dealt with URL encoding. And if you're honest, you've probably Googled "encodeURI vs encodeURIComponent" at least five times this year. I know I have.&lt;/p&gt;

&lt;p&gt;Here's the mental model that finally made it stick for me:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;encodeURI()&lt;/code&gt; = "I'm encoding a complete URL" → keeps structural chars like &lt;code&gt;/ ? &amp;amp; #&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;encodeURIComponent()&lt;/code&gt; = "I'm encoding ONE piece of data" → encodes EVERYTHING except &lt;code&gt;A-Z a-z 0-9 - _ . ! ~ * ' ( )&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When Things Go Wrong
&lt;/h3&gt;

&lt;p&gt;Last week I spent an hour debugging a 500 error from a payment gateway. The culprit? I used &lt;code&gt;encodeURI()&lt;/code&gt; on a query parameter that contained a &lt;code&gt;#&lt;/code&gt; character. The browser interpreted everything after &lt;code&gt;#&lt;/code&gt; as a fragment identifier and never sent it to the server. &lt;code&gt;encodeURIComponent()&lt;/code&gt; would have caught it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The 3 Rules I Now Live By
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Query string values&lt;/strong&gt; → ALWAYS &lt;code&gt;encodeURIComponent()&lt;/code&gt;. No exceptions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full URLs&lt;/strong&gt; → &lt;code&gt;encodeURI()&lt;/code&gt;, but only if you're sure no component contains special chars.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;When in doubt&lt;/strong&gt; → &lt;code&gt;encodeURIComponent()&lt;/code&gt;. Worst case: you encode too much. Best case: you avoid a bug.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  A Free Tool for When You're Lazy
&lt;/h3&gt;

&lt;p&gt;Sometimes I just want to paste a gnarly URL and see what happens — especially when it's 200 characters long and I don't want to open DevTools. I built a &lt;a href="https://codetoolbox.pro/tools/url-encoder.html" rel="noopener noreferrer"&gt;free URL encoder/decoder&lt;/a&gt; that runs entirely in the browser. No uploads, no ads, no signup. Just paste and encode.&lt;/p&gt;

&lt;p&gt;What URL encoding footgun have you stepped on? I'd love to hear your war stories in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
