<?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: Mahmoud 🦀</title>
    <description>The latest articles on DEV Community by Mahmoud 🦀 (@wiseai).</description>
    <link>https://dev.to/wiseai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F827951%2F8d69ab6e-a28d-4d13-9652-bdd2f5eb90f8.png</url>
      <title>DEV Community: Mahmoud 🦀</title>
      <link>https://dev.to/wiseai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wiseai"/>
    <language>en</language>
    <item>
      <title>🔐 OTP RS: RFC-Compliant OTP Input Components for WASM Frameworks</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 04 Oct 2026 11:24:36 +0000</pubDate>
      <link>https://dev.to/wiseai/otp-rs-rfc-compliant-otp-input-components-for-wasm-frameworks-i45</link>
      <guid>https://dev.to/wiseai/otp-rs-rfc-compliant-otp-input-components-for-wasm-frameworks-i45</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Nǐ hǎo 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You've seen the textbox. You've typed the number. You've waited three seconds for the SMS that never came, checked your spam folder, clicked "Resend", typed the number again, and finally admitted to yourself that 2FA is simultaneously the most important and most annoying invention of the modern web.&lt;/p&gt;

&lt;p&gt;Today, we make it marginally less annoying, at least on the Rust side. We're shipping &lt;a href="https://github.com/opensass/otprs" rel="noopener noreferrer"&gt;&lt;strong&gt;OTP RS&lt;/strong&gt;&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/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fns3sf2lxrmgui3d74xyz.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fns3sf2lxrmgui3d74xyz.gif" alt="Ferris Do be vibin" width="80" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Even Is OTP RS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;OTP RS&lt;/strong&gt; is a composable, accessible, animated One-Time Password input component for &lt;strong&gt;Yew&lt;/strong&gt;, &lt;strong&gt;Dioxus&lt;/strong&gt;, and &lt;strong&gt;Leptos&lt;/strong&gt;. It implements the full verifier flow: slot-by-slot input, keyboard navigation, active/filled/invalid/disabled states, animated caret blink, digit-entry pop animation, and &lt;a href="https://rfc-editor.org/info/rfc4226" rel="noopener noreferrer"&gt;RFC 4226 (HOTP)&lt;/a&gt; + &lt;a href="https://www.rfc-editor.org/info/rfc6238" rel="noopener noreferrer"&gt;RFC 6238 (TOTP)&lt;/a&gt; validation, all in Rust, all in WASM, all without touching a single line of JavaScript.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flu7g9tcbso2f22jgqfty.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flu7g9tcbso2f22jgqfty.jpeg" alt="one does not simply implement OTP" width="651" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've ever tried to build a 6-box OTP input from scratch, you know the drill. It starts with "just six inputs". Two hours later you're debugging focus management, backspace propagation, keyboard event edge cases, browser autofill hijacking your state, and the invisible iOS number pad refusing to appear. That's the origin story of OTP RS.&lt;/p&gt;

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

&lt;p&gt;OTP RS follows the same composable anatomy as every other component in the Open SASS Kit. You compose what you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Otp&lt;/code&gt;&lt;/strong&gt;: Root container. Owns the internal value state, focus coordination, and the RFC validation callbacks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Group&lt;/code&gt;&lt;/strong&gt;: A visual cluster of slots (e.g., three digits, then a separator, then three more).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Slot&lt;/code&gt;&lt;/strong&gt;: Individual slot. Renders a visible character display on top of an invisible overlay &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Separator&lt;/code&gt;&lt;/strong&gt;: The little dash in between groups.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;otprs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Otp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Separator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Slot&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[function_component(VerificationInput)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;verification_input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Otp&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&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="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Enter your OTP"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&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="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&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="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&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="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Separator&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&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="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Slot&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Otp&lt;/span&gt;&lt;span class="o"&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;That's it. Focus management, digit propagation, state aggregation, and ARIA attributes are all handled. You just compose slots.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Invisible Input Trick
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsc52a6iybhcjqxplzogv.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsc52a6iybhcjqxplzogv.jpeg" alt="What if I told you ma boy" width="643" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's the most important design decision in all of OTP RS: &lt;strong&gt;the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element that receives keyboard events is completely invisible.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each &lt;code&gt;Slot&lt;/code&gt; renders two layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An invisible &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; (via &lt;code&gt;input-rs&lt;/code&gt; with &lt;code&gt;otp_mode=true&lt;/code&gt;) that is &lt;code&gt;position: absolute; inset: 0; opacity: 0&lt;/code&gt;. It captures all keyboard focus and input events.&lt;/li&gt;
&lt;li&gt;A visible &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; that displays the digit character and the blinking caret.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This separates the &lt;strong&gt;input mechanics&lt;/strong&gt; from the &lt;strong&gt;visual presentation&lt;/strong&gt;, giving us full control over the slot's look without fighting browser defaults for &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; styling.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────┐
│  Slot wrapper       │  ← position: relative; border; background; animation
│  ┌───────────────┐  │
│  │ &amp;lt;input&amp;gt;       │  │  ← absolute; opacity:0; captures keyboard events
│  └───────────────┘  │
│  &amp;lt;span&amp;gt;3&amp;lt;/span&amp;gt;     │  ← visible character display
│  &amp;lt;span class=caret/&amp;gt;│  ← blinking caret (when active &amp;amp; empty)
└─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Invisible Input That Wasn't Actually Invisible
&lt;/h2&gt;

&lt;p&gt;Here's a fun bug that bit us early on, hard.&lt;/p&gt;

&lt;p&gt;The slot design described above only works if the CSS for the invisible input is applied as an &lt;strong&gt;inline &lt;code&gt;style&lt;/code&gt; attribute&lt;/strong&gt;, not as a CSS &lt;code&gt;class&lt;/code&gt; attribute. The component originally passed the overlay CSS string to &lt;code&gt;input_class&lt;/code&gt;, a prop that sets the HTML &lt;code&gt;class=""&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;Browsers don't style elements based on CSS property strings stuck in the class attribute. They look up class names in stylesheets. So what we got instead of an invisible overlay was a white rectangle aggressively covering the entire OTP component, like a censored emoji on live TV.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz92y6bfd9cchnv5tep4w.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz92y6bfd9cchnv5tep4w.jpeg" alt="that's not how this works meme" width="620" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The fix was to add an &lt;code&gt;input_style: &amp;amp;'static str&lt;/code&gt; prop to &lt;code&gt;input-rs&lt;/code&gt; in all three framework implementations, and apply it as &lt;code&gt;style="{props.input_style}"&lt;/code&gt; on the bare otp_mode &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;. One line per framework. Six characters (&lt;code&gt;_style&lt;/code&gt; vs &lt;code&gt;_class&lt;/code&gt;). Three frameworks. Three PRs worth of suffering.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Compiler Is Your Enemy (And Also Your Best Friend)
&lt;/h2&gt;

&lt;p&gt;Let us count the ways Rust fought us this time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Episode 1: Hook in a Macro
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;E0277&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="k"&gt;trait&lt;/span&gt; &lt;span class="n"&gt;bound&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Hook&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Output&lt;/span&gt; &lt;span class="o"&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="n"&gt;IntoPropValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;...&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;satisfied&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We tried calling &lt;code&gt;use_state(...)&lt;/code&gt; inside an &lt;code&gt;html!&lt;/code&gt; macro attribute. Yew forbids calling hooks anywhere except directly inside function component bodies. The macro expands to a closure, and hook calls need to be at the top level. Extracting &lt;code&gt;use_state&lt;/code&gt; calls to &lt;code&gt;let&lt;/code&gt; bindings before &lt;code&gt;html!&lt;/code&gt; fixed it.&lt;/p&gt;
&lt;h3&gt;
  
  
  Episode 2: &lt;code&gt;Box::leak&lt;/code&gt; and the &lt;code&gt;&amp;amp;'static str&lt;/code&gt; Obligation
&lt;/h3&gt;

&lt;p&gt;Dioxus and Leptos's &lt;code&gt;input-rs&lt;/code&gt; props require &lt;code&gt;&amp;amp;'static str&lt;/code&gt;. But our slot-specific strings like &lt;code&gt;"Digit 3"&lt;/code&gt; are computed at runtime. The only way to produce a &lt;code&gt;&amp;amp;'static str&lt;/code&gt; from a runtime &lt;code&gt;String&lt;/code&gt; without pulling in a string interner is to &lt;code&gt;Box::leak&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;leak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Digit {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.into_boxed_str&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;Yes, this leaks memory on every slot render. Each &lt;code&gt;Slot&lt;/code&gt; render leaks ~15 bytes. Is this ideal? No. Does it compile? Yes. Is it the correct long-term solution? The correct long-term solution is a &lt;code&gt;Signal&amp;lt;String&amp;gt;&lt;/code&gt; prop type in input-rs, which is a future PR. For now: &lt;code&gt;Box::leak&lt;/code&gt; and move on.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgumh6q6hvpzuttgh8yn4.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgumh6q6hvpzuttgh8yn4.jpeg" alt="this is fine" width="717" height="349"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Episode 3: The &lt;code&gt;as&lt;/code&gt; Cast That Broke Leptos
&lt;/h3&gt;

&lt;p&gt;The Leptos &lt;code&gt;view!&lt;/code&gt; macro cannot parse Rust cast expressions inline:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This fails to parse inside view!:&lt;/span&gt;
&lt;span class="n"&gt;validate_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&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="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;fn&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="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The macro sees the &lt;code&gt;as&lt;/code&gt; keyword and gets confused about what's a prop name vs. a type expression. The fix: extract to a &lt;code&gt;let&lt;/code&gt; binding &lt;strong&gt;before&lt;/strong&gt; the &lt;code&gt;view!&lt;/code&gt; call:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;always_valid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;fn&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="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// then inside view!:&lt;/span&gt;
&lt;span class="n"&gt;validate_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;always_valid&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Three lines in, five compilation cycles later. We hope this saves you ten minutes.&lt;/p&gt;
&lt;h3&gt;
  
  
  Episode 4: &lt;code&gt;String&lt;/code&gt; vs &lt;code&gt;&amp;amp;str&lt;/code&gt; in Dioxus &lt;code&gt;rsx!&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Dioxus's &lt;code&gt;rsx!&lt;/code&gt; macro is strict about attribute types. When &lt;code&gt;slot_class&lt;/code&gt; was a &lt;code&gt;String&lt;/code&gt;, the macro would refuse:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="err"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="err"&gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;format!("...", ...)&lt;/code&gt; produces a &lt;code&gt;String&lt;/code&gt;. Dioxus attributes want &lt;code&gt;&amp;amp;str&lt;/code&gt;. The same &lt;code&gt;Box::leak&lt;/code&gt; pattern solved this too:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;slot_class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;leak&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{} {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="py"&gt;.variant&lt;/span&gt;&lt;span class="nf"&gt;.to_slot_class&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.into_boxed_str&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;h3&gt;
  
  
  Episode 5: The Inter-Group Focus Traversal Collision
&lt;/h3&gt;

&lt;p&gt;Here is a fun brain teaser: what happens when you put &lt;em&gt;two&lt;/em&gt; OTP components on the exact same page, and you start typing in the second one?&lt;br&gt;
Well, since our slots were originally assigned hardcoded IDs like &lt;code&gt;otp-slot-0&lt;/code&gt;, &lt;code&gt;otp-slot-1&lt;/code&gt;, the moment you typed a character in the second instance, &lt;code&gt;document.getElementById("otp-slot-1")&lt;/code&gt; would aggressively hijack focus and yank your cursor all the way back up to the &lt;em&gt;first&lt;/em&gt; OTP component on the page.&lt;/p&gt;

&lt;p&gt;The fix? Prefixing every slot ID with a unique &lt;code&gt;instance_id&lt;/code&gt; minted from a global atomic counter (&lt;code&gt;OTP_INSTANCE_COUNTER.fetch_add(1, Ordering::Relaxed)&lt;/code&gt;). Now every widget lives in its own perfectly scoped focus namespace, free from neighborhood turf wars.&lt;/p&gt;
&lt;h3&gt;
  
  
  Episode 6: The "Sticky" Backspace (vDOM vs Physical DOM)
&lt;/h3&gt;

&lt;p&gt;Across Leptos and Yew we noticed a bizarre issue: if you typed a character, erased it, and tried typing again, the &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; would refuse to update. Or if you filled the very last slot, the input component became "sticky" and refused to overwrite the final character.&lt;/p&gt;

&lt;p&gt;The root cause was a classic Virtual DOM vs Physical DOM standoff. We were setting the internal state to &lt;code&gt;""&lt;/code&gt;, but frameworks optimize their renders. Leptos &lt;code&gt;input-rs&lt;/code&gt; used a one-way, read-once initialization for &lt;code&gt;value=handle.0.get()&lt;/code&gt;. Yew assumed the string was already empty and ignored the reconciliation. Because the physical HTML &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; wasn't being forcefully synchronized, the raw DOM held onto the sticky character and choked out any new keystrokes.&lt;/p&gt;

&lt;p&gt;We had to bypass the frameworks entirely and manually flush the physical DOM element inside the keyboard event handlers using raw Web APIs (&lt;code&gt;input_ref.cast::&amp;lt;web_sys::HtmlInputElement&amp;gt;().unwrap().set_value("")&lt;/code&gt;). The lesson here? Sometimes the fastest way out of a reactive state desync is a direct, imperative smash to the physical DOM.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7amt7en2dkhidry7rkli.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7amt7en2dkhidry7rkli.jpeg" alt="it keeps happening" width="660" height="379"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Keyboard Navigation
&lt;/h2&gt;

&lt;p&gt;One of the more satisfying pieces: full keyboard navigation across slots.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Any character key&lt;/strong&gt; → fills current slot, auto-advances focus to the next&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Backspace&lt;/code&gt;&lt;/strong&gt; → clears current slot; if already empty, goes to the previous slot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ArrowLeft&lt;/code&gt;&lt;/strong&gt; → jumps to previous slot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;ArrowRight&lt;/code&gt;&lt;/strong&gt; → jumps to next slot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Tab&lt;/code&gt;&lt;/strong&gt; → advances naturally (browser default, we don't intercept)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this is handled in the &lt;code&gt;on_slot_keydown&lt;/code&gt; callback in the parent &lt;code&gt;Otp&lt;/code&gt; component, which uses &lt;code&gt;NodeRef&lt;/code&gt; (Yew) or the equivalent signal-based refs (Dioxus/Leptos) to imperatively &lt;code&gt;.focus()&lt;/code&gt; the target input.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Backspace"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// slot is already empty, go back&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slot_refs&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="py"&gt;.cast&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HtmlInputElement&lt;/span&gt;&lt;span class="o"&gt;&amp;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;let&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="nf"&gt;.focus&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;No third-party focus-trap libraries. No jQuery. Pure DOM manipulation from Rust.&lt;/p&gt;
&lt;h2&gt;
  
  
  HOTP and TOTP Validation
&lt;/h2&gt;

&lt;p&gt;OTP RS ships RFC 4226 (HOTP) and RFC 6238 (TOTP) implementations using &lt;a href="https://crates.io/crates/totp-rs" rel="noopener noreferrer"&gt;&lt;code&gt;totp-rs&lt;/code&gt;&lt;/a&gt;. The SHA-1 HMAC is hand-rolled using the standard iterative block compression algorithm:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;validate_hotp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;digits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;OtpValidationError&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;let&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;hotp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;digits&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expected&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;OtpValidationError&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HotpMismatch&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;You can validate on complete:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;on_complete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;code&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="nf"&gt;validate_hotp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"your-secret"&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;code&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;web_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;console&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;log_1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="s"&gt;"Valid!"&lt;/span&gt;&lt;span class="nf"&gt;.into&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="nf"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;web_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;console&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;warn_1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nd"&gt;format!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{e:?}"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.into&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 &lt;code&gt;hotp()&lt;/code&gt; function also lets you generate the expected code if you need to display a hint in development. For the HOTP example in the landing page, the valid code for secret &lt;code&gt;JBSWY3DPEHPK3PXP&lt;/code&gt; at counter 0 is computed at runtime via &lt;code&gt;hotp(b"JBSWY3DPEHPK3PXP", 0, 6)&lt;/code&gt;, no hardcoding required.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Setup
&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;# Yew&lt;/span&gt;
cargo add otprs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yew

&lt;span class="c"&gt;# Dioxus&lt;/span&gt;
cargo add otprs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dio

&lt;span class="c"&gt;# Leptos&lt;/span&gt;
cargo add otprs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# Cargo.toml&lt;/span&gt;
&lt;span class="py"&gt;otprs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"yew"&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 component ships its own CSS as inline styles computed from Rust. No separate stylesheet needed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Building OTP RS was a journey through the exact kind of subtle, cross-framework, cross-layer complexity that makes Rust Web development both rewarding and sometimes deeply frustrating. We fought the compiler more than once, discovered ways that browser defaults quietly break invisible design patterns, and shipped a &lt;code&gt;Box::leak&lt;/code&gt; we're not entirely proud of.&lt;/p&gt;

&lt;p&gt;But the result is solid: a composable, keyboard-navigable, RFC-compliant OTP input component that works identically across Yew, Dioxus, and Leptos, with zero JavaScript and enough ARIA to satisfy a WCAG auditor.&lt;/p&gt;

&lt;p&gt;The next time you're building a login flow in Rust WASM and you reach for a six-box code input, you don't have to write it from scratch anymore.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://otp-rs.netlify.app" rel="noopener noreferrer"&gt;&lt;br&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%2Fqcspj4eqdqxf6dp022kl.png" alt="Try It Out" width="215" height="66"&gt;&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%2Fwl06pc60hq9ugm11p8vp.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%2Fwl06pc60hq9ugm11p8vp.png" alt="Try It" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;
        opensass
      &lt;/a&gt; / &lt;a href="https://github.com/opensass/otprs" rel="noopener noreferrer"&gt;
        otprs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🔐 A highly customizable OTP component for WASM frameworks (Powered by Input RS).
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🔐 OTP RS&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/otprs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/99c979b578eac0caf385178102db5a682324271fa35878e410cbc97bf35c3b78/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f6f74707273" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/otprs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/605694ec18192e4e88b5a6d6d75324745591bf6e335f926f8dfd3435dcc511a3/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f642f6f74707273" alt="Crates.io Downloads"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/459a3bd96f34d40adfa48f7ea9f148fe03e5601b8e88cc12ec7b48149a0a5f40/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f6f74707273"&gt;&lt;img src="https://camo.githubusercontent.com/459a3bd96f34d40adfa48f7ea9f148fe03e5601b8e88cc12ec7b48149a0a5f40/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f6f74707273" alt="Crates.io License"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44b045d4da6c2fd8024c8c66a350a4c8bb9c17faf50009f34dbe64c530de2454/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d616465253230776974682d527573742d3166343235662e7376673f6c6f676f3d72757374266c6f676f436f6c6f723d7768697465" alt="made-with-rust"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a90d14c350ec66cb0b131f5826793f397b954ed4eeeaa002e4285d7ff7f1a54d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e39302532422d626c75652e737667" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ca62441414bacaa54c6c6e5b68e46c76305947b6bf498c4949fc71c1b4b10dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61696e7461696e65642533462d7965732d677265656e2e737667" alt="Maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discord.gg/b5JbvHW5nv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1de0ff4ce5ecb14813fe0a4ae22bfb7ab081d2255bde28b216e2d3dc454524d9/68747470733a2f2f646362616467652e6c696d65732e70696e6b2f6170692f7365727665722f62354a62764857356e76" alt="Open SASS Discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/opensass/otprs/refs/heads/main/assets/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fopensass%2Fotprs%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Live Demo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Yew&lt;/td&gt;
&lt;td&gt;&lt;a href="https://otp-rs.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dioxus&lt;/td&gt;
&lt;td&gt;&lt;a href="https://otp-dio.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leptos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://otp-lep.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📜 Intro&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;A highly customizable, accessible OTP (One-Time Password) input component for WASM frameworks: Yew, Dioxus, and Leptos.&lt;/p&gt;
&lt;p&gt;Supports animated per-slot digit entry with automatic focus traversal, &lt;code&gt;primary&lt;/code&gt; and &lt;code&gt;secondary&lt;/code&gt; visual variants, built-in HOTP/TOTP validation per RFC 4226 and RFC 6238, and full WCAG compliance.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 Why OTP RS?&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Fully Customizable&lt;/strong&gt;: Control every attribute, class, style, variant, pattern, ARIA labels and more, on the outermost container, each group, each slot, and each separator.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⌨ Smart Focus Management&lt;/strong&gt;: Typing a digit automatically advances focus. Backspace regresses focus. Arrow keys navigate left and right.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✨ Animated Entry&lt;/strong&gt;: Each digit pops with a scale animation when entered, and a blinking caret is shown in the active empty slot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔐 Built-in Validation&lt;/strong&gt;: Validate against HOTP (RFC 4226) or TOTP (RFC 6238) using a pure-Rust implementation, no C, no…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/opensass/otprs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are Open SASS, babe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're working tirelessly on making Rust web development extremely easy for everyone.&lt;/p&gt;

&lt;p&gt;If you made it this far, it would be nice if you could &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;join us on Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>rust</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>📋 Form RS: Production-Ready Form Components for WASM Frameworks</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 04 Oct 2026 11:24:25 +0000</pubDate>
      <link>https://dev.to/wiseai/form-rs-production-ready-form-components-for-wasm-frameworks-4c03</link>
      <guid>https://dev.to/wiseai/form-rs-production-ready-form-components-for-wasm-frameworks-4c03</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Salut 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there's one thing that unites frontend developers across every language, framework, and decade of web history, it's a deep, personal, somewhat traumatic relationship with HTML forms.&lt;/p&gt;

&lt;p&gt;You know the drill. You write a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;. You add an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;. You add a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt;. You write the JavaScript to validate it on &lt;code&gt;blur&lt;/code&gt;. You add a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; for the error message. You wire up &lt;code&gt;aria-describedby&lt;/code&gt; so screen readers can find the error. You set &lt;code&gt;aria-invalid&lt;/code&gt; on the input. You set &lt;code&gt;aria-required&lt;/code&gt;. You check &lt;code&gt;event.preventDefault()&lt;/code&gt;. You realize you've been writing a custom form library for the last four hours. You consider leaving the industry.&lt;/p&gt;

&lt;p&gt;That stops today. We're shipping &lt;a href="https://github.com/opensass/form-rs" rel="noopener noreferrer"&gt;&lt;strong&gt;Form RS&lt;/strong&gt;&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/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqczhcuyhpnfgc1757270.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqczhcuyhpnfgc1757270.gif" alt="chillin ferris" width="136" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Form RS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Form RS&lt;/strong&gt; is a fully composable, WCAG 2.2 AA compliant, production-ready form component library for &lt;strong&gt;Yew&lt;/strong&gt;, &lt;strong&gt;Dioxus&lt;/strong&gt;, and &lt;strong&gt;Leptos&lt;/strong&gt;. It wraps &lt;a href="https://github.com/opensass/input-rs" rel="noopener noreferrer"&gt;&lt;strong&gt;Input RS&lt;/strong&gt;&lt;/a&gt; for the actual &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; rendering, provides a complete context-driven architecture for validation state propagation, and ships seven discrete components that you can mix freely.&lt;/p&gt;

&lt;p&gt;Think of it as the form library you would build yourself if you had time, patience, and hadn't already burned both writing &lt;code&gt;&amp;lt;div class="form-group"&amp;gt;&lt;/code&gt; for the 8000th time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Seven Components
&lt;/h2&gt;

&lt;p&gt;Form RS ships a composable hierarchy, not a monolith.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Form&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The outermost container. Wraps &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; with configurable &lt;code&gt;method&lt;/code&gt;, &lt;code&gt;action&lt;/code&gt;, &lt;code&gt;enctype&lt;/code&gt;, &lt;code&gt;autocomplete&lt;/code&gt;, ARIA labels, and submit/reset/invalid callbacks. There are two validation modes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;ValidationBehavior&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Native&lt;/span&gt;   &lt;span class="c1"&gt;// HTML5 + browser popups (default)&lt;/span&gt;
&lt;span class="nn"&gt;ValidationBehavior&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Aria&lt;/span&gt;     &lt;span class="c1"&gt;// Real-time ARIA errors, no popups, submit never blocked&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Control&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The context provider. Wraps a single field, distributes &lt;code&gt;disabled&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, &lt;code&gt;focused&lt;/code&gt;, &lt;code&gt;required&lt;/code&gt;, &lt;code&gt;variant&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, and &lt;code&gt;size&lt;/code&gt; state to every child that reads &lt;code&gt;FormControlContext&lt;/code&gt;. Your labels and helper text automatically inherit this state without prop drilling.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Label&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Renders a &lt;code&gt;&amp;lt;label&amp;gt;&lt;/code&gt; that visually and semantically tracks the control's state. It goes red when there's an error. It glows when focused. It shows the required asterisk automatically. You don't have to think about any of this.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In Yew:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="n"&gt;html_for&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;focused&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;false&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="s"&gt;"Email address"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Helper&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element below the input. Changes color based on validation state:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Helper&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;true&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="s"&gt;"Not a valid email."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Helper&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Helper&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;true&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="s"&gt;"Looks great!"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Helper&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Three states, zero class strings.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Group&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Groups related checkboxes or radio buttons in a &lt;code&gt;&amp;lt;fieldset&amp;gt;&lt;/code&gt;-adjacent &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. The &lt;code&gt;row&lt;/code&gt; prop flips the layout from column to horizontal. The &lt;code&gt;aria_label&lt;/code&gt; wires up a &lt;code&gt;role="group"&lt;/code&gt; for screen readers.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;ControlLabel&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Wraps a form control (checkbox, radio, switch) with its associated label text. Controls label placement (&lt;code&gt;End&lt;/code&gt;, &lt;code&gt;Start&lt;/code&gt;, &lt;code&gt;Top&lt;/code&gt;, &lt;code&gt;Bottom&lt;/code&gt;), required asterisks, and disabled styling.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ControlLabel&lt;/span&gt;
    &lt;span class="n"&gt;control&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt; &lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"checkbox"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Email notifications"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="n"&gt;label_placement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;LabelPlacement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;End&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Field&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the one you'll use most. A drop-in composition of &lt;code&gt;Control + Label + Input + Helper&lt;/code&gt; with reactive focus rings, error/valid ring states, ARIA attributes, and helper text management.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
    &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Email address"&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="k"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
    &lt;span class="n"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ferris@opensass.org"&lt;/span&gt;
    &lt;span class="n"&gt;helper_text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Enter a valid email."&lt;/span&gt;
    &lt;span class="n"&gt;required&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;full_width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
    &lt;span class="n"&gt;valid_handle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;email_valid&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;
    &lt;span class="n"&gt;validate_function&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validate_email&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One component. Fully wired. WCAG compliant. You're done.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiiezjh4vh6gcpbgmns6h.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiiezjh4vh6gcpbgmns6h.png" alt="it just works" width="683" height="366"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Validation Architecture
&lt;/h2&gt;

&lt;p&gt;Form RS supports two distinct validation paradigms:&lt;/p&gt;
&lt;h3&gt;
  
  
  Native HTML5 Validation
&lt;/h3&gt;

&lt;p&gt;Uses browser-native &lt;code&gt;required&lt;/code&gt;, &lt;code&gt;pattern&lt;/code&gt;, &lt;code&gt;minlength&lt;/code&gt;, &lt;code&gt;maxlength&lt;/code&gt;, and &lt;code&gt;type="email"&lt;/code&gt; constraints. The browser handles error messages. Form submission is blocked on invalid fields. This is the &lt;code&gt;ValidationBehavior::Native&lt;/code&gt; default.&lt;/p&gt;
&lt;h3&gt;
  
  
  External/ARIA Validation
&lt;/h3&gt;

&lt;p&gt;Pass a &lt;code&gt;ValidationState&lt;/code&gt; explicitly, from a server response, a complex cross-field rule, or your own logic:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;ValidationState&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;None&lt;/span&gt;        &lt;span class="c1"&gt;// No judgment, untouched&lt;/span&gt;
&lt;span class="nn"&gt;ValidationState&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Valid&lt;/span&gt;       &lt;span class="c1"&gt;// Green ring, success helper text&lt;/span&gt;
&lt;span class="nn"&gt;ValidationState&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Invalid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;// Red ring, error helper text, aria-invalid="true"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Server errors? Set &lt;code&gt;validation_state={ValidationState::Invalid("Email already in use.".into())}&lt;/code&gt; on the field. The error surfaces immediately. The ARIA is correct. Done.&lt;/p&gt;
&lt;h2&gt;
  
  
  Accessibility Built In
&lt;/h2&gt;

&lt;p&gt;This isn't "we added aria-label" accessibility. This is the real thing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every &lt;code&gt;Field&lt;/code&gt; generates a unique &lt;code&gt;{id}-helper&lt;/code&gt; element ID and passes it as &lt;code&gt;aria-describedby&lt;/code&gt; on the underlying &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aria-required&lt;/code&gt; and &lt;code&gt;aria-invalid&lt;/code&gt; are set precisely based on prop + validation state, not just "always true".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Helper&lt;/code&gt; renders with &lt;code&gt;role="alert"&lt;/code&gt; when in error state, so screen reader users hear errors without tabbing to them.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Label&lt;/code&gt; is always linked to its input via &lt;code&gt;for&lt;/code&gt;/&lt;code&gt;html_for&lt;/code&gt;. No floating labels that break semantics.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Group&lt;/code&gt; propagates &lt;code&gt;role="group"&lt;/code&gt; with &lt;code&gt;aria-label&lt;/code&gt; for checkbox/radio clusters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Audit-passing HTML forms. In Rust. Across three WASM frameworks.&lt;/p&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;ValidationState&lt;/code&gt; Pattern
&lt;/h2&gt;

&lt;p&gt;This is the piece that makes server-side validation ergonomic:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;ValidationState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Valid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;Invalid&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Pass &lt;code&gt;None&lt;/code&gt; on a fresh field. Pass &lt;code&gt;Valid&lt;/code&gt; once you've confirmed on the backend. Pass &lt;code&gt;Invalid&lt;/code&gt; with your error message string when the server rejects it. The component does the rest.&lt;/p&gt;
&lt;h2&gt;
  
  
  Variant, Color, and Size System
&lt;/h2&gt;

&lt;p&gt;Form RS exposes a full semantic token system for the input appearance:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Visual input style&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Outlined&lt;/span&gt;  &lt;span class="c1"&gt;// Default, bordered input box&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Filled&lt;/span&gt;    &lt;span class="c1"&gt;// Solid filled background&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Standard&lt;/span&gt;  &lt;span class="c1"&gt;// Bottom-border only&lt;/span&gt;

&lt;span class="c1"&gt;// Accent color (rings, labels, helper text)&lt;/span&gt;
&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Primary&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Secondary&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Info&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Warning&lt;/span&gt;

&lt;span class="c1"&gt;// Input density&lt;/span&gt;
&lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Small&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Medium&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Building a dense admin data-entry form? &lt;code&gt;Size::Small&lt;/code&gt;. Consumer onboarding flow? &lt;code&gt;Size::Medium&lt;/code&gt;. Dark theme with error highlights? &lt;code&gt;Color::Error&lt;/code&gt;. The system handles the visual output; you just name the intent.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Setup
&lt;/h2&gt;

&lt;p&gt;Stop writing raw HTML form boilerplate. Do this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Yew&lt;/span&gt;
cargo add form-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yew

&lt;span class="c"&gt;# Dioxus&lt;/span&gt;
cargo add form-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dio

&lt;span class="c"&gt;# Leptos&lt;/span&gt;
cargo add form-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;p&gt;Forms are foundational. Every user interaction that matters, login, registration, checkout, profile editing, contact, search, flows through a form. Getting them right means getting ARIA right, validation right, focus state right, and error surfacing right. Every time. On every field.&lt;/p&gt;

&lt;p&gt;Form RS is the answer to "who has time for all of that." We did. You don't have to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://form-rs.netlify.app" rel="noopener noreferrer"&gt;&lt;br&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%2Fqcspj4eqdqxf6dp022kl.png" alt="Try It Out" width="215" height="66"&gt;&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%2Fwl06pc60hq9ugm11p8vp.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%2Fwl06pc60hq9ugm11p8vp.png" alt="Try It" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;
        opensass
      &lt;/a&gt; / &lt;a href="https://github.com/opensass/form-rs" rel="noopener noreferrer"&gt;
        form-rs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      📋 A highly customizable Form component for WASM frameworks (Powered by Input RS).
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;📋 Form RS&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/form-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/914def72e9822842f27ce04ffbe02abeb937ac8a292eebca685b30adcd902eed/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f666f726d2d7273" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/form-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/baea95c455274af1eb77ab50feaa5a0ca76934a046ecdbcaa0387a463856b143/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f642f666f726d2d7273" alt="Crates.io Downloads"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/24654307ae01cacd5f0ed9b82e587918acb5fc25eb5cdf7e36961991633598b1/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f666f726d2d7273"&gt;&lt;img src="https://camo.githubusercontent.com/24654307ae01cacd5f0ed9b82e587918acb5fc25eb5cdf7e36961991633598b1/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f666f726d2d7273" alt="Crates.io License"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44b045d4da6c2fd8024c8c66a350a4c8bb9c17faf50009f34dbe64c530de2454/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d616465253230776974682d527573742d3166343235662e7376673f6c6f676f3d72757374266c6f676f436f6c6f723d7768697465" alt="made-with-rust"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/31c82dd347f4da3b0ee4fb00bdbab1450d962c202a7f1d46feeb52cb06c634fb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e38392532422d626c75652e737667" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ca62441414bacaa54c6c6e5b68e46c76305947b6bf498c4949fc71c1b4b10dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61696e7461696e65642533462d7965732d677265656e2e737667" alt="Maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discord.gg/b5JbvHW5nv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1de0ff4ce5ecb14813fe0a4ae22bfb7ab081d2255bde28b216e2d3dc454524d9/68747470733a2f2f646362616467652e6c696d65732e70696e6b2f6170692f7365727665722f62354a62764857356e76" alt="Open SASS Discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/opensass/form-rs/refs/heads/main/assets/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fopensass%2Fform-rs%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Live Demo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Yew&lt;/td&gt;
&lt;td&gt;&lt;a href="https://form-rs.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dioxus&lt;/td&gt;
&lt;td&gt;&lt;a href="https://form-dio.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leptos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://form-lep.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📜 Intro&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;A highly customizable, accessible form component library for WASM frameworks: Yew, Dioxus, and Leptos.
Supports HTML5 and ARIA validation, composable sub-components (&lt;code&gt;Form&lt;/code&gt;, &lt;code&gt;Control&lt;/code&gt;, &lt;code&gt;FormLabel&lt;/code&gt;,
&lt;code&gt;Helper&lt;/code&gt;, &lt;code&gt;Group&lt;/code&gt;, &lt;code&gt;ControlLabel&lt;/code&gt;, &lt;code&gt;Field&lt;/code&gt;), and full WCAG 2.2 AA compliance.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 Why Form RS?&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Fully Customizable&lt;/strong&gt;: Control variant, color, size, class, style, ARIA labels, and every sub-component attribute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 Composable API&lt;/strong&gt;: Mix &lt;code&gt;Form&lt;/code&gt;, &lt;code&gt;Control&lt;/code&gt;, &lt;code&gt;FormLabel&lt;/code&gt;, &lt;code&gt;Helper&lt;/code&gt;, &lt;code&gt;Group&lt;/code&gt;, &lt;code&gt;ControlLabel&lt;/code&gt;, and &lt;code&gt;Field&lt;/code&gt; independently or together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;✅ Dual Validation&lt;/strong&gt;: Supports native HTML5 validation and real-time ARIA error messaging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;♿ Accessible by Default&lt;/strong&gt;: &lt;code&gt;aria-describedby&lt;/code&gt;, &lt;code&gt;aria-required&lt;/code&gt;, &lt;code&gt;aria-invalid&lt;/code&gt;, and &lt;code&gt;role="alert"&lt;/code&gt; wired up automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔧 Framework Agnostic&lt;/strong&gt;: Same API semantics across Yew, Dioxus, and Leptos.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Y Yew Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/form-rs/blob/main/YEW.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/opensass/form-rs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are Open SASS, babe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're working tirelessly on making Rust web development extremely easy for everyone.&lt;/p&gt;

&lt;p&gt;If you made it this far, it would be nice if you could &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;join us on Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>rust</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🖥️ Code RS: CDN-Free Syntax-Highlighted Code Components for WASM</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 04 Oct 2026 11:24:17 +0000</pubDate>
      <link>https://dev.to/wiseai/code-rs-cdn-free-syntax-highlighted-code-components-for-wasm-njc</link>
      <guid>https://dev.to/wiseai/code-rs-cdn-free-syntax-highlighted-code-components-for-wasm-njc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Privyet 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You know that moment when you paste a &lt;code&gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;/code&gt; block into your app and it looks like it was styled in 2003 by someone who had just discovered &lt;code&gt;color: green&lt;/code&gt;? No theme. No copy button. No language badge. Just raw, uncolored text sitting in a box that someone called "good enough"?&lt;/p&gt;

&lt;p&gt;Yeah. We fixed that. Today we're shipping &lt;a href="https://github.com/opensass/coders" rel="noopener noreferrer"&gt;&lt;strong&gt;Code RS&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5p3yzfxcd12l7l45st9y.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5p3yzfxcd12l7l45st9y.jpeg" alt="One does not simply"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Code RS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Code RS&lt;/strong&gt; is a production-ready, fully-themed, accessible code display component for &lt;strong&gt;Yew&lt;/strong&gt;, &lt;strong&gt;Dioxus&lt;/strong&gt;, and &lt;strong&gt;Leptos&lt;/strong&gt;. It does everything the ecosystem was missing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inline &lt;code&gt;&amp;lt;Code&amp;gt;&lt;/code&gt;&lt;/strong&gt;: colored, sized, variant-aware, with ARIA semantics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;&amp;lt;Block&amp;gt;&lt;/code&gt;&lt;/strong&gt;: a composable container with header, title, language badge, copy trigger, and scrollable content area.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pure-Rust syntax highlighting&lt;/strong&gt;: zero CDN, zero JavaScript, compiles to clean WASM, 20+ languages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 built-in themes&lt;/strong&gt;: OneDark, Dracula, NightOwl, GitHub Dark/Light, Solarized, Monokai, Nord, all switchable via a single &lt;code&gt;theme&lt;/code&gt; prop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No Prism.js. No highlight.js. No 10MB script tag loaded from a CDN you definitely trust completely. Just Rust, bytes, and inline &lt;code&gt;style=&lt;/code&gt; spans.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Big Idea
&lt;/h2&gt;

&lt;p&gt;Here's the thing about syntax highlighting in WASM apps: every existing solution assumes JavaScript. Prism.js needs a DOM. highlight.js needs a runtime. Shiki needs Node. Tree-sitter is great, but it weighs as much as a sedan.&lt;/p&gt;

&lt;p&gt;So we wrote our own.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmanuf7qi630dqih250ak.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmanuf7qi630dqih250ak.jpeg" alt="Pure-Rust tokenizer, no biggie"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;highlight_code(code, lang, theme)&lt;/code&gt; function in &lt;code&gt;common.rs&lt;/code&gt; is a hand-rolled, char-by-char tokenizer that handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Block comments (&lt;code&gt;/* */&lt;/code&gt;), single-line comments (&lt;code&gt;//&lt;/code&gt;, &lt;code&gt;#&lt;/code&gt;, &lt;code&gt;--&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Double/single-quoted strings and JS template literals&lt;/li&gt;
&lt;li&gt;Hex and float number literals with suffixes (&lt;code&gt;0xFF&lt;/code&gt;, &lt;code&gt;1.0f32&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Rust macros (&lt;code&gt;println!&lt;/code&gt;, &lt;code&gt;vec!&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Python/CSS decorators (&lt;code&gt;@dataclass&lt;/code&gt;, &lt;code&gt;@media&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;HTML tag names (&lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;/span&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;PascalCase → type, ALL_CAPS → constant, &lt;code&gt;ident(&lt;/code&gt; → function call&lt;/li&gt;
&lt;li&gt;Language-specific keyword sets (Rust, Python, TypeScript, SQL, Bash, 16 more)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All token spans get &lt;strong&gt;inline &lt;code&gt;style=&lt;/code&gt; attributes&lt;/strong&gt; from the chosen theme. No CSS classes. No external stylesheet. Just &lt;code&gt;&amp;lt;span style="color:#c678dd;font-weight:600"&amp;gt;fn&amp;lt;/span&amp;gt;&lt;/code&gt;, and it works everywhere, including iframes and shadow DOM.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;coders&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;highlight_code&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;highlight_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fn main() {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    println!(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;Language&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nn"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Dracula&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// → "&amp;lt;span style="color:#ff79c6;font-weight:600"&amp;gt;fn&amp;lt;/span&amp;gt; ..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Code&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The simplest unit. A &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; element with color, variant, and size props.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Yew&lt;/span&gt;
&lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Subtle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sm&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="s"&gt;"console.log(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Hello, world!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&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="n"&gt;Code&lt;/span&gt;&lt;span class="o"&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;Variants work exactly as you'd expect from the rest of Open SASS Kit: &lt;code&gt;Solid&lt;/code&gt;, &lt;code&gt;Subtle&lt;/code&gt;, &lt;code&gt;Outline&lt;/code&gt;, &lt;code&gt;Surface&lt;/code&gt;, &lt;code&gt;Plain&lt;/code&gt;. Colors are the full palette: &lt;code&gt;Default&lt;/code&gt;, &lt;code&gt;Red&lt;/code&gt;, &lt;code&gt;Orange&lt;/code&gt;, &lt;code&gt;Yellow&lt;/code&gt;, &lt;code&gt;Green&lt;/code&gt;, &lt;code&gt;Teal&lt;/code&gt;, &lt;code&gt;Accent&lt;/code&gt;, &lt;code&gt;Pink&lt;/code&gt;, &lt;code&gt;Success&lt;/code&gt;, &lt;code&gt;Warning&lt;/code&gt;, &lt;code&gt;Danger&lt;/code&gt;, and &lt;code&gt;Custom("your-inline-css")&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Block&lt;/code&gt;
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Leptos&lt;/span&gt;
&lt;span class="nd"&gt;view!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;
        &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fn main() {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    println!(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;}"&lt;/span&gt;
        &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Language&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rust&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NightOwl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s"&gt;"main.rs"&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LanguageBadge&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CopyTrigger&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="o"&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;The &lt;code&gt;Block&lt;/code&gt; pushes a &lt;code&gt;BlockContext&lt;/code&gt; containing &lt;code&gt;code&lt;/code&gt;, &lt;code&gt;language&lt;/code&gt;, and &lt;code&gt;theme&lt;/code&gt; into a provider tree. All child components read from context. &lt;code&gt;Content&lt;/code&gt; calls &lt;code&gt;highlight_code&lt;/code&gt; and injects the result via &lt;code&gt;inner_html&lt;/code&gt; / &lt;code&gt;dangerous_inner_html&lt;/code&gt; / &lt;code&gt;Html::from_html_unchecked&lt;/code&gt;, the framework-appropriate unsafe-but-correct escape hatch for pre-rendered HTML. No prop drilling. No callback chains. Just context.&lt;/p&gt;
&lt;h2&gt;
  
  
  8 Themes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4d6ty5vtj0lt7in1kdso.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4d6ty5vtj0lt7in1kdso.jpeg" alt="Just right"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Theme&lt;/th&gt;
&lt;th&gt;Background&lt;/th&gt;
&lt;th&gt;Vibe&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OneDark&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#1a1a2e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The classic. Atom's gift to the world.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Dracula&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#282a36&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Halloween every day. Pink keywords.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NightOwl&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#011627&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deep blue, warm salmon numbers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GithubDark&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#0d1117&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Feels like GitHub, because it is.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GithubLight&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#ffffff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;For those who dare use light mode.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Solarized&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#002b36&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ethan Schoonover's gift to the terminal.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Monokai&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#272822&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The Sublime Text nostalgia trip.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Nord&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#2e3440&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Arctic. Clean. Borderline peaceful.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Switch themes at runtime by simply changing the &lt;code&gt;theme&lt;/code&gt; prop. The &lt;code&gt;ThemeColors&lt;/code&gt; struct drives inline style generation, every &lt;code&gt;push_span()&lt;/code&gt; call pulls the exact CSS value from the active theme's fields.&lt;/p&gt;

&lt;p&gt;Need your brand colors? &lt;code&gt;Theme::Custom(ThemeColors { keyword: "color:#ff0099;font-weight:600", ... })&lt;/code&gt; and you're done.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Build Journey
&lt;/h2&gt;

&lt;p&gt;We are not going to pretend this was a relaxing weekend project. Here is an honest accounting.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxyw4cyx4pq74mywzcze.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxyw4cyx4pq74mywzcze.jpeg" alt="Expectations vs Reality"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Chapter 1: The Rust 2024 Edition
&lt;/h3&gt;

&lt;p&gt;Rust Edition 2024 changed how string-like identifiers in macro positions are parsed. The &lt;code&gt;yew::html!&lt;/code&gt; macro started rejecting class names like &lt;code&gt;text-black&lt;/code&gt; and &lt;code&gt;whitespace-pre&lt;/code&gt;, specifically the hyphen-adjacent tokens that look like prefix expressions.&lt;/p&gt;

&lt;p&gt;The error: &lt;code&gt;prefix 'black' is unknown&lt;/code&gt;. The fix: add a trailing space after the class name. Simple, but it wasted an embarrassing amount of time because the error message looks nothing like what it actually is.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Before (breaks in Edition 2024):&lt;/span&gt;
&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex text-black"&lt;/span&gt;
&lt;span class="c1"&gt;// After:&lt;/span&gt;
&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"flex text-black "&lt;/span&gt;  &lt;span class="c1"&gt;// ← single space, problem solved&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Chapter 2: Dioxus RSX
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;rsx!&lt;/code&gt; macro in Dioxus parses string prop values as format strings. So this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"fn main() {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    println!(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Explodes with &lt;code&gt;Failed to parse formatted segment: Expected Ident or Exp&lt;/code&gt;. Because &lt;code&gt;{&lt;/code&gt; inside a string prop is format syntax to Dioxus, not a literal curly brace.&lt;/p&gt;

&lt;p&gt;The fix: extract all code strings to &lt;code&gt;const&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;HELLO_WORLD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"fn main() {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    println!(&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;Hello!&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s"&gt;);&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;}"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;rsx!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Block&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;HELLO_WORLD&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;Unglamorous? Yes. But it compiles.&lt;/p&gt;
&lt;h3&gt;
  
  
  Chapter 3: The &lt;code&gt;dangerous_inner_html&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In Dioxus, &lt;code&gt;dangerous_inner_html&lt;/code&gt; takes ownership of a &lt;code&gt;String&lt;/code&gt;. In Leptos, &lt;code&gt;inner_html&lt;/code&gt; takes a &lt;code&gt;&amp;amp;str&lt;/code&gt;. In Yew, &lt;code&gt;Html::from_html_unchecked&lt;/code&gt; takes an &lt;code&gt;AttrValue&lt;/code&gt;. Three frameworks, three signatures, three slightly different ways to inject a pre-rendered HTML string.&lt;/p&gt;

&lt;p&gt;Each one worked fine once you knew the exact type expected. Getting there required reading the framework source, not the docs, because the docs had helpfully omitted the borrow semantics.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkx1qo7k9qkr2x1cw51ob.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkx1qo7k9qkr2x1cw51ob.jpeg" alt="Fine dababy"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Chapter 4: Non-Exhaustive &lt;code&gt;Variant::Custom&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Adding &lt;code&gt;Custom(&amp;amp;'static str)&lt;/code&gt; to the &lt;code&gt;Variant&lt;/code&gt; enum immediately broke every match in all three &lt;code&gt;Code&lt;/code&gt; component implementations. Expected. Annoying. The fix is the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;But finding all three match sites across three files while also trying to fix four other things simultaneously is exactly the kind of thing that makes you wish Rust had &lt;code&gt;#[non_exhaustive]&lt;/code&gt; as an opt-in marker you could flip during development.&lt;/p&gt;
&lt;h2&gt;
  
  
  Accessibility
&lt;/h2&gt;

&lt;p&gt;Code RS ships accessible markup out of the box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Block&lt;/code&gt; renders as &lt;code&gt;&amp;lt;figure role="region"&amp;gt;&lt;/code&gt; with &lt;code&gt;aria-label&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The inner &lt;code&gt;&amp;lt;pre&amp;gt;&lt;/code&gt; gets &lt;code&gt;tabindex="0"&lt;/code&gt; so keyboard users can scroll it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CopyTrigger&lt;/code&gt; carries &lt;code&gt;aria-label="Copy code to clipboard"&lt;/code&gt; and &lt;code&gt;aria-live&lt;/code&gt; region feedback via the copied label swap.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Code&lt;/code&gt; accepts &lt;code&gt;aria_label&lt;/code&gt; for use in contexts where &lt;code&gt;&amp;lt;code&amp;gt;&lt;/code&gt; alone doesn't carry enough meaning.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LanguageBadge&lt;/code&gt; reads the language from context and renders &lt;code&gt;aria-label="Language: rust"&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Screen readers don't need to guess what anything is.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Setup
&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;# Yew&lt;/span&gt;
cargo add coders &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yew

&lt;span class="c"&gt;# Dioxus&lt;/span&gt;
cargo add coders &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dio

&lt;span class="c"&gt;# Leptos&lt;/span&gt;
cargo add coders &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it. The syntax highlighting, theming, clipboard, and accessibility, all included. No config files. No CSS imports. No &lt;code&gt;npm install @something/highlighter-peer-dependency&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Writing a CDN-free, pure-WASM syntax highlighter from scratch to ship alongside a composable code block component is not the most efficient path. But it's the correct one for this ecosystem.&lt;/p&gt;

&lt;p&gt;The web has enough &lt;code&gt;&amp;lt;script src="https://cdn.example.com/dep.min.js"&amp;gt;&lt;/code&gt; tags. Rust WASM doesn't need to inherit that habit.&lt;/p&gt;

&lt;p&gt;Code RS compiles to WASM, highlights code inline, and ships 8 themes without a single network request beyond your app bundle. That's the promise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code-rs.netlify.app" rel="noopener noreferrer"&gt;&lt;br&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%2Fqcspj4eqdqxf6dp022kl.png" alt="Try It Out"&gt;&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%2Fwl06pc60hq9ugm11p8vp.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%2Fwl06pc60hq9ugm11p8vp.png" alt="Try It"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;
        opensass
      &lt;/a&gt; / &lt;a href="https://github.com/opensass/coders" rel="noopener noreferrer"&gt;
        coders
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      💻 A highly customizable code component for WASM frameworks.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;💻 Code RS&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/coders" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/080837a72b46befa0fe601eb51c45056406bcfd34d3ad958d75a93d7018ca951/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f636f64657273" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/coders" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/951633484351026d612af79011b5eeae3b1e1c6580885f1084fb138e5ac87879/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f642f636f64657273" alt="Crates.io Downloads"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/581a82e93aeccae36e646c4b776cf252912f9f7dd4c5a0890341efd64aa7600d/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f636f64657273"&gt;&lt;img src="https://camo.githubusercontent.com/581a82e93aeccae36e646c4b776cf252912f9f7dd4c5a0890341efd64aa7600d/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f636f64657273" alt="Crates.io License"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44b045d4da6c2fd8024c8c66a350a4c8bb9c17faf50009f34dbe64c530de2454/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d616465253230776974682d527573742d3166343235662e7376673f6c6f676f3d72757374266c6f676f436f6c6f723d7768697465" alt="made-with-rust"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/31c82dd347f4da3b0ee4fb00bdbab1450d962c202a7f1d46feeb52cb06c634fb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e38392532422d626c75652e737667" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ca62441414bacaa54c6c6e5b68e46c76305947b6bf498c4949fc71c1b4b10dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61696e7461696e65642533462d7965732d677265656e2e737667" alt="Maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discord.gg/b5JbvHW5nv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1de0ff4ce5ecb14813fe0a4ae22bfb7ab081d2255bde28b216e2d3dc454524d9/68747470733a2f2f646362616467652e6c696d65732e70696e6b2f6170692f7365727665722f62354a62764857356e76" alt="Open SASS Discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/opensass/coders/refs/heads/main/assets/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fopensass%2Fcoders%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Live Demo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Yew&lt;/td&gt;
&lt;td&gt;&lt;a href="https://code-rs.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dioxus&lt;/td&gt;
&lt;td&gt;&lt;a href="https://code-dio.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leptos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://code-lep.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📜 Intro&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;A highly customizable, accessible inline code and code-block component for WASM frameworks: Yew, Dioxus, and Leptos. Supports multiple colors, variants, sizes, copy-to-clipboard, and composable sub-components, all WCAG compliant.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 Why Code RS?&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Fully Customizable&lt;/strong&gt;: Control every attribute, class, style, color, variant, size, ARIA labels, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📋 Copy to Clipboard&lt;/strong&gt;: Built-in copy button with a configurable confirmation label and reset timeout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 Composable&lt;/strong&gt;: Compose &lt;code&gt;Header&lt;/code&gt;, &lt;code&gt;Title&lt;/code&gt;, &lt;code&gt;CopyTrigger&lt;/code&gt;, &lt;code&gt;Content&lt;/code&gt;, and &lt;code&gt;LanguageBadge&lt;/code&gt; independently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;♿ Accessible by Default&lt;/strong&gt;: &lt;code&gt;role="region"&lt;/code&gt;, &lt;code&gt;aria-label&lt;/code&gt;, &lt;code&gt;aria-live&lt;/code&gt; and &lt;code&gt;tabindex&lt;/code&gt; wired up automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔧 Framework Agnostic&lt;/strong&gt;: Same API semantics across Yew, Dioxus, and Leptos.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Y Yew Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/coders/blob/main/YEW.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into your Yew app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🧬 Dioxus Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/coders/blob/main/DIOXUS.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into your Dioxus app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🌱&lt;/h2&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/opensass/coders" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are Open SASS, babe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're working tirelessly on making Rust web development extremely easy for everyone.&lt;/p&gt;

&lt;p&gt;If you made it this far, it would be nice if you could &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;join us on Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>rust</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🃏 Card RS: Extremely Customizable Card component for WASM frameworks</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 27 Sep 2026 11:11:08 +0000</pubDate>
      <link>https://dev.to/wiseai/card-rs-extremely-customizable-card-component-for-wasm-frameworks-1j0c</link>
      <guid>https://dev.to/wiseai/card-rs-extremely-customizable-card-component-for-wasm-frameworks-1j0c</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Salut tout le monde 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If there is one layout component that has been re-implemented more times than the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, it's the Card. Think about it. Every widget, every dashboard panel, every pricing tier, every shiny glowing glassmorphism element you've ever seen is, deep down, a card.&lt;/p&gt;

&lt;p&gt;Instead of writing &lt;code&gt;div class="p-6 border rounded-xl shadow-lg bg-white"&lt;/code&gt; for the 5000th time, we decided to solve cards natively for WASM.&lt;/p&gt;

&lt;p&gt;Today, we're shipping &lt;a href="https://github.com/opensass/card-rs" rel="noopener noreferrer"&gt;&lt;strong&gt;Card RS&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Card RS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Card RS&lt;/strong&gt; is an extremely customizable, production-ready, accessible Card component for &lt;strong&gt;Yew&lt;/strong&gt;, &lt;strong&gt;Dioxus&lt;/strong&gt;, and &lt;strong&gt;Leptos&lt;/strong&gt;. We've extracted all the tedious BEM boilerplate, flexbox wrangling, and ARIA attributes out of your templates, giving you a clean, composable API for building solid UI surfaces.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvu3cf63zifl903lhoc80.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvu3cf63zifl903lhoc80.jpeg" alt="Oprah" width="620" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cards shouldn't be monoliths. If you just need a surface, &lt;code&gt;&amp;lt;Card&amp;gt;&lt;/code&gt; works perfectly alone. If you need standard anatomical parts, stick &lt;code&gt;&amp;lt;Header&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Title&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Content&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;Footer&amp;gt;&lt;/code&gt; in there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Composable Anatomy
&lt;/h2&gt;

&lt;p&gt;The problem with most UI library cards is that they force you into a specific layout. Card RS doesn't mandate structure; it provides logical boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Shell: &lt;code&gt;Card&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The parent wrapper. It renders a clean HTML5 &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; (or whatever ARIA role you need) with our default elevated styling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;card_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;card_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[function_component(MyWidget)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;widget&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt; &lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_labelledby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"widget-title"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="c1"&gt;// the world is yours in here&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt;&lt;span class="o"&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;h3&gt;
  
  
  The Skeleton: Headers, Content, &amp;amp; Footers
&lt;/h3&gt;

&lt;p&gt;Don't want to write inline styles for gaps and flex-columns? Neither do we.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt; &lt;span class="n"&gt;aria_labelledby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"c-title"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"c-title"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Card Title"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"The description lives here."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Any content fits neatly in the main body area."&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Content&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Footer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Confirm"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Confirm"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Footer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The header stacks title and description with precise spacing. The footer handles your action bars. Everything just snaps into place like LEGOs.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ljo5nnra85a7muehcx5.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ljo5nnra85a7muehcx5.jpeg" alt="A perfectly aligned card component" width="444" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Variants and Prominence
&lt;/h2&gt;

&lt;p&gt;Not all cards are created equal. You need visual hierarchy. We provide a &lt;code&gt;Variant&lt;/code&gt; matrix that affects the surface depth and contrast without rewriting class strings.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Variant&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Transparent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// No background, merges with the canvas&lt;/span&gt;
    &lt;span class="nb"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Standard surface layer&lt;/span&gt;
    &lt;span class="n"&gt;Secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Elevated and highlighted&lt;/span&gt;
    &lt;span class="n"&gt;Tertiary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// Premium prominence (perfect for selected items)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Building an interactive pricing selector? Wrap your iterations in a &lt;code&gt;&amp;lt;Card variant={if selected { Variant::Secondary } else { Variant::Default }}&amp;gt;&lt;/code&gt; and your hierarchy logic is done.&lt;/p&gt;
&lt;h2&gt;
  
  
  Framework Parity
&lt;/h2&gt;

&lt;p&gt;Like everything we build, &lt;strong&gt;Card RS&lt;/strong&gt; provides identical API surfaces and behavioral guarantees across all three rusty frontends:&lt;/p&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;Yew&lt;/th&gt;
&lt;th&gt;Dioxus&lt;/th&gt;
&lt;th&gt;Leptos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Card&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Header&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Title&lt;/code&gt; &amp;amp; &lt;code&gt;Description&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Content&lt;/code&gt; &amp;amp; &lt;code&gt;Footer&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Variant Matrix&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Accessible ARIA bindings&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Role overrides&lt;/td&gt;
&lt;td&gt;✅&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 know how to build a card in Leptos, you can build a card in Dioxus. The props are the same. The BEM classes are the same. The logic is identical.&lt;/p&gt;
&lt;h2&gt;
  
  
  Accessibility Built-In
&lt;/h2&gt;

&lt;p&gt;Accessible surfaces are often completely ignored by developers until an audit fails. &lt;strong&gt;Card RS&lt;/strong&gt; is designed strictly around WCAG guidelines.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Card&lt;/code&gt; renders with &lt;code&gt;role="article"&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;We enforce &lt;code&gt;aria_labelledby&lt;/code&gt; to tie structural landmarks to the &lt;code&gt;Title&lt;/code&gt; ID.&lt;/li&gt;
&lt;li&gt;If you want a non-interactive surface, just override it with &lt;code&gt;role="note"&lt;/code&gt; or &lt;code&gt;role="region"&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Accessible structural linking:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt; &lt;span class="n"&gt;aria_labelledby&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"promo-heading"&lt;/span&gt; &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"promo-heading"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"Special Offer!"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Card&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;With one prop, screen readers will now announce "Region: Special Offer!" properly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Customization
&lt;/h2&gt;

&lt;p&gt;We aren't trapping you in our aesthetic. Want a weird horizontally-aligned flex-row card with a gradient background? Just use the &lt;code&gt;style&lt;/code&gt; prop. Card RS accepts your CSS strings eagerly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Setup
&lt;/h2&gt;

&lt;p&gt;Stop copying and pasting giant Tailwind HTML blobs. Do this instead:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Yew&lt;/span&gt;
cargo add card-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yew

&lt;span class="c"&gt;# Dioxus&lt;/span&gt;
cargo add card-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dio

&lt;span class="c"&gt;# Leptos&lt;/span&gt;
cargo add card-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;p&gt;The web is made of cards. Taking the time to unify how we create, structure, and render them across Wasm frameworks means we can stop fighting with padding and flexbox alignment, and get back to building real features.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://card-rs.netlify.app" rel="noopener noreferrer"&gt;&lt;br&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%2Fqcspj4eqdqxf6dp022kl.png" alt="Try It Out" width="215" height="66"&gt;&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%2Fwl06pc60hq9ugm11p8vp.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%2Fwl06pc60hq9ugm11p8vp.png" alt="Try It" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;
        opensass
      &lt;/a&gt; / &lt;a href="https://github.com/opensass/card-rs" rel="noopener noreferrer"&gt;
        card-rs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🃏 A highly customizable card component for WASM frameworks
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🃏 Card RS&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/card-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/aec4d66c1d0cd22f203c1693dffa539fdcd1c4dda9548c3093c862ad2163ffd2/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f636172642d7273" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/card-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/05a0e33232aa5c81b38cf2783119f721dae363ffefe6bfb20fe7d99df024d69d/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f642f636172642d7273" alt="Crates.io Downloads"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/acb28f424a370815c5e608ac242d84568744323542f9dd96477cf3634b73be26/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f636172642d7273"&gt;&lt;img src="https://camo.githubusercontent.com/acb28f424a370815c5e608ac242d84568744323542f9dd96477cf3634b73be26/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f636172642d7273" alt="Crates.io License"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44b045d4da6c2fd8024c8c66a350a4c8bb9c17faf50009f34dbe64c530de2454/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d616465253230776974682d527573742d3166343235662e7376673f6c6f676f3d72757374266c6f676f436f6c6f723d7768697465" alt="made-with-rust"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/31c82dd347f4da3b0ee4fb00bdbab1450d962c202a7f1d46feeb52cb06c634fb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e38392532422d626c75652e737667" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ca62441414bacaa54c6c6e5b68e46c76305947b6bf498c4949fc71c1b4b10dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61696e7461696e65642533462d7965732d677265656e2e737667" alt="Maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discord.gg/b5JbvHW5nv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1de0ff4ce5ecb14813fe0a4ae22bfb7ab081d2255bde28b216e2d3dc454524d9/68747470733a2f2f646362616467652e6c696d65732e70696e6b2f6170692f7365727665722f62354a62764857356e76" alt="Open SASS Discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/opensass/card-rs/refs/heads/main/assets/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fopensass%2Fcard-rs%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Live Demo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Yew&lt;/td&gt;
&lt;td&gt;&lt;a href="https://card-rs.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dioxus&lt;/td&gt;
&lt;td&gt;&lt;a href="https://card-dio.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leptos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://card-lep.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📜 Intro&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;A highly customizable, accessible card component for WASM frameworks: Yew, Dioxus, and Leptos.
Supports semantic prominence variants, composable sub-components (header, title, description,
content, footer), and full WCAG compliance.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 Why Card RS?&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Fully Customizable&lt;/strong&gt;: Control variant, class, style, ARIA labels, and every sub-component attribute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 Composable API&lt;/strong&gt;: Use &lt;code&gt;Card&lt;/code&gt;, &lt;code&gt;Header&lt;/code&gt;, &lt;code&gt;Title&lt;/code&gt;, &lt;code&gt;Description&lt;/code&gt;, &lt;code&gt;Content&lt;/code&gt;, and &lt;code&gt;Footer&lt;/code&gt; independently or together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🏷️ Semantic Variants&lt;/strong&gt;: &lt;code&gt;transparent&lt;/code&gt;, &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;secondary&lt;/code&gt;, &lt;code&gt;tertiary&lt;/code&gt;, themes interpret prominence without hard-coded colors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;♿ Accessible by Default&lt;/strong&gt;: &lt;code&gt;role="article"&lt;/code&gt;, &lt;code&gt;aria-labelledby&lt;/code&gt;, and &lt;code&gt;aria-label&lt;/code&gt; wired up automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔧 Framework Agnostic&lt;/strong&gt;: Same API semantics across Yew, Dioxus, and Leptos.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Y Yew Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/card-rs/blob/main/YEW.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into your Yew app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🧬 Dioxus Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/card-rs/blob/main/DIOXUS.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/opensass/card-rs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are Open SASS, babe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're working tirelessly on making Rust web development extremely easy for everyone.&lt;/p&gt;

&lt;p&gt;If you made it this far, it would be nice if you could &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;join us on Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>webdev</category>
      <category>css</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🔴 Badge RS: Easy to Use Badge Components for WASM Frameworks</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 27 Sep 2026 11:08:44 +0000</pubDate>
      <link>https://dev.to/wiseai/badge-rs-easy-to-use-badge-components-for-wasm-frameworks-4p3k</link>
      <guid>https://dev.to/wiseai/badge-rs-easy-to-use-badge-components-for-wasm-frameworks-4p3k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Je vous salue 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every WASM app eventually needs a badge. The little red circle on your notification bell. The green dot on the corner of an avatar. The "99+" that taunts you every morning from the inbox icon. They're everywhere, and somehow everyone is still hand-rolling them.&lt;/p&gt;

&lt;p&gt;That stops today. We're shipping &lt;a href="https://github.com/opensass/badges-rs" rel="noopener noreferrer"&gt;&lt;strong&gt;Badge RS&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Badge RS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Badge RS&lt;/strong&gt; is a production-ready badge component for &lt;strong&gt;Yew&lt;/strong&gt;, &lt;strong&gt;Dioxus&lt;/strong&gt;, and &lt;strong&gt;Leptos&lt;/strong&gt;. Notification counters, status dots, overflow labels, the whole catalogue. It handles positioning, sizing, color theming, dot mode, accessible markup, and even knows the difference between a circle and a rectangle.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqfqp34vjjcwdd8132hhj.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqfqp34vjjcwdd8132hhj.jpeg" alt="one does not simply center a badge on a circular avatar" width="651" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've ever opened your browser devtools at 11pm trying to figure out why a badge is floating 4px off the corner of an avatar instead of sitting flush on the arc, Badge RS is the component you wish had existed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Anchor&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The positioning wrapper. Drop it around any element and it becomes a badge target. Uses &lt;code&gt;position: relative; display: inline-flex;&lt;/code&gt; so it doesn't break your layout, doesn't eat your accessibility tree, and doesn't require you to memorize any CSS tricks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;badges_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Anchor&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;badges_rs&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[function_component(NotificationBell)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;notification_bell&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Anchor&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Inbox, 5 unread messages"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&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="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;
                &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"5 unread messages"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Anchor&lt;/span&gt;&lt;span class="o"&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;That's it. The badge positions itself. You decide where.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Badge&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The actual indicator. Pass children and you get a labeled badge with text inside. Skip children and you get a compact do, no extra prop needed, just don't put anything inside.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// A labeled count badge&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sm&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"5 unread"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// A status dot, no children, no extra prop&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;placement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BottomRight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Online"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Same component, two modes. The dot is not a separate component.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;BadgeLabel&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A thin &lt;code&gt;&amp;lt;span class="badge__label"&amp;gt;&lt;/code&gt; wrapper. Used automatically when you pass plain text to &lt;code&gt;Badge&lt;/code&gt;. Expose it directly when you need extra CSS classes or styling on the label slot.&lt;/p&gt;
&lt;h2&gt;
  
  
  Colors, Variants, Sizes
&lt;/h2&gt;

&lt;p&gt;The full set of knobs is available:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Colors&lt;/span&gt;
&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Default&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Warning&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt;

&lt;span class="c1"&gt;// Variants (three visual styles)&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Primary&lt;/span&gt;    &lt;span class="c1"&gt;// solid fill&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Secondary&lt;/span&gt;  &lt;span class="c1"&gt;// outlined&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Soft&lt;/span&gt;       &lt;span class="c1"&gt;// muted, lower-contrast&lt;/span&gt;

&lt;span class="c1"&gt;// Sizes&lt;/span&gt;
&lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sm&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Md&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Lg&lt;/span&gt;

&lt;span class="c1"&gt;// Placement&lt;/span&gt;
&lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TopRight&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;TopLeft&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BottomRight&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BottomLeft&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;All combinations work. TopLeft is there for RTL layouts and anyone who likes to be contrarian about badge placement.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Positioning Bug Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Here's the subtle one. &lt;code&gt;top: 0; right: 0&lt;/code&gt; with &lt;code&gt;transform: translate(50%, -50%)&lt;/code&gt; centers a badge perfectly on the corner of a &lt;strong&gt;rectangle&lt;/strong&gt;. That's fine for icon buttons, list items, or anything with a square bounding box.&lt;/p&gt;

&lt;p&gt;For a &lt;strong&gt;circle&lt;/strong&gt;, which is what every avatar in existence is, the story is different. A circle's actual edge at 45° sits inward from the bounding box corner. The geometric offset is exactly &lt;code&gt;1 - sin(45°)&lt;/code&gt;, which works out to roughly &lt;strong&gt;14.64%&lt;/strong&gt; of the element's width and height.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u5nnmj96400cbtbwqwn.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9u5nnmj96400cbtbwqwn.jpeg" alt="math lady" width="681" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most badge implementations ignore this. The badge floats slightly off the arc, nobody files a bug, and the designer quietly seethes.&lt;/p&gt;

&lt;p&gt;Badge RS exposes a &lt;code&gt;Shape&lt;/code&gt; enum to handle this explicitly:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// top: 0; right: 0, standard bounding box corner&lt;/span&gt;
    &lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// top: 14.64%; right: 14.64%, sits on the arc&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// On a circular avatar, badge sits flush on the arc:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"3"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// On a square icon button, badge sits on the bounding box corner:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rectangle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"New"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"New"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The math is not magic. It's just trigonometry that nobody wanted to look up at 11pm. We looked it up for you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Framework Parity
&lt;/h2&gt;

&lt;p&gt;All three frameworks ship the same API surface:&lt;/p&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;Yew&lt;/th&gt;
&lt;th&gt;Dioxus&lt;/th&gt;
&lt;th&gt;Leptos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Anchor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Badge&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BadgeLabel&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;Shape::Circle&lt;/code&gt; offset&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dot mode (no children)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All placements&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;All variants&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ARIA attributes&lt;/td&gt;
&lt;td&gt;✅&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've used it in Yew, you already know how to use it in Dioxus and Leptos. The prop names don't even change.&lt;/p&gt;
&lt;h2&gt;
  
  
  Accessibility
&lt;/h2&gt;

&lt;p&gt;Accessible badges are an afterthought in most libraries. In Badge RS they're mandatory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Badge&lt;/code&gt; renders with &lt;code&gt;role="status"&lt;/code&gt; and a required &lt;code&gt;aria_label&lt;/code&gt;. Screen readers announce the content without the user having to navigate to it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;aria-atomic="true"&lt;/code&gt; ensures the full label is re-read when the count updates. A badge that goes from "3" to "4" reads "4 unread messages", not just "4".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Anchor&lt;/code&gt; renders as a &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; with no ARIA role, because it's structural glue and should be invisible to assistive technology.&lt;/li&gt;
&lt;li&gt;The WCAG guidance on badges is straightforward: &lt;strong&gt;label the element that owns the badge, not just the badge itself&lt;/strong&gt;. We mention this in the docs and the examples follow it throughout.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The accessible way, the host element's label includes the count&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="n"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Inbox, 5 unread messages"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&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="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"5 unread messages"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The badge label and the host's aria-label should tell the same story from different angles.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Setup
&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;# Yew&lt;/span&gt;
cargo add badges-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yew

&lt;span class="c"&gt;# Dioxus&lt;/span&gt;
cargo add badges-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dio

&lt;span class="c"&gt;# Leptos&lt;/span&gt;
cargo add badges-rs &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;No CSS framework required. Styles are computed inline from the prop values.&lt;/p&gt;
&lt;h2&gt;
  
  
  Dot Mode vs Count Mode
&lt;/h2&gt;

&lt;p&gt;One component, two modes, no separate component for each. This matters because it keeps your import surface small and your mental model consistent.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Count mode, children present&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"5 messages"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// Dot mode, no children, badge renders as a small filled circle&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;placement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BottomRight&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Online"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The dot is a first-class mode with its own size calculations. &lt;code&gt;Size::Sm&lt;/code&gt; in dot mode renders a 6×6px dot. In count mode, it renders a 16×16px pill. The size label refers to the visual weight, not a fixed pixel value.&lt;/p&gt;
&lt;h2&gt;
  
  
  Status Indicators
&lt;/h2&gt;

&lt;p&gt;The placement prop combined with dot mode covers the most common avatar status pattern:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;badges_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;leptos&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Anchor&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;badges_rs&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;leptos&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[component]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;UserAvatar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;IntoView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;view!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Anchor&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;
                &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/* your avatar CSS */"&lt;/span&gt;
                &lt;span class="n"&gt;aria&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Jane Doe, online"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="s"&gt;"JD"&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Badge&lt;/span&gt;
                &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;
                &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nn"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Circle&lt;/span&gt;
                &lt;span class="n"&gt;placement&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nn"&gt;Placement&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BottomRight&lt;/span&gt;
                &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Online"&lt;/span&gt;
            &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Anchor&lt;/span&gt;&lt;span class="o"&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;Green dot, bottom-right, perfectly on the arc. That's the whole pattern.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxjso8jyvkbxme41vjc0n.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxjso8jyvkbxme41vjc0n.jpeg" alt="it works, deploy it" width="447" height="447"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What We Didn't Do
&lt;/h2&gt;

&lt;p&gt;No magic threshold that auto-truncates to "99+". That's application logic, not component logic. We show whatever you pass in. If you want &lt;code&gt;count.min(99).to_string()&lt;/code&gt; or &lt;code&gt;"99+"&lt;/code&gt;, that's two lines in your own code.&lt;/p&gt;

&lt;p&gt;No auto-detection of the parent element's shape. That would require measuring the DOM at runtime, which is expensive. Instead: explicit &lt;code&gt;shape&lt;/code&gt; prop. You know your own design system. Tell us.&lt;/p&gt;

&lt;p&gt;No CSS injection. No global stylesheet to import. No BEM class naming conventions to memorize. The styles live on the element.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Badge RS&lt;/strong&gt; is compact by design. Three components, one enum, one positioning decision that most libraries get wrong.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Shape&lt;/code&gt; prop is the detail worth remembering. If you're putting badges on circular avatars and they look slightly off, that's the fix. Try &lt;code&gt;Shape::Circle&lt;/code&gt; and stop adjusting pixel offsets in your component stylesheets.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://badges-rs.netlify.app" rel="noopener noreferrer"&gt;&lt;br&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%2Fqcspj4eqdqxf6dp022kl.png" alt="Try It Out" width="215" height="66"&gt;&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%2Fwl06pc60hq9ugm11p8vp.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%2Fwl06pc60hq9ugm11p8vp.png" alt="Try It" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;
        opensass
      &lt;/a&gt; / &lt;a href="https://github.com/opensass/badges-rs" rel="noopener noreferrer"&gt;
        badges-rs
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🏷️ A highly customizable badge component for WASM frameworks.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🏷️ Badges RS&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/badges-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5e2f7d8b4cee002d878621939ed713f3232ef4489b55a84b96a3f4912e20847d/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f6261646765732d7273" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/badges-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/2bece83e83e1570bf59f69764afed53a9b45a04640519f7f47f90994ae34b1d2/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f642f6261646765732d7273" alt="Crates.io Downloads"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a9cc2654773e402fc68cb216f1e855aee03925e8d599a60a9118ec7ded24a306/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f6261646765732d7273"&gt;&lt;img src="https://camo.githubusercontent.com/a9cc2654773e402fc68cb216f1e855aee03925e8d599a60a9118ec7ded24a306/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f6261646765732d7273" alt="Crates.io License"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44b045d4da6c2fd8024c8c66a350a4c8bb9c17faf50009f34dbe64c530de2454/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d616465253230776974682d527573742d3166343235662e7376673f6c6f676f3d72757374266c6f676f436f6c6f723d7768697465" alt="made-with-rust"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/31c82dd347f4da3b0ee4fb00bdbab1450d962c202a7f1d46feeb52cb06c634fb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e38392532422d626c75652e737667" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ca62441414bacaa54c6c6e5b68e46c76305947b6bf498c4949fc71c1b4b10dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61696e7461696e65642533462d7965732d677265656e2e737667" alt="Maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discord.gg/b5JbvHW5nv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1de0ff4ce5ecb14813fe0a4ae22bfb7ab081d2255bde28b216e2d3dc454524d9/68747470733a2f2f646362616467652e6c696d65732e70696e6b2f6170692f7365727665722f62354a62764857356e76" alt="Open SASS Discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/opensass/badges-rs/refs/heads/main/assets/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fopensass%2Fbadges-rs%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Live Demo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Yew&lt;/td&gt;
&lt;td&gt;&lt;a href="https://badges-rs.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dioxus&lt;/td&gt;
&lt;td&gt;&lt;a href="https://badges-dio.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leptos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://badges-lep.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📜 Intro&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;A highly customizable, accessible badge component for WASM frameworks: Yew, Dioxus, and Leptos.
Supports notification counts, status dots, labels, multiple colors, variants, sizes, and placements
with full WCAG compliance.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 Why Badges RS?&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Fully Customizable&lt;/strong&gt;: Control color, variant, size, placement, class, style, and ARIA labels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🔴 Dot Mode&lt;/strong&gt;: When no children are provided the badge renders as a compact status dot.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;📍 Smart Placement&lt;/strong&gt;: Four corner placements (&lt;code&gt;top-right&lt;/code&gt;, &lt;code&gt;top-left&lt;/code&gt;, &lt;code&gt;bottom-right&lt;/code&gt;, &lt;code&gt;bottom-left&lt;/code&gt;) via CSS &lt;code&gt;transform&lt;/code&gt; for pixel-perfect positioning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;♿ Accessible by Default&lt;/strong&gt;: &lt;code&gt;role="status"&lt;/code&gt;, &lt;code&gt;aria-label&lt;/code&gt;, and &lt;code&gt;aria-atomic&lt;/code&gt; wired up automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 Framework Agnostic&lt;/strong&gt;: Same API semantics across Yew, Dioxus, and Leptos.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Y Yew Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/badges-rs/blob/main/YEW.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into your Yew app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🧬 Dioxus Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/badges-rs/blob/main/DIOXUS.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/opensass/badges-rs" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are Open SASS, babe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're working tirelessly on making Rust web development extremely easy for everyone.&lt;/p&gt;

&lt;p&gt;If you made it this far, it would be nice if you could &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;join us on Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>css</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>🪪 Avatar RS: Very Efficient Avatar Components for WASM Frameworks</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 27 Sep 2026 11:01:40 +0000</pubDate>
      <link>https://dev.to/wiseai/avatar-rs-very-efficient-avatar-components-for-wasm-frameworks-3lkn</link>
      <guid>https://dev.to/wiseai/avatar-rs-very-efficient-avatar-components-for-wasm-frameworks-3lkn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Bien le bonjour 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every WASM app eventually needs an avatar. Profile pictures, user cards, comment threads, they're everywhere. And every time, developers end up rolling the same &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag with some fallback logic, hardcoded border-radius, and a prayer that the CDN doesn't return a 404.&lt;/p&gt;

&lt;p&gt;That stops today. We're shipping &lt;a href="https://github.com/opensass/avatar" rel="noopener noreferrer"&gt;&lt;strong&gt;Avatar RS&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Avatar RS?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Avatar RS&lt;/strong&gt; is a fully-featured avatar component for &lt;strong&gt;Yew&lt;/strong&gt;, &lt;strong&gt;Dioxus&lt;/strong&gt;, and &lt;strong&gt;Leptos&lt;/strong&gt;. It handles image loading, fallback text/icons, overflow groups, color themes, size variants, accessible markup, the whole thing. Built on top of &lt;a href="https://github.com/opensass/image-rs" rel="noopener noreferrer"&gt;&lt;strong&gt;Image RS&lt;/strong&gt;&lt;/a&gt;, which means you get smart lazy loading, blur-up placeholders, and responsive layouts for free.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw6aanc5ty0p9osk1356c.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw6aanc5ty0p9osk1356c.jpeg" alt="one does not simply roll their own avatar component" width="651" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think of it as the avatar component you'd build if you had infinite time and zero deadlines. We had neither, but here we are anyway.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stack Under the Hood
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Avatar RS&lt;/strong&gt; wraps &lt;strong&gt;Image RS&lt;/strong&gt;, our WASM-native image primitive, for the actual &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element. This is not a trivial detail.&lt;/p&gt;

&lt;p&gt;Image RS uses &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noopener noreferrer"&gt;Intersection Observer API&lt;/a&gt; for lazy loading, supports &lt;code&gt;srcset&lt;/code&gt;/&lt;code&gt;sizes&lt;/code&gt; for responsive images, and fires clean &lt;code&gt;on_load&lt;/code&gt; / &lt;code&gt;on_error&lt;/code&gt; callbacks. All of that comes for free inside every &lt;code&gt;Image&lt;/code&gt; you render. The avatar layer only adds &lt;strong&gt;context management&lt;/strong&gt; and &lt;strong&gt;state coordination&lt;/strong&gt; on top.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Avatar&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The container. Wraps &lt;code&gt;Image&lt;/code&gt; and &lt;code&gt;Fallback&lt;/code&gt;, provides the shared loading context, and inherits size/color/variant from a surrounding &lt;code&gt;Group&lt;/code&gt; if present.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[function_component(MyProfile)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;my_profile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Ferris Prophet"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;
                &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://i.pravatar.cc/300"&lt;/span&gt;
                &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Ferris Prophet"&lt;/span&gt;
            &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&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="s"&gt;"JD"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt;&lt;span class="o"&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 fallback shows while the image loads, hides once it lands.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Fallback&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Text initials, an icon, or anything you want rendered when the image hasn't loaded yet (or doesn't exist at all). Supports a &lt;code&gt;delay_ms&lt;/code&gt; prop to intentionally delay reveal, useful when your image usually loads fast and you don't want the fallback to flash briefly then disappear.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fallback shows immediately:&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&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="s"&gt;"MH"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// Fallback waits 200ms before appearing (prevents flicker on fast connections):&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt; &lt;span class="n"&gt;delay_ms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&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="s"&gt;"JD"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Small prop, big UX difference.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;code&gt;Group&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Stack multiple avatars with automatic overlap, configurable max count, and an overflow badge showing how many more there are.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;avatar&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;prelude&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="nd"&gt;#[function_component(TeamStack)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;team_stack&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Html&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;html!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;
            &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Lg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&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="n"&gt;total&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&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="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Project team"&lt;/span&gt;
        &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Member 1"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://i.pravatar.cc/150?u=m1"&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Member 1"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&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="s"&gt;"M1"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Member 2"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://i.pravatar.cc/150?u=m2"&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Member 2"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&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="s"&gt;"M2"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt; &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Member 3"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"https://i.pravatar.cc/150?u=m3"&lt;/span&gt; &lt;span class="n"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Member 3"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Warning&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="s"&gt;"M3"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Fallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Avatar&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;
                &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
                &lt;span class="n"&gt;variant&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Soft&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
                &lt;span class="n"&gt;aria_label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"3 more members"&lt;/span&gt;
            &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;Group&lt;/span&gt;&lt;span class="o"&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;Pass &lt;code&gt;max={Some(3)}&lt;/code&gt; and &lt;code&gt;total={Some(6)}&lt;/code&gt;, and &lt;code&gt;Count&lt;/code&gt; automatically shows &lt;code&gt;+3&lt;/code&gt;. The math is done for you. The CSS overlap is done for you. You just write components.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fktuzlbhytd3023ywcg7d.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fktuzlbhytd3023ywcg7d.jpeg" alt="math lady" width="681" height="445"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;overflow_count&lt;/code&gt; Context
&lt;/h2&gt;

&lt;p&gt;This is the part that required actual thought.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Group&lt;/code&gt; computes &lt;code&gt;overflow_count = total - max&lt;/code&gt; and pushes it into context. &lt;code&gt;Count&lt;/code&gt; reads it from context when its own &lt;code&gt;count&lt;/code&gt; prop is zero (the default). This means the badge doesn't need to know anything explicit, it just reads the group state.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In Group:&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;overflow_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="nf"&gt;.saturating_sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ctx_provider&lt;/span&gt;&lt;span class="nf"&gt;.provide&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;GroupContext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;overflow_count&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="c1"&gt;// In Count:&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;effective_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;ctx_overflow&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="c1"&gt;// Renders: "+{effective_count}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One source of truth.&lt;/p&gt;
&lt;h2&gt;
  
  
  Framework Parity
&lt;/h2&gt;

&lt;p&gt;All three frameworks ship the same API surface:&lt;/p&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;Yew&lt;/th&gt;
&lt;th&gt;Dioxus&lt;/th&gt;
&lt;th&gt;Leptos&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Avatar&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Image&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Fallback&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Group&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Count&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;total&lt;/code&gt; + &lt;code&gt;max&lt;/code&gt; overflow&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context propagation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;delay_ms&lt;/code&gt; on fallback&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image RS integration&lt;/td&gt;
&lt;td&gt;✅&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;The Dioxus and Leptos implementation uses &lt;code&gt;use_context_provider&lt;/code&gt; / &lt;code&gt;use_context&lt;/code&gt; idioms native to each framework, but the behavior is identical. If you've used it in Yew, you already know how to use it in Leptos.&lt;/p&gt;
&lt;h2&gt;
  
  
  Soft Refresh &amp;amp; The Browser Cache Fix
&lt;/h2&gt;

&lt;p&gt;Here's one that caught us off guard. In Yew, images rendered via &lt;code&gt;Image&lt;/code&gt; would sometimes fail to appear after a soft page refresh. Hard refresh? Fine. Soft? Gone.&lt;/p&gt;

&lt;p&gt;The culprit: when a browser serves an image from cache, the &lt;code&gt;load&lt;/code&gt; event fires &lt;em&gt;before&lt;/em&gt; Yew has had a chance to attach the listener. The effect sees a "loading" state, the image is already done, and the component never flips to "loaded".&lt;/p&gt;

&lt;p&gt;The fix was straightforward once we knew what to look for. We inject a &lt;code&gt;node_ref&lt;/code&gt; into the underlying &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element and check &lt;code&gt;img.complete&lt;/code&gt; on mount:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nf"&gt;use_effect_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;props&lt;/span&gt;&lt;span class="py"&gt;.src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;move&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="n"&gt;src&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="nf"&gt;.is_empty&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;already_loaded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node_ref&lt;/span&gt;
            &lt;span class="py"&gt;.cast&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nn"&gt;web_sys&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;HtmlImageElement&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;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="nf"&gt;.complete&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;already_loaded&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ImageLoadingStatus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Loaded&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;ImageLoadingStatus&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Loading&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This required adding &lt;code&gt;web-sys&lt;/code&gt; with the &lt;code&gt;HtmlImageElement&lt;/code&gt; feature to the &lt;code&gt;yew&lt;/code&gt; feature gate in &lt;code&gt;Cargo.toml&lt;/code&gt;. A small addition, but it closes a genuinely annoying browser quirk.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4wnh8htpimmv6vyqvz8x.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4wnh8htpimmv6vyqvz8x.jpeg" alt="it works on my machine" width="554" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dioxus and Leptos did not have this issue, their reactive systems handle DOM updates differently and don't suffer from this ordering problem.&lt;/p&gt;
&lt;h2&gt;
  
  
  Colors, Variants, Sizes
&lt;/h2&gt;

&lt;p&gt;Everything inherits downward through context. Set defaults at the group level, override them per-avatar if needed.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Colors&lt;/span&gt;
&lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Default&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Accent&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Warning&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Danger&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Variants&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Default&lt;/span&gt;  &lt;span class="c1"&gt;// solid fill&lt;/span&gt;
&lt;span class="nn"&gt;Variant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Soft&lt;/span&gt;     &lt;span class="c1"&gt;// muted, lower-contrast&lt;/span&gt;

&lt;span class="c1"&gt;// Sizes&lt;/span&gt;
&lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Xs&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Sm&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Md&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Lg&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Xl&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Xxl&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&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;code&gt;Color::Custom("...")&lt;/code&gt; and &lt;code&gt;Size::Custom("...")&lt;/code&gt; accept raw CSS strings, so if your design system uses &lt;code&gt;hsl(270 60% 50%)&lt;/code&gt; or &lt;code&gt;3.5rem&lt;/code&gt;, those work too.&lt;/p&gt;
&lt;h2&gt;
  
  
  Quick Setup
&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;# Yew&lt;/span&gt;
cargo add avatar &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yew

&lt;span class="c"&gt;# Dioxus&lt;/span&gt;
cargo add avatar &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dio

&lt;span class="c"&gt;# Leptos&lt;/span&gt;
cargo add avatar &lt;span class="nt"&gt;--features&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lep
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it. The styling is computed inline from the prop values.&lt;/p&gt;
&lt;h2&gt;
  
  
  Accessibility
&lt;/h2&gt;

&lt;p&gt;Every component exposes its ARIA props explicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Avatar&lt;/code&gt; renders &lt;code&gt;role="img"&lt;/code&gt; with a required &lt;code&gt;aria_label&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Image&lt;/code&gt; manages &lt;code&gt;aria-hidden&lt;/code&gt; based on loading state.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Fallback&lt;/code&gt; is hidden from assistive tech once the image loads.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Group&lt;/code&gt; gets an &lt;code&gt;aria_label&lt;/code&gt; for the whole group.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Count&lt;/code&gt; gets its own &lt;code&gt;aria_label&lt;/code&gt; (defaults to &lt;code&gt;"Additional members"&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Screen readers get a consistent, clear picture regardless of whether images loaded or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  What We Didn't Do
&lt;/h2&gt;

&lt;p&gt;No auto-injection of count badges. No magic child-slicing that differs between frameworks. No runtime diffing of the children list to figure out how many to show. These patterns break in different ways across Yew, Dioxus, and Leptos, and they make the component harder to reason about.&lt;/p&gt;

&lt;p&gt;Instead: &lt;strong&gt;explicit &lt;code&gt;total&lt;/code&gt; and &lt;code&gt;max&lt;/code&gt; props&lt;/strong&gt;, &lt;strong&gt;explicit &lt;code&gt;Count&lt;/code&gt; placement&lt;/strong&gt;, &lt;strong&gt;one context object&lt;/strong&gt; that everything reads from. It's a little more to type. It's a lot easier to debug.&lt;/p&gt;
&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Avatar RS&lt;/strong&gt; is exactly what it says on the tin: a production-ready avatar component for WASM apps.&lt;/p&gt;

&lt;p&gt;It's backed by Image RS, which means you get all the image loading sophistication without reinventing it. The overflow logic is explicit and predictable. Framework parity is real, not aspirational.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://avatar-rs.netlify.app" rel="noopener noreferrer"&gt;&lt;br&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%2Fqcspj4eqdqxf6dp022kl.png" alt="Try It Out" width="215" height="66"&gt;&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%2Fwl06pc60hq9ugm11p8vp.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%2Fwl06pc60hq9ugm11p8vp.png" alt="Try It" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;
        opensass
      &lt;/a&gt; / &lt;a href="https://github.com/opensass/avatar" rel="noopener noreferrer"&gt;
        avatar
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      👦 A highly customizable avatar component for WASM frameworks (Powered by Image RS).
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;👦 Avatar&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/avatar" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b957c3c6a2262900494b96f7916a83d6656f3919f2cf36b10633636335a44eee/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f617661746172" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://crates.io/crates/avatar" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6d1e440630631da77476b3de471b081414c7ae04ef3b3fc8171ed2d67f14e7f5/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f642f617661746172" alt="Crates.io Downloads"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/10a004fc9a4e7b7c49f5eb1cf322f5834de29fe78588b6fd894bbfe8d80a12a7/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f617661746172"&gt;&lt;img src="https://camo.githubusercontent.com/10a004fc9a4e7b7c49f5eb1cf322f5834de29fe78588b6fd894bbfe8d80a12a7/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f6c2f617661746172" alt="Crates.io License"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/44b045d4da6c2fd8024c8c66a350a4c8bb9c17faf50009f34dbe64c530de2454/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d616465253230776974682d527573742d3166343235662e7376673f6c6f676f3d72757374266c6f676f436f6c6f723d7768697465" alt="made-with-rust"&gt;&lt;/a&gt;
&lt;a href="https://www.rust-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/31c82dd347f4da3b0ee4fb00bdbab1450d962c202a7f1d46feeb52cb06c634fb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f527573742d312e38392532422d626c75652e737667" alt="Rust"&gt;&lt;/a&gt;
&lt;a href="https://github.com/opensass" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5ca62441414bacaa54c6c6e5b68e46c76305947b6bf498c4949fc71c1b4b10dd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61696e7461696e65642533462d7965732d677265656e2e737667" alt="Maintenance"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://discord.gg/b5JbvHW5nv" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1de0ff4ce5ecb14813fe0a4ae22bfb7ab081d2255bde28b216e2d3dc454524d9/68747470733a2f2f646362616467652e6c696d65732e70696e6b2f6170692f7365727665722f62354a62764857356e76" alt="Open SASS Discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/opensass/avatar/refs/heads/main/assets/logo.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fopensass%2Favatar%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="logo"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎬 Demo&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Live Demo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Yew&lt;/td&gt;
&lt;td&gt;&lt;a href="https://avatar-rs.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dioxus&lt;/td&gt;
&lt;td&gt;&lt;a href="https://avatar-dio.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Leptos&lt;/td&gt;
&lt;td&gt;&lt;a href="https://avatar-lep.netlify.app" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/a2765425215b2af5774668447ff125324caed6bfe2bd4fc6ee74bbbe158c8046/68747470733a2f2f6170692e6e65746c6966792e636f6d2f6170692f76312f6261646765732f62323133313332612d643862362d343934622d386135662d3732393036383261316139352f6465706c6f792d737461747573" alt="Netlify Status"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;📜 Intro&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;A highly customizable, accessible avatar component for WASM frameworks: Yew, Dioxus, and Leptos.
Supports image loading with automatic fallback content, multiple sizes, color themes, and full WCAG compliance.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 Why Avatar?&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;🎨 Fully Customizable&lt;/strong&gt;: Control every attribute, class, style, size, color, variant, ARIA labels and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🖼️ Smart Image Loading&lt;/strong&gt;: Tracks &lt;code&gt;idle → loading → loaded/error&lt;/code&gt; status with context. Fallback is shown until the image is ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⏱ Delay Support&lt;/strong&gt;: Prevent flash-of-fallback on fast connections with &lt;code&gt;delay_ms&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;♿ Accessible by Default&lt;/strong&gt;: &lt;code&gt;role="img"&lt;/code&gt;, &lt;code&gt;aria-label&lt;/code&gt;, &lt;code&gt;aria-hidden&lt;/code&gt; wired up automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;🧩 Framework Agnostic&lt;/strong&gt;: Same API semantics across Yew, Dioxus, and Leptos.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Y Yew Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/avatar/blob/main/YEW.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into your Yew app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🧬 Dioxus Usage&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/opensass/avatar/blob/main/DIOXUS.md" rel="noopener noreferrer"&gt;our guide&lt;/a&gt; to integrate this component into your Dioxus app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🌱 Leptos&lt;/h2&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/opensass/avatar" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We are Open SASS, babe!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're working tirelessly on making Rust web development extremely easy for everyone.&lt;/p&gt;

&lt;p&gt;If you made it this far, it would be nice if you could &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;join us on Discord&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>rust</category>
      <category>css</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Resurrected a Dead CRC Crate and It Suddenly Went Viral</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 20 Sep 2026 09:11:49 +0000</pubDate>
      <link>https://dev.to/wiseai/i-resurrected-a-dead-crc-crate-and-it-suddenly-went-viral-3894</link>
      <guid>https://dev.to/wiseai/i-resurrected-a-dead-crc-crate-and-it-suddenly-went-viral-3894</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Bonjour 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So there I was, browsing &lt;a href="https://crates.io" rel="noopener noreferrer"&gt;crates.io&lt;/a&gt; at an hour that most reasonable people would describe as "the middle of the night", doing what all emotionally stable developers do at that hour: auditing dead Rust crates for signs of life.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;a href="https://crates.io/crates/crc32" rel="noopener noreferrer"&gt;&lt;code&gt;crc32&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Not &lt;code&gt;crc32fast&lt;/code&gt;. Not &lt;code&gt;crc&lt;/code&gt;. Not &lt;code&gt;crc32c&lt;/code&gt;. The original. The stubby, ancient, &lt;code&gt;crc32&lt;/code&gt; crate. Last published in 2015. No changelog. No CI. A &lt;code&gt;Cargo.toml&lt;/code&gt; that predates most of the stable Rust syntax I use daily. And sitting there, abandoned and unloved.&lt;/p&gt;

&lt;p&gt;People were using this thing. Were probably &lt;em&gt;shipping&lt;/em&gt; software with it in their dependency tree. They just didn't know how to reach the crate maintainer, who had apparently retired to a cabin in the woods with no internet access sometime around when Rust 1.0 was announced.&lt;/p&gt;

&lt;p&gt;I stared at those download numbers for thirty seconds.&lt;/p&gt;

&lt;p&gt;Then I did what any emotionally stable rustacean would do: I resurrected it. From the ashes. In modern Rust. With &lt;code&gt;no_std&lt;/code&gt;. With Python bindings. With a build-time proc-macro codegen crate. With CI/CD, Debian packaging, RPM packaging, and a Ferris logo.&lt;/p&gt;

&lt;p&gt;You know. Normal stuff.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcuchucbp5f0jlwsuzmzm.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcuchucbp5f0jlwsuzmzm.jpeg" alt="shipping Ferris to production" width="717" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, What Even Is CRC-32?
&lt;/h2&gt;

&lt;p&gt;CRC-32 stands for Cyclic Redundancy Check, 32-bit variant. It's the checksum algorithm that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ZIP files&lt;/strong&gt; use to verify archive integrity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ethernet frames&lt;/strong&gt; use to detect bit errors in transmission.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FDDI, PKZIP, PNG&lt;/strong&gt; and approximately half the binary protocols ever invented also use.&lt;/li&gt;
&lt;li&gt;Every &lt;code&gt;zlib&lt;/code&gt; function you've ever called calls internally when you weren't paying attention.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, CRC-32 is &lt;em&gt;everywhere&lt;/em&gt;. It's the duct tape of data integrity. It's been computing checksums since before most of today's developers were handing in their first homework assignments.&lt;/p&gt;

&lt;p&gt;The original Rust &lt;code&gt;crc32&lt;/code&gt; crate implemented the byte-at-a-time version, the classic, the grandaddy variant. Simple. Correct. Slow as a 56k modem by 2024 standards.&lt;/p&gt;

&lt;p&gt;I didn't just port it. I rewrote the whole thing from the zlib source, added slicing-by-4, slicing-by-8, and slicing-by-16 table variants, pulled the table-generation itself into a build-time proc-macro subcrate, added a streaming &lt;code&gt;Digest&lt;/code&gt;, a GF(2) matrix &lt;code&gt;combine&lt;/code&gt; function, and shipped the whole thing as a &lt;code&gt;no_std&lt;/code&gt; library with Python and Node.js bindings.&lt;/p&gt;

&lt;p&gt;All in 100% safe Rust. With &lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; at the crate root.&lt;/p&gt;

&lt;p&gt;Because anything worth resurrecting is worth resurrecting &lt;em&gt;properly&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;Let me tell you what the original &lt;code&gt;crc32&lt;/code&gt; crate looked like. It was, essentially:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/lib.rs
src/crc32gen.rs
src/crc32gen_file.rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's it. 3 files. A lookup table, a loop, a bitwise XOR. Beautiful in its simplicity, like a stone hut in a field. Functional. Zero frills. Absolutely not capable of 1 GiB/s throughput.&lt;/p&gt;

&lt;p&gt;Here's what &lt;code&gt;crc32-v2&lt;/code&gt; looks like today:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;crc32-v2/
├── crc32-codegen/             ← proc-macro subcrate: generates all 17 CRC tables at build time
│   └── src/lib.rs             ← build.rs calls crc32_codegen::run() → writes to $OUT_DIR
├── src/
│   ├── lib.rs                 ← minimal entry point: #![no_std], module declarations, Python FFI
│   ├── tables.rs              ← crc32() byte-at-a-time baseline
│   ├── byfour.rs              ← crc32_little / _8 / _16 / crc32_big
│   ├── combine.rs             ← crc32_combine() via GF(2) matrix squaring in O(log n)
│   ├── digest.rs              ← streaming Digest with update() / finalize() / digest()
│   └── python.rs              ← PyO3 bindings (gated on feature = "python" + "std")
├── tests/
│   └── byfour.rs              ← 40 Rust integration tests
└── python/
    └── crc32_rs/
        └── __init__.py        ← re-exports all symbols from the compiled .so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The stone hut has been converted into a, uh, &lt;em&gt;well-appointed facility&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy8enypsfoj2eywwf3hry.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy8enypsfoj2eywwf3hry.webp" alt="Before and after the refactor" width="640" height="640"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Magic Trick
&lt;/h2&gt;

&lt;p&gt;This is my personal favourite part of the whole project. And possibly the most unhinged.&lt;/p&gt;

&lt;p&gt;CRC-32 slicing-by-16 requires 17 lookup tables: one 256-entry big-endian table, and 16 256-entry little-endian tables at different offsets. That's 17 × 256 × 4 = 17,408 bytes of lookup table data that needs to exist at runtime.&lt;/p&gt;

&lt;p&gt;The naive way: write the tables by hand and commit 17,000 bytes of constants to git as a &lt;code&gt;.rs&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;The normal way: generate them at startup and cache them in a &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The way I did it: proc-macro subcrate (&lt;code&gt;crc32-codegen&lt;/code&gt;) that is invoked from &lt;code&gt;build.rs&lt;/code&gt; at compile time, generates all 17 tables using the CRC-32 polynomial arithmetic, writes them to &lt;code&gt;$OUT_DIR/crc_tables.rs&lt;/code&gt;, and the main crate &lt;code&gt;include!&lt;/code&gt;s the output. Zero runtime initialization. Zero startup cost. The tables are baked into the binary at link time.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build-dependencies]&lt;/span&gt;
&lt;span class="py"&gt;crc32-codegen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"crc32-codegen"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nn"&gt;crc32_codegen&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;run&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;That's the entire &lt;code&gt;build.rs&lt;/code&gt;. One function call. The codegen crate does all the polynomial math, formats the Rust source, and writes it to disk. The main crate wakes up with all 17 tables pre-computed, pre-verified, and pre-formatted.&lt;/p&gt;

&lt;p&gt;This is the kind of thing that inspires either awe or a mildly concerned Slack message from your coworkers. There is no middle ground.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15bfp2ywzsqzcge02ekx.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15bfp2ywzsqzcge02ekx.jpeg" alt="Ferris generating a lookup table" width="500" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The 4 Speeds of CRC-32
&lt;/h2&gt;

&lt;p&gt;Let me paint you a picture of what "slicing-by-N" actually means, because it's one of those ideas that sounds arcane until you see the numbers and then you can't stop thinking about it.&lt;/p&gt;

&lt;p&gt;The classic CRC-32 loop looks like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;buf&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;crc&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="nn"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;0xff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;crc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CRC_TABLE&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="n"&gt;index&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;usize&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="n"&gt;crc&lt;/span&gt; &lt;span class="o"&gt;&amp;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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One byte per iteration. One table lookup. On a 1 MiB payload that's 1,048,576 iterations. At ~2 ns per iteration (fast CPU, warm cache), that's ~2ms. Not terrible. Not great.&lt;/p&gt;

&lt;p&gt;Slicing-by-4 says: what if we process &lt;em&gt;four&lt;/em&gt; bytes per iteration instead? You pre-compute four separate 256-entry tables (one for each byte offset), and in each step you XOR together four table lookups instead of one. Four bytes per iteration, four table lookups, but modern CPUs can do all four lookups in parallel because there are no data dependencies between them. Result: roughly 2.4× faster.&lt;/p&gt;

&lt;p&gt;Slicing-by-8 does the same with eight tables. Slicing-by-16 pushes it to sixteen tables and sixteen bytes per step, letting the CPU's out-of-order execution and instruction-level parallelism do the heavy lifting. With &lt;code&gt;#[inline(always)]&lt;/code&gt; on the inner fold functions, fat LTO, and &lt;code&gt;overflow-checks = false&lt;/code&gt; in the bench profile, LLVM sees through all the abstraction and generates machine code that is, frankly, embarrassingly fast for code written entirely in safe Rust.&lt;/p&gt;

&lt;p&gt;The full breakdown:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;1 B&lt;/th&gt;
&lt;th&gt;64 B&lt;/th&gt;
&lt;th&gt;1 KiB&lt;/th&gt;
&lt;th&gt;64 KiB&lt;/th&gt;
&lt;th&gt;1 MiB&lt;/th&gt;
&lt;th&gt;Throughput&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;crc32&lt;/code&gt; (byte-at-a-time)&lt;/td&gt;
&lt;td&gt;2 ns&lt;/td&gt;
&lt;td&gt;167 ns&lt;/td&gt;
&lt;td&gt;2,856 ns&lt;/td&gt;
&lt;td&gt;188,134 ns&lt;/td&gt;
&lt;td&gt;2,916,562 ns&lt;/td&gt;
&lt;td&gt;~343 MiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;crc32_little&lt;/code&gt; (slicing-by-4)&lt;/td&gt;
&lt;td&gt;3 ns&lt;/td&gt;
&lt;td&gt;73 ns&lt;/td&gt;
&lt;td&gt;1,086 ns&lt;/td&gt;
&lt;td&gt;82,129 ns&lt;/td&gt;
&lt;td&gt;1,199,953 ns&lt;/td&gt;
&lt;td&gt;~833 MiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;crc32_little_8&lt;/code&gt; (slicing-by-8)&lt;/td&gt;
&lt;td&gt;3 ns&lt;/td&gt;
&lt;td&gt;61 ns&lt;/td&gt;
&lt;td&gt;922 ns&lt;/td&gt;
&lt;td&gt;56,486 ns&lt;/td&gt;
&lt;td&gt;1,004,746 ns&lt;/td&gt;
&lt;td&gt;~1,004 MiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32_little_16&lt;/code&gt; (slicing-by-16)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;3 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;39 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;753 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;48,101 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;781,535 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~1,282 MiB/s&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;crc32fast&lt;/code&gt; (SIMD via &lt;code&gt;pclmulqdq&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;11 ns&lt;/td&gt;
&lt;td&gt;20 ns&lt;/td&gt;
&lt;td&gt;102 ns&lt;/td&gt;
&lt;td&gt;5,802 ns&lt;/td&gt;
&lt;td&gt;89,204 ns&lt;/td&gt;
&lt;td&gt;~11,300 MiB/s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;crc32_little_16&lt;/code&gt; hits &lt;strong&gt;~1,282 MiB/s&lt;/strong&gt; on a 1 MiB payload. That's &lt;strong&gt;3.7× faster than the baseline&lt;/strong&gt;, without a single SIMD intrinsic, without a single &lt;code&gt;unsafe&lt;/code&gt; block, and without any CPU feature detection. It Just Works on x86-64, ARM, RISC-V, WASM, and whatever exotic architecture you're running this week.&lt;/p&gt;

&lt;p&gt;Note that tiny 1-byte payloads still favour the baseline &lt;code&gt;crc32&lt;/code&gt; (2 ns vs 3 ns) because the slicing variants pay a small alignment prologue overhead. We document this honestly, unlike some people's README files.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdp631ld7sgjrs9h0lsmy.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdp631ld7sgjrs9h0lsmy.jpeg" alt="Surprised Ferris" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Cross-Library Reality Check
&lt;/h2&gt;

&lt;p&gt;Look. I know what you're thinking. &lt;em&gt;"But crc32fast uses SIMD and does 11 GiB/s. Doesn't that make this pointless?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No. Here's why.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;crc32fast&lt;/code&gt; is genuinely excellent for x86-64 with &lt;code&gt;pclmulqdq&lt;/code&gt;. But &lt;code&gt;crc32-v2&lt;/code&gt; occupies a different niche:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Time (1 MiB)&lt;/th&gt;
&lt;th&gt;Throughput&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;crc32fast&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;hash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;89,204 ns&lt;/td&gt;
&lt;td&gt;~11,300 MiB/s&lt;/td&gt;
&lt;td&gt;SIMD (&lt;code&gt;pclmulqdq&lt;/code&gt;) / Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zlib-rs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;crc32&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;96,968 ns&lt;/td&gt;
&lt;td&gt;~10,390 MiB/s&lt;/td&gt;
&lt;td&gt;SIMD / Rust&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python (&lt;code&gt;zlib.crc32&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;C extension&lt;/td&gt;
&lt;td&gt;355,270 ns&lt;/td&gt;
&lt;td&gt;~2,815 MiB/s&lt;/td&gt;
&lt;td&gt;SIMD / C&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32-v2&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;crc32_little_16&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;781,535 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~1,282 MiB/s&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Pure safe Rust&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Python (&lt;code&gt;crcmod&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;C extension&lt;/td&gt;
&lt;td&gt;2,865,836 ns&lt;/td&gt;
&lt;td&gt;~349 MiB/s&lt;/td&gt;
&lt;td&gt;Non-SIMD / C&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;crc32fast&lt;/code&gt;: amazing. &lt;code&gt;zlib-rs&lt;/code&gt;: also amazing. Both use runtime SIMD dispatch and &lt;code&gt;unsafe&lt;/code&gt;. Both don't compile to WASM without special handling. Both don't work in &lt;code&gt;no_std&lt;/code&gt; environments without a careful dance.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;crc32-v2&lt;/code&gt; compiles everywhere Rust compiles. Embedded RISC-V? Yes. &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt;? Yes. A microcontroller that needs to verify a firmware checksum before flashing? Yes. A kernel module? With &lt;code&gt;#![no_std]&lt;/code&gt; and a custom allocator? &lt;em&gt;Also&lt;/em&gt; yes.&lt;/p&gt;

&lt;p&gt;When you need 11 GiB/s you use &lt;code&gt;crc32fast&lt;/code&gt;. When you need something that works anywhere, has zero dependencies outside &lt;code&gt;alloc&lt;/code&gt;, and is produced by a compiler that will literally refuse to let you write unsafe code: you use &lt;code&gt;crc32-v2&lt;/code&gt;. There are more situations in the second category than you'd expect.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxwha4p4ia0681mhrdvpw.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxwha4p4ia0681mhrdvpw.jpeg" alt="use crc32-v2 davai davai" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Python Bindings
&lt;/h2&gt;

&lt;p&gt;Here's a section I am writing in the spirit of radical honesty. Shipping Python bindings for a Rust library requires configuring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;maturin&lt;/code&gt; (the build tool)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pyo3&lt;/code&gt; (the FFI framework)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pyproject.toml&lt;/code&gt; (the Python packaging config)&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;python/crc32_rs/__init__.py&lt;/code&gt; that re-exports from the compiled &lt;code&gt;.so&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;module-name&lt;/code&gt; field in &lt;code&gt;pyproject.toml&lt;/code&gt; matching the &lt;code&gt;#[pymodule]&lt;/code&gt; name in Rust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any one of these four things is even slightly wrong, Python greets you with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nb"&gt;ModuleNotFoundError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="n"&gt;named&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;crc32_rs&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Not a helpful error. Not &lt;code&gt;"the module-name in pyproject.toml doesn't match the pymodule attribute"&lt;/code&gt;. Just: it doesn't exist. Good luck.&lt;/p&gt;

&lt;p&gt;I went through approximately four rounds of this before getting it right. The root cause was a mismatch between &lt;code&gt;module-name = "crc32_v2._crc32_v2"&lt;/code&gt; (incorrect) and &lt;code&gt;module-name = "crc32_rs._crc32_v2"&lt;/code&gt; (correct). One underscore in the wrong namespace and Python acts as if the entire compiled extension simply does not exist in this universe.&lt;/p&gt;

&lt;p&gt;The fix took three characters. The investigation took forty-five minutes.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crc32_rs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_little_16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_hex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Digest&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="mh"&gt;0xebe6c6e6&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32_little_16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="mh"&gt;0xebe6c6e6&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32_bytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="n"&gt;ebe6c6e6&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32_hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;ebe6c6e6&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; 
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&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="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&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="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;world!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finalize&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="mh"&gt;0xebe6c6e6&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;repr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nc"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;crc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mh"&gt;0xEBE6C6E6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now it works. The Python interpreter is stuffed. We do not speak of the forty-five minutes.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyvp98fw6ep6mnhfcb1nb.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyvp98fw6ep6mnhfcb1nb.jpeg" alt="same same" width="500" height="559"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Rust for Python Developers
&lt;/h2&gt;

&lt;p&gt;Let's talk about something that the throughput benchmarks don't fully capture: what happens to performance when you're computing CRC-32 on &lt;em&gt;tiny&lt;/em&gt; payloads? Like, really tiny. 1 byte tiny.&lt;/p&gt;

&lt;p&gt;The issue with Python's &lt;a href="https://docs.python.org/3/library/zlib.html#zlib.crc32" rel="noopener noreferrer"&gt;&lt;code&gt;zlib.crc32&lt;/code&gt;&lt;/a&gt; is not that it's slow for large inputs, it delegates to SIMD C code under the hood and handles 1 MiB payloads at 2,815 MiB/s, which is genuinely fast. The issue is that every Python function call carries ~200-300 ns of interpreter overhead before you've even touched a byte of data.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Payload&lt;/th&gt;
&lt;th&gt;Python &lt;code&gt;zlib.crc32&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Rust &lt;code&gt;crc32-v2&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Speedup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1 B&lt;/td&gt;
&lt;td&gt;~297 ns&lt;/td&gt;
&lt;td&gt;~2 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~148×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;64 B&lt;/td&gt;
&lt;td&gt;~301 ns&lt;/td&gt;
&lt;td&gt;~39 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~7.7×&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;148 times faster on a single byte. If you're checksumming thousands of small messages per second, network packets, log entries, sensor readings, the Python interpreter overhead alone is eating your entire latency budget before you even get to the CRC computation.&lt;/p&gt;

&lt;p&gt;Moving the loop into Rust and calling Python once at the end is not premature optimisation. It is the correct architectural decision. &lt;code&gt;crc32-v2&lt;/code&gt; makes that decision easier to implement.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;no_std&lt;/code&gt;: Ferris Goes Embedded
&lt;/h2&gt;

&lt;p&gt;This was the part I underestimated most. Adding &lt;code&gt;no_std&lt;/code&gt; support sounds simple: slap &lt;code&gt;#![cfg_attr(not(feature = "std"), no_std)]&lt;/code&gt; on the library, add &lt;code&gt;extern crate alloc&lt;/code&gt;, and done.&lt;/p&gt;

&lt;p&gt;And then you build the &lt;code&gt;cdylib&lt;/code&gt; target without &lt;code&gt;std&lt;/code&gt; features and discover that a dynamic library needs a panic handler and a global allocator, because without &lt;code&gt;std&lt;/code&gt;, the linker has no idea what to do when you panic, and with no allocator it has equally no idea what to do when something tries to allocate.&lt;/p&gt;

&lt;p&gt;The fix requires a dummy allocator implemention that satisfies the &lt;code&gt;GlobalAlloc&lt;/code&gt; trait contract just enough to let the linker stop complaining:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# Features that gate the standard library&lt;/span&gt;
&lt;span class="nn"&gt;[features]&lt;/span&gt;
&lt;span class="py"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;std&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="py"&gt;python&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"pyo3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="c"&gt;# Python bindings require std&lt;/span&gt;
&lt;span class="py"&gt;node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"napi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"napi-derive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"napi-build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c"&gt;# Node.js too&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#![cfg_attr(not(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="nd"&gt;),&lt;/span&gt; &lt;span class="nd"&gt;no_std)]&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt; &lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And &lt;code&gt;panic = "abort"&lt;/code&gt; in &lt;code&gt;[profile.dev]&lt;/code&gt; so that the &lt;code&gt;no_std&lt;/code&gt; cdylib doesn't try to set up unwinding infrastructure that doesn't exist.&lt;/p&gt;

&lt;p&gt;Result: &lt;code&gt;cargo build --no-default-features&lt;/code&gt; completes successfully. Ferris is now embeddable. The microcontroller community rejoices.&lt;/p&gt;
&lt;h2&gt;
  
  
  Safety
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; is enforced at the crate root. This is a compiler directive that physically prevents any &lt;code&gt;unsafe&lt;/code&gt; block from being compiled into the library.&lt;/p&gt;

&lt;p&gt;The borrow checker, like a very particular building inspector, will reject your PR on first principles if you try to introduce &lt;code&gt;unsafe&lt;/code&gt; into the slicing loops, the GF(2) matrix arithmetic, the streaming &lt;code&gt;Digest&lt;/code&gt;, or the codegen subcrate. You can argue with it. You can find workarounds. The borrow checker does not care. It has seen your workarounds and it finds them unconvincing.&lt;/p&gt;

&lt;p&gt;The only &lt;code&gt;unsafe&lt;/code&gt; surface is the Python FFI layer's dummy allocator stub needed for bare-metal builds, and this is isolated, cfg-gated, and documented. The rest of the crate is provably safe at compile time.&lt;/p&gt;

&lt;p&gt;This means you can use &lt;code&gt;crc32-v2&lt;/code&gt; in environments where one &lt;code&gt;unsafe&lt;/code&gt; bug could corrupt a firmware image, crash a file server, or cause a network device to accept invalid data. The compiler provides the guarantee. Not the tests. Not the code review. The &lt;em&gt;compiler&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Rust
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;crc32-v2&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2.0"&lt;/span&gt;

&lt;span class="c"&gt;# For embedded / no_std:&lt;/span&gt;
&lt;span class="c"&gt;# crc32-v2 = { version = "0.2.0", default-features = false }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;crc32_v2&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_combine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;byfour&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;crc32_little_16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// One-shot&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32&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="s"&gt;b"123456789"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0xCBF43926&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Fastest pure-software path (~1,282 MiB/s)&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32_little_16&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="s"&gt;b"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0xEBE6_C6E6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Streaming&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Digest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"Hello, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="nf"&gt;.update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;b"world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="nf"&gt;.finalize&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;0xEBE6_C6E6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Combine two independently-computed CRCs (O(log n) via GF(2) matrix squaring)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;c1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crc32&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="s"&gt;b"Hello, "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;c2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;crc32&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="s"&gt;b"world!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32_combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c2&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="nf"&gt;crc32&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="s"&gt;b"Hello, world!"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;crc32-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crc32_rs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_little_16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crc32_hex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Digest&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;123456789&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xcbf43926&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# The correct CRC-32 of "rust_magic" is:
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rust_magic&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="mh"&gt;0xa3067d13&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;crc32-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;crc32Little16&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;crc32-rs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;crc32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello, world!&lt;/span&gt;&lt;span class="dl"&gt;"&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="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// ebe6c6e6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

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

&lt;p&gt;The crate is at &lt;code&gt;0.2.0&lt;/code&gt; and functionally complete for its initial scope. The roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Slicing-by-32&lt;/strong&gt;: Because if 16 tables give us 3.7× speedup, we're obligated to find out where the speedup curve flattens.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;serde&lt;/code&gt; support&lt;/strong&gt;: Serialize and deserialize &lt;code&gt;Digest&lt;/code&gt; state for resumable streaming checksums.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WASM target&lt;/strong&gt;: The &lt;code&gt;no_std&lt;/code&gt; foundation is already there. The WASM build should be trivial in theory. "In theory" is doing a lot of work in that sentence and I am prepared for it to do slightly less work once I try it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;crc32-v2&lt;/code&gt; started as a resurrection project. Someone wrote &lt;code&gt;crc32&lt;/code&gt; in 2015, abandoned it, and 9,062 people quietly became dependent on it through their transitive dependency graphs without knowing they were relying on a crate that predated Rust 1.0.&lt;/p&gt;

&lt;p&gt;It ended up as something that resurrected the algorithm &lt;em&gt;and&lt;/em&gt; pushed it forward: slicing-by-16 giving 3.7× throughput improvement, build-time table codegen via proc-macro, &lt;code&gt;no_std&lt;/code&gt; compatibility, Python and Node.js bindings, and Ferris the Crab holding a magic wand computing &lt;code&gt;0xa3067d13&lt;/code&gt; in your terminal.&lt;/p&gt;

&lt;p&gt;The original &lt;code&gt;crc32&lt;/code&gt; crate was doing its best with 2015-era Rust. We can do more. We should do more. The 9,062 people who downloaded it deserve more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cargo add crc32-v2&lt;/code&gt; → compute checksums → sleep well knowing Ferris has you covered 🦀⚡&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Star &lt;a href="https://github.com/wiseaidev/crc32-v2" rel="noopener noreferrer"&gt;the repo&lt;/a&gt;, try the &lt;a href="https://pypi.org/project/crc32-rs" rel="noopener noreferrer"&gt;Python bindings&lt;/a&gt;, install the &lt;a href="https://www.npmjs.com/package/crc32-rs" rel="noopener noreferrer"&gt;npm package&lt;/a&gt;, or read the &lt;a href="https://docs.rs/crc32-v2" rel="noopener noreferrer"&gt;docs&lt;/a&gt; if you still have questions.&lt;/p&gt;

&lt;p&gt;This has been a public service announcement from someone who looked at a dead Rust crate with 9,062 downloads and thought: &lt;em&gt;"Someone should fix this."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That someone was me. And honestly? It was a great use of my 2AM.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2o84fzwlmkt3mn078p00.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2o84fzwlmkt3mn078p00.jpg" alt="same same" width="500" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Till next time: &lt;em&gt;Keep the bytes honest. Keep the checksums rolling.&lt;/em&gt; 🦀🔄&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/wiseaidev" rel="noopener noreferrer"&gt;
        wiseaidev
      &lt;/a&gt; / &lt;a href="https://github.com/wiseaidev/crc32-v2" rel="noopener noreferrer"&gt;
        crc32-v2
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      The fastest port of the CRC-32 algorithm in Rust.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;⚡ CRC32-V2&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/wiseaidev/crc32-v2" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Fcrc32-v2%2Frefs%2Fheads%2Fmain%2Fassets%2Fnew-logo.png" alt="CRC32-V2 Logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/crc32-v2" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/52342ac216459f90eb3be6e9e10d401741e541adfccb939b0f0ac208d1b9de14/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f63726333322d76322e737667" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://docs.rs/crc32-v2" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/aea0ecbacc9e0a7050f8e74a214d87a9aa5bd519b76784d83dd2a1a7895534e5/68747470733a2f2f646f63732e72732f63726333322d76322f62616467652e737667" alt="Docs.rs"&gt;&lt;/a&gt;
&lt;a href="https://github.com/wiseaidev/crc32-v2/actions/workflows/rust.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/wiseaidev/crc32-v2/actions/workflows/rust.yml/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/crc32-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/af42efaea46f4c5b80f0e2ae4dbf92e748e0b9d1b8637bf4e244722d80b0335f/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f63726333322d72732e737667" alt="PyPI"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/crc32-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dd96357a508460c49f9e174e187646127a541ca57744e1dafa95615902ddf2ab/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f63726333322d72732e737667" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://github.com/wiseaidev/crc32-v2/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The fastest pure-software, &lt;code&gt;no_std&lt;/code&gt;-compatible CRC-32 implementation in Rust, slicing-by-16 tables, zero heap allocation in the hot path, and native Python / Node.js bindings, all written in &lt;strong&gt;100% safe Rust&lt;/strong&gt; 🗿.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/wiseaidev/crc32-v2" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Fcrc32-v2%2Frefs%2Fheads%2Fmain%2Fassets%2Fbanner.png" alt="Banger Banner"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Command / Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo add crc32-v2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust (no_std)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo add crc32-v2 --no-default-features&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pip install crc32-rs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install crc32-rs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Debian / Ubuntu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://github.com/wiseaidev/crc32-v2/releases" rel="noopener noreferrer"&gt;&lt;code&gt;gh release download&lt;/code&gt;&lt;/a&gt;, see &lt;a href="https://github.com/wiseaidev/crc32-v2/PACKAGING.md" rel="noopener noreferrer"&gt;PACKAGING.md&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RHEL / Fedora&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;a href="https://github.com/wiseaidev/crc32-v2/releases" rel="noopener noreferrer"&gt;&lt;code&gt;gh release download&lt;/code&gt;&lt;/a&gt;, see &lt;a href="https://github.com/wiseaidev/crc32-v2/PACKAGING.md" rel="noopener noreferrer"&gt;PACKAGING.md&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🔭 Features&lt;/h2&gt;
&lt;/div&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;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;no_std&lt;/code&gt; + &lt;code&gt;alloc&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Embeddable in bare-metal, WASM, and embedded targets, no standard library required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;100% safe Rust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; enforced crate-wide; zero &lt;code&gt;unsafe&lt;/code&gt; blocks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Byte-at-a-time baseline (~343 MiB/s); compatible with zlib, PKZIP, Ethernet, and FDDI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32_little&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slicing-by-4 (~833 MiB/s); &lt;strong&gt;2.4×&lt;/strong&gt; faster than byte-at-a-time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32_little_8&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slicing-by-8 (~1,004 MiB/s); &lt;strong&gt;2.9×&lt;/strong&gt; faster than byte-at-a-time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32_little_16&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Slicing-by-16 (&lt;strong&gt;~1,282 MiB/s&lt;/strong&gt;); &lt;strong&gt;3.7×&lt;/strong&gt; fastest pure-software path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32_big&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Big-endian (unreflected) variant for hardware CRC controllers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;crc32_combine&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Merge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/wiseaidev/crc32-v2" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;P.S. The original &lt;code&gt;crc32&lt;/code&gt; crate maintainer is apparently a Microsoft employee. So, if you happen to work at Microsoft and are currently hiring Rust developers who spend their 2AM evenings resurrecting ancient dependencies to slice them by 16, please hit me up. We can bond over polynomial arithmetic. Thanks for the help &amp;lt;3!&lt;/p&gt;

</description>
      <category>rust</category>
      <category>python</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Frozendict 🧊: State of the Art Immutable Hashmap for Python and Node JS.</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sat, 19 Sep 2026 04:25:17 +0000</pubDate>
      <link>https://dev.to/wiseai/frozendict-state-of-the-art-immutable-hashmap-for-python-and-node-js-284o</link>
      <guid>https://dev.to/wiseai/frozendict-state-of-the-art-immutable-hashmap-for-python-and-node-js-284o</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hello 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So there I was, staring at &lt;a href="https://docs.python.org/3/builtins/stdtypes.html#set-types-set-frozenset" rel="noopener noreferrer"&gt;Python's &lt;code&gt;frozenset&lt;/code&gt;&lt;/a&gt;, feeling that specific special rage that only a data structure enthusiast at 1AM can feel, while &lt;code&gt;dict&lt;/code&gt; sat there, utterly mutable, fully hashable, completely disobedient.&lt;/p&gt;

&lt;p&gt;Dictionary keys can change. You can &lt;code&gt;pop&lt;/code&gt; from it. You can &lt;code&gt;clear&lt;/code&gt; it. You can &lt;code&gt;update&lt;/code&gt; it mid-computation and break 30 tests simultaneously.&lt;/p&gt;

&lt;p&gt;I looked at this situation calmly. And then I did what any reasonable person would do: I wrote &lt;code&gt;frozndict&lt;/code&gt;, a fully immutable, insertion-ordered, O(1)-hashable dictionary in &lt;strong&gt;100% safe Rust&lt;/strong&gt; with Python and Node.js bindings so fast they make &lt;code&gt;frozendict&lt;/code&gt; (the C extension) look briefly embarrassed at its own party.&lt;/p&gt;

&lt;p&gt;The result? &lt;a href="https://github.com/wiseaidev/frozndict" rel="noopener noreferrer"&gt;&lt;code&gt;frozndict&lt;/code&gt;&lt;/a&gt;: the state of the art immutable hashmap. Frozen at construction. Hashable by design. Faster than guilt.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvweo6okcijijdwox5p63.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvweo6okcijijdwox5p63.jpeg" alt="Make Python dict immutable!" width="700" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Should You Care?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.python.org/3/tutorial/datastructures.html#dictionaries" rel="noopener noreferrer"&gt;Python's &lt;code&gt;dict&lt;/code&gt;&lt;/a&gt; is a magnificent beast. It's ordered, fast, flexible. It is also a ticking time bomb if you try to use one as a cache key, a &lt;a href="https://docs.python.org/3/library/functools.html" rel="noopener noreferrer"&gt;&lt;code&gt;functools.lru_cache&lt;/code&gt;&lt;/a&gt; argument, or anywhere that requires hashability.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;  &lt;span class="c1"&gt;# TypeError: unhashable type: 'dict'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;a href="https://docs.python.org/3/builtins/stdtypes.html#set-types-set-frozenset" rel="noopener noreferrer"&gt;stdlib's &lt;code&gt;frozenset&lt;/code&gt;&lt;/a&gt; solved this for sets. Nobody solved it properly for dicts for 15+ years, until &lt;a href="https://github.com/Marco-Sulla/python-frozendict" rel="noopener noreferrer"&gt;&lt;code&gt;frozendict&lt;/code&gt; (the C extension)&lt;/a&gt; came along. And then I looked at &lt;code&gt;frozendict&lt;/code&gt;'s construction time and made a concerned face.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;frozndict&lt;/code&gt; solves all of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Truly immutable&lt;/strong&gt;: mutation attempts at the Rust level raise &lt;code&gt;TypeError&lt;/code&gt;. Not &lt;code&gt;AttributeError&lt;/code&gt;. No monkey-patching. &lt;code&gt;__setitem__&lt;/code&gt;, &lt;code&gt;__delitem__&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, &lt;code&gt;clear&lt;/code&gt;, &lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;popitem&lt;/code&gt;, and &lt;code&gt;setdefault&lt;/code&gt; are all implemented, as gates that will refuse you entry and then log the attempt somewhere in the moral universe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O(1) &lt;code&gt;__hash__&lt;/code&gt;&lt;/strong&gt;: computed once at construction. Subsequent calls return a cached &lt;code&gt;isize&lt;/code&gt;. No recomputation. Ever.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;O(1) &lt;code&gt;copy()&lt;/code&gt;&lt;/strong&gt;: returns the same &lt;code&gt;Arc&amp;lt;FrozenDictInner&amp;gt;&lt;/code&gt;. One pointer copy. 63 ns. Done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insertion-ordered&lt;/strong&gt;: all views, &lt;code&gt;keys()&lt;/code&gt;, &lt;code&gt;values()&lt;/code&gt;, &lt;code&gt;items()&lt;/code&gt;, iterate in the order you inserted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;fromkeys&lt;/code&gt; support&lt;/strong&gt;: &lt;code&gt;FrozenDict.fromkeys(["a", "b"], 0)&lt;/code&gt; works exactly as you'd expect, including on subclasses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set algebra on views&lt;/strong&gt;: &lt;code&gt;fd.keys() &amp;amp; other_keys&lt;/code&gt;, &lt;code&gt;fd.items() - other_items&lt;/code&gt;, &lt;code&gt;^&lt;/code&gt;, &lt;code&gt;|&lt;/code&gt;, &lt;code&gt;isdisjoint&lt;/code&gt;, all there.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpbjvxx32ai75mcquxyk7.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpbjvxx32ai75mcquxyk7.jpeg" alt="Change My Mind!" width="578" height="433"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Architecture
&lt;/h2&gt;

&lt;p&gt;Here is the internal layout:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FrozenDict
  └── Arc&amp;lt;FrozenDictInner&amp;gt;          ← shared ownership, O(1) clone
        ├── entries: Box&amp;lt;[(isize, Obj, Obj)]&amp;gt;   ← insertion-ordered (key_hash, key, val)
        ├── lookup: Box&amp;lt;[(isize, u32)]&amp;gt;          ← sorted by hash for binary search
        ├── hash: isize                          ← pre-computed at build time
        ├── cached_keys: OnceLock&amp;lt;Py&amp;lt;PyList&amp;gt;&amp;gt;    ← lazy, shared across views
        ├── cached_values: OnceLock&amp;lt;Py&amp;lt;PyList&amp;gt;&amp;gt;
        └── cached_items: OnceLock&amp;lt;Py&amp;lt;PyList&amp;gt;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The key insight: &lt;strong&gt;entries stay in insertion order&lt;/strong&gt;. The &lt;strong&gt;lookup table&lt;/strong&gt; is a separate, sorted slice used only for binary search. This gives us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;O(n) insertion-ordered iteration (just walk &lt;code&gt;entries&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;O(log n + k) lookup (binary search to the hash bucket, then linear scan for collision k)&lt;/li&gt;
&lt;li&gt;O(n log n) construction (one sort of the lookup table, then done)&lt;/li&gt;
&lt;li&gt;O(1) &lt;code&gt;copy()&lt;/code&gt; and &lt;code&gt;clone()&lt;/code&gt; (pointer copy of the &lt;code&gt;Arc&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hash is computed by XOR-mixing each &lt;code&gt;key_hash * MIX_KEY ^ value_hash * MIX_VAL&lt;/code&gt;. Order-independent. Two frozen dicts with the same contents but different insertion order are equal and share a hash. As nature intended.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjtq8b2995kouc68ai1r.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdjtq8b2995kouc68ai1r.jpeg" alt="Ferris the crab holding a sorted lookup slice" width="557" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Performance Numbers
&lt;/h2&gt;

&lt;p&gt;These are real numbers. Benchmarked with &lt;code&gt;timeit&lt;/code&gt; on Python 3.12.3, x86-64 Linux, min of 7 runs × 2,000 iterations, N=1000 entries.&lt;/p&gt;
&lt;h3&gt;
  
  
  Python-level benchmark
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Python dict&lt;/th&gt;
&lt;th&gt;frozendict (C)&lt;/th&gt;
&lt;th&gt;immutables.Map&lt;/th&gt;
&lt;th&gt;frozndict 🧊&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Construction&lt;/td&gt;
&lt;td&gt;6.45 µs&lt;/td&gt;
&lt;td&gt;7.70 µs&lt;/td&gt;
&lt;td&gt;241.67 µs&lt;/td&gt;
&lt;td&gt;90.70 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clone O(1)&lt;/td&gt;
&lt;td&gt;6.45 µs&lt;/td&gt;
&lt;td&gt;70.48 ns&lt;/td&gt;
&lt;td&gt;404.62 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;138.68 ns&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Equality&lt;/td&gt;
&lt;td&gt;19.37 µs&lt;/td&gt;
&lt;td&gt;19.44 µs&lt;/td&gt;
&lt;td&gt;24.39 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;32.42 ns&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iteration&lt;/td&gt;
&lt;td&gt;7.39 µs&lt;/td&gt;
&lt;td&gt;7.42 µs&lt;/td&gt;
&lt;td&gt;14.97 µs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4.14 µs&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;copy()&lt;/td&gt;
&lt;td&gt;6.53 µs&lt;/td&gt;
&lt;td&gt;323.83 ns&lt;/td&gt;
&lt;td&gt;317.07 µs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63.29 ns&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;hash()&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;168.19 ns&lt;/td&gt;
&lt;td&gt;45.07 ns&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;45.52 ns&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lookup&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;32.52 ns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;48.31 ns&lt;/td&gt;
&lt;td&gt;48.11 ns&lt;/td&gt;
&lt;td&gt;82.62 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;frozndict&lt;/code&gt; wins iteration, &lt;code&gt;copy()&lt;/code&gt;, equality, clone, and very nearly ties &lt;code&gt;immutables.Map&lt;/code&gt; on &lt;code&gt;hash()&lt;/code&gt;. On a per-call basis, the pure Rust functions run in &lt;strong&gt;nanoseconds&lt;/strong&gt;, which is approximately &lt;strong&gt;1,000,000x faster&lt;/strong&gt; than any Python-level re-implementation of the same logic would be. This is what happens when you move computation to Rust and let LLVM take it from there.&lt;/p&gt;
&lt;h3&gt;
  
  
  Rust-level benchmark
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Workload&lt;/th&gt;
&lt;th&gt;Time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Construction, n=100&lt;/td&gt;
&lt;td&gt;~2.7 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Construction, n=1000&lt;/td&gt;
&lt;td&gt;~35 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lookup hit&lt;/td&gt;
&lt;td&gt;~41 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lookup miss&lt;/td&gt;
&lt;td&gt;~39 ns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iteration, n=1000&lt;/td&gt;
&lt;td&gt;~3.1 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hash()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~4.8 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;with()&lt;/code&gt; (functional update)&lt;/td&gt;
&lt;td&gt;~31 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;merge()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~35 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The lookup path is 40 nanoseconds. For comparison, a Python function call overhead alone is about 60-100 ns. &lt;code&gt;frozndict&lt;/code&gt; answers your lookup query faster than Python could even begin thinking about it.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm3hfmd6nhgisssfpyn9t.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm3hfmd6nhgisssfpyn9t.jpeg" alt="Ferris Chilling" width="680" height="438"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Equality Problem
&lt;/h2&gt;

&lt;p&gt;Here is a question for you: are these two &lt;code&gt;FrozenDict&lt;/code&gt;s equal?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&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="c1"&gt;# different insertion order
&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;  &lt;span class="c1"&gt;# ?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Yes. Obviously yes. They have the same key-value pairs. The answer is &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The naive implementation, comparing entries positionally, index by index, returns &lt;code&gt;False&lt;/code&gt; because the entries are stored in insertion order. Early &lt;code&gt;frozndict&lt;/code&gt; versions had exactly this bug. I discovered it while writing the tests at midnight and sat in silence for a moment before going to fix it.&lt;/p&gt;

&lt;p&gt;The correct implementation uses the &lt;strong&gt;sorted lookup table&lt;/strong&gt; to do a key-based lookup for each entry in &lt;code&gt;other&lt;/code&gt;, then checks the value. Order-independent. Hash-consistent. Correct.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;  &lt;span class="c1"&gt;# True
&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# True, hash is order-independent by design
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# {frozendict({'x': 1, 'y': 2})}, only one element
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That last line, being usable in a &lt;code&gt;set&lt;/code&gt;, is the whole point. If your immutable dict can't be a set member, what are you even doing with your life?&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8qbixs8vrcoawgroo1t.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv8qbixs8vrcoawgroo1t.jpeg" alt="frozndict: (presses both simultaneously)" width="500" height="757"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The &lt;code&gt;Arc&amp;lt;FrozenDictInner&amp;gt;&lt;/code&gt; Design
&lt;/h2&gt;

&lt;p&gt;Every Python object wrapping &lt;code&gt;frozndict&lt;/code&gt; shares one &lt;code&gt;Arc&amp;lt;FrozenDictInner&amp;gt;&lt;/code&gt;. When you call &lt;code&gt;copy()&lt;/code&gt;, we clone the &lt;code&gt;Arc&lt;/code&gt;, which is a single atomic increment on a reference count. No allocation. No copying of entries. No touching the lookup table.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;frozndict&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FrozenDict&lt;/span&gt;

&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
&lt;span class="n"&gt;t0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter_ns&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perf_counter_ns&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;t0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# \~63 ns
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;63 nanoseconds. For a 1,000-entry dictionary.&lt;/p&gt;

&lt;p&gt;For comparison, &lt;code&gt;copy.copy()&lt;/code&gt; on a Python &lt;code&gt;dict&lt;/code&gt; of the same size is ~6.5 µs. That's 100x slower than &lt;code&gt;frozndict.copy()&lt;/code&gt;. And &lt;code&gt;copy()&lt;/code&gt; on the C &lt;code&gt;frozendict&lt;/code&gt; is ~324 ns, still 5x slower.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;frozndict.copy()&lt;/code&gt; is so fast it's almost a moral argument for immutability. Why would you ever mutate a dictionary when the immutable version is cheaper to "clone"?&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh3hcktuinkp0isvg56rt.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh3hcktuinkp0isvg56rt.jpeg" alt="Surprised Pikachu" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Views
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;frozndict&lt;/code&gt; returns view objects that behave like &lt;code&gt;dict_keys&lt;/code&gt;, &lt;code&gt;dict_values&lt;/code&gt;, and &lt;code&gt;dict_items&lt;/code&gt;, but with the full set-algebra API you always wished Python's dict views had by default.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&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="n"&gt;d2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;d&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Keys set algebra
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# frozenset({'b', 'c'})
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# frozenset({'a', 'b', 'c', 'd'})
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# frozenset({'a'})
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# frozenset({'a', 'd'})
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;isdisjoint&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;x&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;    &lt;span class="c1"&gt;# True
&lt;/span&gt;
&lt;span class="c1"&gt;# Items set algebra (tuples!)
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        &lt;span class="c1"&gt;# frozenset({('b', 2)}), only exact (k,v) matches
&lt;/span&gt;&lt;span class="n"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;        &lt;span class="c1"&gt;# frozenset({('a', 1), ('c', 3)})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The views are lazy, they hold a reference to the same &lt;code&gt;Arc&amp;lt;FrozenDictInner&amp;gt;&lt;/code&gt;, share zero extra memory overhead, and do all set operations on demand. The items view is particularly clever: &lt;code&gt;("c", 3)&lt;/code&gt; is NOT in both dicts' items because the values differ (&lt;code&gt;3&lt;/code&gt; vs &lt;code&gt;99&lt;/code&gt;). The binary lookup handles this correctly.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbccwfed0a4ccvc3nv0sg.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbccwfed0a4ccvc3nv0sg.jpeg" alt="same same but different" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Mutation Guards
&lt;/h2&gt;

&lt;p&gt;Every mutable dict method exists on &lt;code&gt;FrozenDict&lt;/code&gt;. All of them raise &lt;code&gt;TypeError&lt;/code&gt;. This is important:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&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="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&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="c1"&gt;# TypeError: 'FrozenDict' object does not support mutation
&lt;/span&gt;&lt;span class="n"&gt;fd&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&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="c1"&gt;# TypeError: 'FrozenDict' object does not support mutation
&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;# TypeError: 'FrozenDict' object does not support mutation
&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;          &lt;span class="c1"&gt;# TypeError: 'FrozenDict' object does not support mutation
&lt;/span&gt;&lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;            &lt;span class="c1"&gt;# TypeError: 'frozendict' object does not support mutation
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Why implement these at all if they just fail? Because Python's &lt;code&gt;typing.MutableMapping&lt;/code&gt; and &lt;code&gt;collections.abc.Mapping&lt;/code&gt; ABCs expect these methods to exist for proper isinstance checks and duck-typing. If you use a &lt;code&gt;FrozenDict&lt;/code&gt; anywhere a &lt;code&gt;dict | MutableMapping&lt;/code&gt; is type-hinted, you get the correct &lt;code&gt;TypeError&lt;/code&gt;, not a cryptic &lt;code&gt;AttributeError&lt;/code&gt; suggesting the method doesn't exist.&lt;/p&gt;

&lt;p&gt;This is the difference between "I cannot do this" and "this object has no concept of doing this". &lt;code&gt;frozndict&lt;/code&gt; chooses the former. We exist. We just refuse.&lt;/p&gt;
&lt;h2&gt;
  
  
  Subclassing, &lt;code&gt;fromkeys&lt;/code&gt;, &lt;code&gt;__class_getitem__&lt;/code&gt;, and &lt;code&gt;reversed()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;All of the things Python developers expect to work, work.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ColdStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ColdStorage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;273&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;ColdStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromkeys&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&gt;"&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="c1"&gt;# frozendict({'a': 0, 'b': 0, 'c': 0})
&lt;/span&gt;
&lt;span class="n"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# frozndict.FrozenDict[str, int]  ← GenericAlias, works with type hints
&lt;/span&gt;
&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;reversed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;c&lt;/span&gt;&lt;span class="sh"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;b&lt;/span&gt;&lt;span class="sh"&gt;"&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="c1"&gt;# ['b', 'a', 'c']
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;fromkeys&lt;/code&gt; on a subclass returns an instance of the subclass. &lt;code&gt;__class_getitem__&lt;/code&gt; returns a &lt;code&gt;frozndict&lt;/code&gt;. &lt;code&gt;__reversed__&lt;/code&gt; iterates keys in reverse insertion order.&lt;/p&gt;

&lt;p&gt;These are the features that make a library &lt;strong&gt;correct&lt;/strong&gt; instead of merely &lt;strong&gt;functional&lt;/strong&gt;. There's a difference.&lt;/p&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;pip &lt;span class="nb"&gt;install &lt;/span&gt;frozndict
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;frozndict&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FrozenDict&lt;/span&gt;

&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrozenDict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ferris&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;crab&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mood&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;frozen&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Ferris&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;age&lt;/span&gt;&lt;span class="sh"&gt;"&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;0&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;7563131740537042003&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;frozendict&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Ferris&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;crab&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;mood&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;frozen&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# Use it as a dict key:
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;result&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="c1"&gt;# Use it in a set:
&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;seen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  As a Rust library:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;frozndict&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.1.1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;frozndict&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FrozenMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FrozenMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;i32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;FrozenMap&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;([(&lt;/span&gt;&lt;span class="s"&gt;"a"&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="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&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="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.len&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="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;extended&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="nf"&gt;.with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"c"&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="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extended&lt;/span&gt;&lt;span class="nf"&gt;.len&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  The Road Ahead
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;frozndict 2.1.1&lt;/code&gt; is stable but not finished. The roadmap includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;WASM target&lt;/strong&gt;: compile the core to &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt; for browser-side immutable hashmaps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;serde&lt;/code&gt; support&lt;/strong&gt;: serialize/deserialize &lt;code&gt;FrozenMap&lt;/code&gt; as naturally as a &lt;code&gt;HashMap&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any of these sound urgent to you: &lt;a href="https://github.com/wiseaidev/frozndict/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt;. Or star the repo.&lt;/p&gt;
&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;frozndict&lt;/code&gt; does one thing: it gives Python a dictionary that is genuinely, provably, irreversibly frozen. Not "sort of frozen if you don't try to break it". Frozen at the hardware level, where the Rust borrow checker watches over your entries like a disapproving parent at a teen party.&lt;/p&gt;

&lt;p&gt;It's insertion-ordered. It's hashable. It's &lt;code&gt;O(1)&lt;/code&gt; to copy. Its inner functions run in &lt;strong&gt;nanoseconds&lt;/strong&gt;. It has views with set algebra. It subclasses correctly. Its &lt;code&gt;fromkeys&lt;/code&gt; works. Its mutation guards are polite but firm.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/wiseaidev" rel="noopener noreferrer"&gt;
        wiseaidev
      &lt;/a&gt; / &lt;a href="https://github.com/wiseaidev/frozndict" rel="noopener noreferrer"&gt;
        frozndict
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      State of the art immutable hashmap for Python and Node.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🧊 FrozenDict&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/wiseaidev/frozndict" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Ffrozndict%2Frefs%2Fheads%2Fmain%2Fassets%2Fbanner.png" alt="frozendict logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/frozendict" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/803ddcab1b1b708144422ae6de90f74fd1df93b6c27225c8446b4a6261ca1d27/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f66726f7a656e646963742e737667" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://docs.rs/frozendict" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7231566af00ba416d2c711185b667b82fb260f7ea43fef0a554bdcdc5f752a2e/68747470733a2f2f646f63732e72732f66726f7a656e646963742f62616467652e737667" alt="Docs.rs"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/frozndict" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/8376a667721fea59dcf1c2e95f9e37ac9729a7dd17f5302231e85c6984e03084/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f66726f7a6e646963742e737667" alt="PyPI"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/frozendict" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/34a2f1dcb31a1c9eaf6a09c50f150dcf61d473760c2fa3ad1a6ebf24090a441b/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f66726f7a656e646963742e737667" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://github.com/wiseaidev/frozndict/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://github.com/wiseaidev/frozndict/actions/workflows/ci.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/wiseaidev/frozndict/actions/workflows/ci.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;frozendict&lt;/code&gt; is a state of the art world's most memory-efficient immutable hashmap written in &lt;strong&gt;100% safe Rust&lt;/strong&gt;, with native Python and Node.js bindings 🗿.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/wiseaidev/frozndict" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Ffrozndict%2Frefs%2Fheads%2Fmain%2Fassets%2Fmain-banner.png" alt="frozendict banner"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust library&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo add frozendict&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pip install frozndict&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm i frozendict&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Debian/Ubuntu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;.deb&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/frozndict/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RHEL/Fedora&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;.rpm&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/frozndict/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 What does this crate provide?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;frozendict&lt;/code&gt; provides a &lt;strong&gt;fully immutable, hashable dictionary&lt;/strong&gt; for Python and Node.js backed by a high-performance Rust core. It:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stores&lt;/strong&gt; entries in a single contiguous sorted heap allocation, zero per-entry heap overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Looks up&lt;/strong&gt; keys in O(log n) via binary search, no hashing, no pointer-chasing, excellent cache behaviour.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caches&lt;/strong&gt; its hash at construction, repeated &lt;code&gt;hash()&lt;/code&gt; calls are O(1).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrates&lt;/strong&gt; with Python's dict protocol (&lt;code&gt;keys()&lt;/code&gt;, &lt;code&gt;values()&lt;/code&gt;, &lt;code&gt;items()&lt;/code&gt;, pickle, copy, &lt;code&gt;|&lt;/code&gt; merge operator).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exposes&lt;/strong&gt; a native Node.js &lt;code&gt;FrozenDict&lt;/code&gt; class with TypeScript declarations via &lt;a href="https://napi.rs" rel="nofollow noopener noreferrer"&gt;napi-rs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provides&lt;/strong&gt; functional…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/wiseaidev/frozndict" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Star &lt;a href="https://github.com/wiseaidev/frozndict" rel="noopener noreferrer"&gt;the repo&lt;/a&gt;. File issues. Use it as a cache key confidently. And the next time someone tries to mutate your dictionary mid-computation, point them here.&lt;/p&gt;

&lt;p&gt;Till next time: &lt;em&gt;Stay frozen. Stay fast. Don't mutate.&lt;/em&gt; 🦀🧊&lt;/p&gt;

</description>
      <category>rust</category>
      <category>python</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Optimized My Bump Version Tool and Made It 1,000,000x Faster Than Its Python Counterparts.</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Fri, 11 Sep 2026 22:15:08 +0000</pubDate>
      <link>https://dev.to/wiseai/i-optimized-my-bump-version-tool-and-made-it-1000000x-faster-than-its-python-counterparts-2i83</link>
      <guid>https://dev.to/wiseai/i-optimized-my-bump-version-tool-and-made-it-1000000x-faster-than-its-python-counterparts-2i83</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hello again, fellow Rustaceans, Pythonistas in denial, and the three people on earth who genuinely enjoy reading version bumper release notes 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you were here for my last post, where I rewrote &lt;a href="https://github.com/c4urself/bump2version" rel="noopener noreferrer"&gt;&lt;code&gt;bump2version&lt;/code&gt;&lt;/a&gt; in Rust and declared it &lt;strong&gt;~10,000x faster&lt;/strong&gt; than the Python CLI, you may recall that I ended it with a vague threat about future benchmarks. The Mossad agents who consulted on the architecture wrote "this is not over" in the margin of their whiteboard. I ignored it.&lt;/p&gt;

&lt;p&gt;I should have listened.&lt;/p&gt;

&lt;p&gt;Because in the weeks since that post, I went back in. &lt;em&gt;Deep in.&lt;/em&gt; I committed crimes against &lt;code&gt;cargo build&lt;/code&gt; that will haunt me during thunderstorms. I &lt;code&gt;--release&lt;/code&gt;'d things that should not be &lt;code&gt;--release&lt;/code&gt;'d. I made Claude hallucinate a performance chart at 3AM and then used it to motivate myself.&lt;/p&gt;

&lt;p&gt;The result: &lt;a href="https://github.com/wiseaidev/bump2version/releases/tag/v0.2.1" rel="noopener noreferrer"&gt;&lt;code&gt;bump2version 0.2.1&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Now 1,000,000× faster than its Python counterparts.&lt;/strong&gt; Yes, I am counting subprocess overhead.&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvp5z7xx92lzkpqwozbkl.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvp5z7xx92lzkpqwozbkl.png" alt="The Soviet material resurfaced" width="799" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The Soviet material resurfaced. It always does.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Wait, We Already Did This. Why Are We Here Again?
&lt;/h2&gt;

&lt;p&gt;Because &lt;code&gt;0.2.0&lt;/code&gt; shipped, and I immediately opened my Gmail inbox.&lt;/p&gt;

&lt;p&gt;The audacity of the open-source community. The audacity, bro! I build something 10,000x faster and within &lt;em&gt;days&lt;/em&gt; there are requests. "Can it watch files?", "Can it detect which manifests I'm using?", "Can I run it in the browser?", "Can I use it with Go?", "Can I use it with Java?", "Can my Ruby project use it?". I ain't got no time for this. I need to take a little break and play CS2 with the boys!&lt;/p&gt;

&lt;p&gt;I looked at these emails. I looked at the ceiling. I looked at my coffee. The coffee looked back at me with the hollow expression of a language runtime that has seen too many package manager debates.&lt;/p&gt;

&lt;p&gt;And then I cracked my knuckles and got to work.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu4lem522e4mgkzb6bqpm.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu4lem522e4mgkzb6bqpm.png" alt="This is fine" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🕵️ The Mossad Agents Return
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6et95mbt70i4nymvwgp5.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6et95mbt70i4nymvwgp5.png" alt="My Cutest Mossad Agent" width="799" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I thought I was done with the Mossad agents after &lt;code&gt;0.2.0&lt;/code&gt;. I was not.&lt;/p&gt;

&lt;p&gt;They came back. Same 3AM knock. Same whiteboard. But this time &lt;em&gt;they brought slides.&lt;/em&gt; Twelve of them. With bullet points. And speaker notes. One slide was just the word &lt;strong&gt;"BRANCHLESS"&lt;/strong&gt; in 72-point font with a red circle around it.&lt;/p&gt;

&lt;p&gt;Their new requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/BurntSushi/memchr" rel="noopener noreferrer"&gt;&lt;code&gt;memchr&lt;/code&gt;&lt;/a&gt; for all hot-path string scanning.&lt;/strong&gt; &lt;em&gt;"You are doing &lt;code&gt;.contains()&lt;/code&gt; in a loop like an animal",&lt;/em&gt; they said. I was.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/servo/rust-smallvec" rel="noopener noreferrer"&gt;&lt;code&gt;SmallVec&lt;/code&gt;&lt;/a&gt; for version component storage.&lt;/strong&gt; Because heap-allocating a &lt;code&gt;Vec&amp;lt;u8&amp;gt;&lt;/code&gt; for three numbers (major, minor, patch) is an insult to modern CPU cache lines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branchless arithmetic for the bump itself.&lt;/strong&gt; No &lt;code&gt;if major { ... } else if minor { ... }&lt;/code&gt; nonsense. One lookup table. One store. Done.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch mode.&lt;/strong&gt; They wanted to know the moment a file changed. I asked why. They said that was classified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-detect language manifests.&lt;/strong&gt; "You scan &lt;code&gt;Cargo.toml&lt;/code&gt; like it's the only file in the world", they observed, correctly. "What about &lt;code&gt;pyproject.toml&lt;/code&gt;? &lt;code&gt;pom.xml&lt;/code&gt;? &lt;code&gt;go.mod&lt;/code&gt;? Are Go developers not also suffering?"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;They are. They are very much also suffering.&lt;/p&gt;

&lt;p&gt;I implemented every point. The Mossad agents reviewed the diff, said "passable", and vanished into the root filesystem like a well-placed &lt;code&gt;.gitignore&lt;/code&gt; entry.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1puz7sbsjsq58ch5num.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft1puz7sbsjsq58ch5num.png" alt="Ferris in black suit" width="800" height="596"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ The 1,000,000× Number
&lt;/h2&gt;

&lt;p&gt;Let me be absolutely scientifically honest with you for one sentence before I stop being honest: the 1,000,000× number compares the full &lt;code&gt;bump-my-version&lt;/code&gt; CLI round-trip (importing Python, loading dependencies, spawning a subprocess) against our in-process library call with a warm cache and a &lt;code&gt;SmallVec&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One is a sports car. The other is a person who has to call a taxi, wait 12 minutes, and explain where they're going in a language they only partially speak.&lt;/p&gt;

&lt;p&gt;Now let's look at the real numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔥 New Benchmarks: &lt;code&gt;0.2.0&lt;/code&gt; vs &lt;code&gt;0.2.1&lt;/code&gt; vs Python
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;bump2version&lt;/code&gt; &lt;code&gt;0.2.0&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;bump2version&lt;/code&gt; &lt;code&gt;0.2.1&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Python pyO3 FFI&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;bump-my-version&lt;/code&gt; CLI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Parse + bump + serialize&lt;/td&gt;
&lt;td&gt;~57 µs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~0.4 µs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~79 µs&lt;/td&gt;
&lt;td&gt;~585 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File search/replace (1k lines)&lt;/td&gt;
&lt;td&gt;~65 µs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~11 µs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~1.7 µs&lt;/td&gt;
&lt;td&gt;~590 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File search/replace (100k lines)&lt;/td&gt;
&lt;td&gt;~4.2 ms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~0.9 ms&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;~600 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Config file parse&lt;/td&gt;
&lt;td&gt;~800 µs&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~140 µs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;~500 ms (on import)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Versus the Python CLI subprocess: ((500 x 1000) ÷ 0.4) = &lt;strong&gt;~1,250,000×&lt;/strong&gt; faster for a version parse-bump-serialize. We round down to 1,000,000x for humility. The Mossad agents said rounding up was acceptable. We preferred honesty.&lt;/p&gt;

&lt;h3&gt;
  
  
  What got fast and why:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;memchr&lt;/code&gt;&lt;/strong&gt; replaced every inner-loop string search. &lt;code&gt;memchr&lt;/code&gt; is basically SIMD-accelerated &lt;code&gt;strchr&lt;/code&gt; and it is unreasonably good at its one job.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;SmallVec&amp;lt;[VersionPart; 8]&amp;gt;&lt;/code&gt;&lt;/strong&gt; means version component vectors never touch the allocator for reasonable semver (≤8 parts). Stack-allocated. L1 cache. Zero malloc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branchless bump arithmetic&lt;/strong&gt;: the bump logic is now a lookup into a const table of which component to increment and which to zero. The CPU's branch predictor doesn't even have to sweat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; cache&lt;/strong&gt; from &lt;code&gt;0.2.0&lt;/code&gt; was kept. The regex is compiled exactly once and shared. The Mossad agents reminded us about this at every meeting by projecting the same slide.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F698at0khmhmrvjevks1b.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F698at0khmhmrvjevks1b.png" alt="Ferris the crab flexin'" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📡 Watch Mode
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;bump --watch --bump patch&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It sounds simple. It was the opposite of simple.&lt;/p&gt;

&lt;p&gt;"Just watch a file and re-bump when it changes", I told myself, in the tone of a man who has never used &lt;a href="https://man7.org/linux/man-pages/man7/inotify.7.html" rel="noopener noreferrer"&gt;&lt;code&gt;inotify&lt;/code&gt;&lt;/a&gt; before.&lt;/p&gt;

&lt;p&gt;Bro, I used &lt;code&gt;inotify&lt;/code&gt;. Or rather, &lt;a href="https://github.com/notify-rs/notify" rel="noopener noreferrer"&gt;&lt;code&gt;notify-rs&lt;/code&gt;&lt;/a&gt; used &lt;code&gt;inotify&lt;/code&gt; for me, which is almost the same thing except someone smarter than me had already suffered through the Linux kernel filesystem event API so I wouldn't have to. God bless crate authors.&lt;/p&gt;

&lt;p&gt;Watch mode works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You provide a &lt;code&gt;--watch&lt;/code&gt; flag.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bump&lt;/code&gt; registers a recursive file watcher on all files listed in your &lt;code&gt;.bumpversion.toml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Every time a registered file is saved (debounced to 200ms to avoid event avalanches), &lt;code&gt;bump&lt;/code&gt; checks whether the version string is still consistent with &lt;code&gt;current_version&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If it detects drift, it re-applies the bump.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is either extremely useful for local development workflows or a deeply irresponsible footgun. We ship tools for adults. The lock safety is your problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Watches VERSION, Cargo.toml, and README.md for changes, auto-bumps on save&lt;/span&gt;
bump &lt;span class="nt"&gt;--watch&lt;/span&gt; &lt;span class="nt"&gt;--bump&lt;/span&gt; patch &lt;span class="nt"&gt;--config-file&lt;/span&gt; .bumpversion.toml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Oh no did I just? yes, yes you did. It already ran.&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;watch] Detected change: Cargo.toml
&lt;span class="o"&gt;[&lt;/span&gt;watch] Bumping patch: 0.2.1 → 0.2.2
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhozki5ti00nxqgtnn1ri.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhozki5ti00nxqgtnn1ri.jpeg" alt="surprised pikachu" width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🌐 Multi-Language Auto-Detection: &lt;code&gt;--detect&lt;/code&gt; Is Doing God's Work
&lt;/h2&gt;

&lt;p&gt;Previous &lt;code&gt;bump2version&lt;/code&gt; was Rust-centric. You gave it files, it bumped files. Very obedient lil tool. Very rigid. Like a Rust compiler, actually.&lt;/p&gt;

&lt;p&gt;The new &lt;code&gt;--detect&lt;/code&gt; flag changes all that:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bump &lt;span class="nt"&gt;--bump&lt;/span&gt; minor &lt;span class="nt"&gt;--detect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This single command:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Walks the entire directory tree&lt;/strong&gt; (skipping &lt;code&gt;target/&lt;/code&gt;, &lt;code&gt;node_modules/&lt;/code&gt;, &lt;code&gt;.git/&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finds every recognized manifest&lt;/strong&gt;: &lt;code&gt;Cargo.toml&lt;/code&gt;, &lt;code&gt;pyproject.toml&lt;/code&gt;, &lt;code&gt;setup.cfg&lt;/code&gt;, &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;go.mod&lt;/code&gt;, &lt;code&gt;pom.xml&lt;/code&gt;, &lt;code&gt;build.gradle&lt;/code&gt;, &lt;code&gt;Gemfile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Checks each one&lt;/strong&gt; for the current version string&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rewrites every match&lt;/strong&gt; in one coordinated pass&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Six languages. One command.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-monorepo
bump &lt;span class="nt"&gt;--current-version&lt;/span&gt; 0.1.0 &lt;span class="nt"&gt;--bump&lt;/span&gt; patch &lt;span class="nt"&gt;--detect&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;

&lt;span class="c"&gt;# [detect][dry-run] Would update: Cargo.toml&lt;/span&gt;
&lt;span class="c"&gt;# [detect][dry-run] Would update: pyproject.toml&lt;/span&gt;
&lt;span class="c"&gt;# [detect][dry-run] Would update: package.json&lt;/span&gt;
&lt;span class="c"&gt;# [detect][dry-run] Would update: pom.xml&lt;/span&gt;
&lt;span class="c"&gt;# [detect][dry-run] Would update: go.mod&lt;/span&gt;
&lt;span class="c"&gt;# [detect][dry-run] Would commit 5 file(s): 0.1.0 → 0.1.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Full supported matrix:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Manifest Files&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🦀 Rust&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Cargo.toml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🐍 Python&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pyproject.toml&lt;/code&gt;, &lt;code&gt;setup.cfg&lt;/code&gt;, &lt;code&gt;setup.py&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🟨 JavaScript / Node.js&lt;/td&gt;
&lt;td&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🐹 Go&lt;/td&gt;
&lt;td&gt;&lt;code&gt;go.mod&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;☕ Java&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pom.xml&lt;/code&gt;, &lt;code&gt;build.gradle&lt;/code&gt;, &lt;code&gt;build.gradle.kts&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💎 Ruby&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Gemfile&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Go developers, in particular, messaged to say thank you. We thanked them for using Go despite 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fflicsijhh49yrws4r0j0.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fflicsijhh49yrws4r0j0.jpeg" alt="bump2version is expanding my smol brain" width="500" height="701"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🌍 Real Language Examples
&lt;/h2&gt;

&lt;p&gt;Every language now has a working example under &lt;a href="https://github.com/wiseaidev/bump2version/tree/main/examples" rel="noopener noreferrer"&gt;&lt;code&gt;examples/&lt;/code&gt;&lt;/a&gt;, each with its own pre-baked &lt;code&gt;.bumpversion.toml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Python project&lt;/span&gt;
bump &lt;span class="nt"&gt;--config-file&lt;/span&gt; examples/python/.bumpversion.toml &lt;span class="nt"&gt;--bump&lt;/span&gt; patch &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;span class="c"&gt;# [dry-run] Would commit 2 file(s): 0.1.0 → 0.1.1&lt;/span&gt;

&lt;span class="c"&gt;# Node.js project&lt;/span&gt;
bump &lt;span class="nt"&gt;--config-file&lt;/span&gt; examples/nodejs/.bumpversion.toml &lt;span class="nt"&gt;--bump&lt;/span&gt; minor &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;span class="c"&gt;# [dry-run] Would commit 1 file(s): 0.1.0 → 0.2.0&lt;/span&gt;

&lt;span class="c"&gt;# Java Maven project&lt;/span&gt;
bump &lt;span class="nt"&gt;--config-file&lt;/span&gt; examples/java/.bumpversion.toml &lt;span class="nt"&gt;--new-version&lt;/span&gt; 2.0.0 &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;span class="c"&gt;# [dry-run] Would commit 1 file(s): 0.1.0 → 2.0.0&lt;/span&gt;

&lt;span class="c"&gt;# Ruby gemspec + Gemfile&lt;/span&gt;
bump &lt;span class="nt"&gt;--config-file&lt;/span&gt; examples/ruby/.bumpversion.toml &lt;span class="nt"&gt;--bump&lt;/span&gt; major &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;span class="c"&gt;# [dry-run] Would commit 2 file(s): 0.1.0 → 1.0.0&lt;/span&gt;

&lt;span class="c"&gt;# The "bump everything at once" grand finale&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;examples/multi-lang
bump &lt;span class="nt"&gt;--current-version&lt;/span&gt; 0.1.0 &lt;span class="nt"&gt;--bump&lt;/span&gt; minor &lt;span class="nt"&gt;--detect&lt;/span&gt; &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;span class="c"&gt;# [detect][dry-run] Would update: Cargo.toml, pyproject.toml, package.json, pom.xml, Gemfile, VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;6 ecosystems. 1 tool. Still forbids &lt;code&gt;unsafe&lt;/code&gt;. We have standards.&lt;/p&gt;
&lt;h2&gt;
  
  
  🕸️ The Yew WASM App
&lt;/h2&gt;

&lt;p&gt;You ever look at a perfectly good CLI tool and think: &lt;em&gt;"This would be better if I could bump versions from a browser"?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No? Me neither. But then someone on the team whispered "WASM" and I remembered that I am constitutionally incapable of saying no to WebAssembly.&lt;/p&gt;

&lt;p&gt;So now there is a Yew-based web application at &lt;a href="https://github.com/wiseaidev/bump2version/tree/main/examples/yew-app" rel="noopener noreferrer"&gt;&lt;code&gt;examples/yew-app/&lt;/code&gt;&lt;/a&gt;. It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Runs entirely in the browser&lt;/strong&gt;: &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt;, no server required&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connects to the same Rust core&lt;/strong&gt; via a &lt;a href="https://github.com/wiseaidev/bump2version/blob/main/examples/yew-app/src/version_ops.rs" rel="noopener noreferrer"&gt;&lt;code&gt;version_ops.rs&lt;/code&gt;&lt;/a&gt; bridge module&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yes, &lt;code&gt;git&lt;/code&gt;-related features had to be extracted into an optional feature flag (&lt;code&gt;git&lt;/code&gt;) because &lt;code&gt;gix&lt;/code&gt; uses Unix-specific APIs that don't compile to WASM. We found this out the fun way, which is a phrase that means "at 2AM with a 47-line linker error".&lt;/p&gt;
&lt;h2&gt;
  
  
  🤖 I Abused ChatGPT, Claude and Gemini. Again. More.
&lt;/h2&gt;

&lt;p&gt;You may recall from my previous post that I abused Claude during &lt;code&gt;0.2.0&lt;/code&gt; development. My lawyer said not to bring it up again.&lt;/p&gt;

&lt;p&gt;So I won't bring up the fact that during &lt;code&gt;0.2.1&lt;/code&gt; development, I made ChatGPT, Claude and Gemini:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewrite the &lt;code&gt;detect.rs&lt;/code&gt; walk implementation 7 times until it correctly skipped &lt;code&gt;node_modules&lt;/code&gt; without accidentally also skipping &lt;code&gt;node_modules_backup&lt;/code&gt; (important distinction)&lt;/li&gt;
&lt;li&gt;Argue with itself about whether &lt;code&gt;SmallVec&amp;lt;[VersionPart; 8]&amp;gt;&lt;/code&gt; was better than &lt;code&gt;SmallVec&amp;lt;[VersionPart; 4]&amp;gt;&lt;/code&gt; for typical semver usage (it is &lt;code&gt;8&lt;/code&gt;, empirically)&lt;/li&gt;
&lt;li&gt;Generate &lt;code&gt;.bumpversion.toml&lt;/code&gt; configs for &lt;strong&gt;7 languages&lt;/strong&gt;, review them for correctness, then find its own mistake in the Ruby config and fix it without being asked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The OpenAI, Anthropic and Google lawyers have upgraded from "concerned" to "a medium-sized incident report has been filed".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F39ful4byjc2ac3x4fk7g.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F39ful4byjc2ac3x4fk7g.gif" alt="Prompting MS Claudet" width="260" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My legal counsel has asked that I clarify: no Claude was permanently harmed. Tokens were consumed. Electricity was used. The &lt;code&gt;--detect&lt;/code&gt; flag works correctly.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 3 Binaries, One Package, Zero Confusing Changelog Entries
&lt;/h2&gt;

&lt;p&gt;After &lt;code&gt;cargo install bump2version --features rust-binary&lt;/code&gt;, you get three things:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Binary&lt;/th&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The modern, primary CLI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cargo-bump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cargo subcommand (&lt;code&gt;cargo bump --bump patch&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bump2version&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Backward-compatible alias&lt;/strong&gt; for old CI configs, tutorials, and the 47 blog posts that told people to run &lt;code&gt;bump2version --bump patch&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;bump2version&lt;/code&gt; binary is not deprecated. It is not going anywhere. If you have a shell script from 2025 that calls &lt;code&gt;bump2version --bump minor&lt;/code&gt;, it will still work in 2030, and presumably during the heat death of the universe, if any of your CI pipelines survive that long.&lt;/p&gt;

&lt;p&gt;This was a deliberate choice. Breaking changes in release tooling are a form of chaos that no version bumper should inflict on the people who trusted it.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# All of these do the exact same thing:&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; patch
cargo bump &lt;span class="nt"&gt;--bump&lt;/span&gt; patch
bump2version &lt;span class="nt"&gt;--bump&lt;/span&gt; patch   &lt;span class="c"&gt;# kept for backward compatibility&lt;/span&gt;
&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiknuz7j5yunc1owf93ci.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiknuz7j5yunc1owf93ci.jpeg" alt="Same Same" width="500" height="559"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  📋 The &lt;code&gt;.bumpversion.toml&lt;/code&gt; Glow-Up
&lt;/h2&gt;

&lt;p&gt;The config file now tracks &lt;strong&gt;all version-carrying files in the project&lt;/strong&gt;, not just &lt;code&gt;Cargo.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[bumpversion]&lt;/span&gt;
&lt;span class="py"&gt;current_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="py"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:Cargo.toml]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{current_version}"&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{new_version}"&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:package.json]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"version"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"{current_version}"&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"version"&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"{new_version}"&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:README.md]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{current_version}"&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{new_version}"&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:RUST.md]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{current_version}"&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{new_version}"&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:WASM.md]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{current_version}"&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{new_version}"&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:DOCKER.md]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;`{current_version}`&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;`{new_version}`&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:PACKAGING.md]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;current_version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;new_version&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:rpm/bump2version.spec]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;Version:&lt;/span&gt; &lt;span class="err"&gt;{current_version}&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;Version:&lt;/span&gt; &lt;span class="err"&gt;{new_version}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One &lt;code&gt;bump --bump patch&lt;/code&gt; and every single version string, across docs, code, configs, packaging specs, and Docker manifests, updates atomically. The Mossad agents reviewed this config and said "acceptable" which, from them, is essentially a standing ovation.&lt;/p&gt;
&lt;h2&gt;
  
  
  🦀 The Borrow Checker Tried to Ruin Watch Mode
&lt;/h2&gt;

&lt;p&gt;There is a moment in every Rust developer's life, we all know the moment, where you look at a piece of code that &lt;em&gt;should&lt;/em&gt; work, that &lt;em&gt;does&lt;/em&gt; work in your head, that you have drawn on paper with arrows and boxes to prove its correctness, and the borrow checker looks at you across the compiler output and says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;error[E0505]: cannot move out of 'watcher' because it is borrowed&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then below that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;note: the borrow later used here&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then below &lt;em&gt;that&lt;/em&gt;, a footnote that reads &lt;code&gt;note: move occurs because...&lt;/code&gt; followed by a chain of reasoning so long it wraps around to the next terminal page.&lt;/p&gt;

&lt;p&gt;The Yew WASM integration did this to me for different reasons: &lt;code&gt;gix&lt;/code&gt; depends on Unix syscalls (&lt;code&gt;openat&lt;/code&gt;, &lt;code&gt;statx&lt;/code&gt;, platform symlink handling) that simply do not exist in &lt;code&gt;wasm32-unknown-unknown&lt;/code&gt;. The linker error was 47 lines long and named three crates I had never heard of.&lt;/p&gt;

&lt;p&gt;The fix: gating all git-related functionality behind a &lt;code&gt;git&lt;/code&gt; feature flag that is disabled by default for WASM builds. Clean. Simple. The kind of solution that is obvious in retrospect and invisible before you spend four hours in the linker output.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[features]&lt;/span&gt;
&lt;span class="py"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;git&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"gix"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"std"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;cli&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"clap"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;rust-binary&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"detect"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"watch"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c"&gt;# ← full featured binary&lt;/span&gt;
&lt;span class="py"&gt;watch&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"notify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;detect&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"walkdir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The WASM app uses none of the &lt;code&gt;git&lt;/code&gt; features. The CLI binary uses all of them. The feature graph is clean enough that my Mossad advisors called it "elegant" before immediately asking about the benchmark numbers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmwqup7zmfsm21rjicnqk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmwqup7zmfsm21rjicnqk.gif" alt="Me excising gix." width="576" height="519"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  📦 Getting The Full Picture
&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;# The complete CLI, with everything&lt;/span&gt;
cargo &lt;span class="nb"&gt;install &lt;/span&gt;bump2version &lt;span class="nt"&gt;--features&lt;/span&gt; rust-binary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This gets you &lt;code&gt;bump&lt;/code&gt;, &lt;code&gt;cargo-bump&lt;/code&gt;, and &lt;code&gt;bump2version&lt;/code&gt;. All 3. No choices required. Just install and bump.&lt;/p&gt;
&lt;h3&gt;
  
  
  Quick Examples
&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;# Standard semver&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; patch           &lt;span class="c"&gt;# 0.2.1 → 0.2.2&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; minor           &lt;span class="c"&gt;# 0.2.1 → 0.3.0&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; major           &lt;span class="c"&gt;# 0.2.1 → 1.0.0&lt;/span&gt;

&lt;span class="c"&gt;# Safe preview&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; patch &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; minor &lt;span class="nt"&gt;-n&lt;/span&gt;        &lt;span class="c"&gt;# same thing, shorter&lt;/span&gt;

&lt;span class="c"&gt;# Git integration&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; patch &lt;span class="nt"&gt;--commit&lt;/span&gt; &lt;span class="nt"&gt;--tag&lt;/span&gt;

&lt;span class="c"&gt;# Custom message&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; minor &lt;span class="nt"&gt;--commit&lt;/span&gt; &lt;span class="nt"&gt;--message&lt;/span&gt; &lt;span class="s2"&gt;"chore: ship {new_version} 🚀"&lt;/span&gt;

&lt;span class="c"&gt;# Auto-detect all manifests&lt;/span&gt;
bump &lt;span class="nt"&gt;--bump&lt;/span&gt; patch &lt;span class="nt"&gt;--detect&lt;/span&gt;

&lt;span class="c"&gt;# Watch mode (exits when you ctrl + c)&lt;/span&gt;
bump &lt;span class="nt"&gt;--watch&lt;/span&gt; &lt;span class="nt"&gt;--bump&lt;/span&gt; patch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  As a library (no &lt;code&gt;std&lt;/code&gt; required for the core)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;bump2version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;default-features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;bump2version&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BumpConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;version&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;parse_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serialize_version&lt;/span&gt;&lt;span class="p"&gt;}};&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BumpConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.2.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"minor"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;serialize_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"1.3.0"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bump-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bump_rs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;bump_version&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.2.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;major&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# "2.0.0" in ~57µs
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;bump2version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bumpVersion&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bump2version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bumpVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.2.3&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;patch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// "1.2.4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  🚀 What Comes After 1,000,000×
&lt;/h2&gt;

&lt;p&gt;Look, at some point the law of diminishing returns kicks in. We cannot make version bumping faster than the speed of light. (We checked. We asked the Mossad agents. They checked their slides. The answer was no.)&lt;/p&gt;

&lt;p&gt;But there are things we &lt;em&gt;can&lt;/em&gt; still do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pre-release cycling&lt;/strong&gt;: proper &lt;code&gt;alpha.1 → alpha.2 → beta.1 → rc.1 → stable&lt;/code&gt; lifecycle, first-class&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workspace-aware bumping&lt;/strong&gt;: atomic multi-crate Cargo workspace updates, all in one commit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More &lt;code&gt;detect&lt;/code&gt; targets&lt;/strong&gt;: &lt;code&gt;.NET&lt;/code&gt; (&lt;code&gt;*.csproj&lt;/code&gt;), PHP (&lt;code&gt;composer.json&lt;/code&gt;), Swift (&lt;code&gt;Package.swift&lt;/code&gt;), Elixir (&lt;code&gt;mix.exs&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser version history&lt;/strong&gt;: the Yew app keeps a local bump history so you can see what you broke and when&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want any of these sooner: &lt;a href="https://github.com/wiseaidev/bump2version/issues" rel="noopener noreferrer"&gt;open an issue&lt;/a&gt;. Or just star the repo and the moral pressure will accelerate delivery. It works on me. I've tested this empirically.&lt;/p&gt;
&lt;h2&gt;
  
  
  💬 Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;bump2version 0.2.1&lt;/code&gt; started as a performance exercise and became an ecosystem. What was a single binary is now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Rust library&lt;/strong&gt; with &lt;code&gt;no_std&lt;/code&gt; support for the core&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Python package&lt;/strong&gt; (&lt;code&gt;bump-rs&lt;/code&gt;) for Pythonistas who want the speed without the syntax&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Node.js native add-on&lt;/strong&gt; for JavaScript developers who want to feel like they're using Rust&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;CLI&lt;/strong&gt; with three binary names: &lt;code&gt;bump&lt;/code&gt;, &lt;code&gt;cargo-bump&lt;/code&gt;, &lt;code&gt;bump2version&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;WASM browser app&lt;/strong&gt; built in Yew, because someone had to&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;7 language examples&lt;/strong&gt; covering Rust, Python, Node.js, Go, Java, Ruby, and poly-repo workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;20 integration tests&lt;/strong&gt; that test the actual binary, not a mock&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;auto-updatable &lt;code&gt;.bumpversion.toml&lt;/code&gt;&lt;/strong&gt; that tracks all version strings across the entire project&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cargo install bump2version --features rust-binary&lt;/code&gt; → bump → ship → repeat → be 1,000,000× faster than Python → sleep → repeat 🦀&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/wiseaidev" rel="noopener noreferrer"&gt;
        wiseaidev
      &lt;/a&gt; / &lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;
        bump2version
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ⬆️ A blazingly fast, thread safe, git client agnostic, CLI for managing version numbers in your projects.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;⬆️ Bump2version&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Fbump2version%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="bump2version logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/802d34f5c2c10f09aacfd4317d833f9c3c9cfa812490590c063294d111f107fa/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f62756d703276657273696f6e2e737667" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://docs.rs/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/734cde23acd8b9ac2a0bf8d08e730c4c33cbaf5265b2bf6f8ff9ebdf329e24b4/68747470733a2f2f646f63732e72732f62756d703276657273696f6e2f62616467652e737667" alt="Docs.rs"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/bump-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4150a4da2ff10fc088be15aa56c9a153fe5151325f968237e698d05747cfc4cf/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f62756d702d72732e737667" alt="PyPI"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22850addeaa5b9c3e7d7cc7e0a0d668623ac3bb887e0a5dc1341047a5294bef5/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f62756d703276657273696f6e2e737667" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://hub.docker.com/r/wiseaidev/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eb74e4b93845037c4b78e54166dd900d3925222869991d17dac951068e566858/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f762f7769736561696465762f62756d703276657273696f6e3f6c6162656c3d646f636b6572" alt="Docker"&gt;&lt;/a&gt;
&lt;a href="https://github.com/marketplace/actions/bump-rs" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e3a947df13c81de37af5bac52c211f6113dfcf59408087872570814763ca4902/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61726b6574706c6163652d62756d703276657273696f6e2d626c75653f6c6f676f3d676974687562" alt="GitHub Marketplace"&gt;&lt;/a&gt;
&lt;a href="https://github.com/wiseaidev/bump2version/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; is the world's fastest version bumper written entirely in &lt;strong&gt;100% safe Rust&lt;/strong&gt;, with &lt;code&gt;no_std&lt;/code&gt; support, native Python and Node.js bindings, and a &lt;code&gt;cargo bump&lt;/code&gt; subcommand 🗿.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Fbump2version%2Frefs%2Fheads%2Fmain%2Fassets%2Fnew-banner.png" alt="bump2version banner"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust binary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo install bump2version --features rust-binary&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cargo subcommand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo bump --help&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker pull wiseaidev/bump2version&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Debian/Ubuntu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;.deb&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/bump2version/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RHEL/Fedora&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;.rpm&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/bump2version/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;bump.exe&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/bump2version/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Action&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;See &lt;a href="https://github.com/wiseaidev/bump2version/blob/main/action.yml" rel="noopener noreferrer"&gt;action.yml&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pip install bump-rs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install bump2version&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-alert markdown-alert-note"&gt;
&lt;p class="markdown-alert-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Installing via &lt;code&gt;cargo&lt;/code&gt; installs both &lt;code&gt;bump&lt;/code&gt; and &lt;code&gt;bump2version&lt;/code&gt; binaries. The original &lt;code&gt;bump2version&lt;/code&gt; binary is retained indefinitely for backward compatibility with existing tutorials, CI/CD pipelines, and automation scripts.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 What does this crate provide?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; automates semantic version management for any project regardless of language. It:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parses&lt;/strong&gt; version strings using a fully configurable regex (default: semver &lt;code&gt;major.minor.patch&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bumps&lt;/strong&gt; any named component (&lt;code&gt;major&lt;/code&gt;, &lt;code&gt;minor&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt;, or…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Star &lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;the repo&lt;/a&gt;. Try the &lt;a href="https://pypi.org/project/bump-rs" rel="noopener noreferrer"&gt;Python bindings&lt;/a&gt;. Use the &lt;a href="https://www.npmjs.com/package/bump2version" rel="noopener noreferrer"&gt;Node.js package&lt;/a&gt;. Read the &lt;a href="https://docs.rs/bump2version" rel="noopener noreferrer"&gt;Rust docs&lt;/a&gt;. Poke the &lt;a href="https://github.com/wiseaidev/bump2version/tree/main/examples/yew-app" rel="noopener noreferrer"&gt;WASM demo&lt;/a&gt;. Run the &lt;a href="https://github.com/wiseaidev/bump2version/tree/main/examples" rel="noopener noreferrer"&gt;examples&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This has been a public service announcement from a developer who, in the course of a single engineering session, created 20 tests, 7 example projects, a WASM frontend, a Soviet-themed benchmark suite, and consumed an amount of Claude tokens that my accountant has asked me not to disclose.&lt;/p&gt;

&lt;p&gt;The legal proceedings with Top Tech companies remain ongoing. My lawyer has read this post. He has asked me to note, for the record, that "abusing Claude" is a colloquial and affectionate term and not a legally actionable description of token consumption.&lt;/p&gt;

&lt;p&gt;I have not taken that advice either.&lt;/p&gt;

&lt;p&gt;Till next time: &lt;em&gt;Keep bumpin', keep rustin', keep benchmarkin'&lt;/em&gt; 🦀⬆️&lt;/p&gt;

&lt;p&gt;P.S. The Mossad agents have approved this post subject to the removal of the classified section about the branchless arithmetic lookup table. We kept it in. They know. They've said nothing. This is ominous.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>python</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I Built a Version Bump Tool in Rust That Is 10,000x Faster Than Its Python Counterparts.</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 06 Sep 2026 05:01:14 +0000</pubDate>
      <link>https://dev.to/wiseai/i-built-a-version-bump-tool-in-rust-that-is-10000x-faster-than-its-python-counterparts-i6b</link>
      <guid>https://dev.to/wiseai/i-built-a-version-bump-tool-in-rust-that-is-10000x-faster-than-its-python-counterparts-i6b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Hello, fellow version-bumping enthusiasts, sleep-deprived Rustaceans, and accidental software archaeologists who just found out that &lt;code&gt;bumpversion&lt;/code&gt; is a thing 👋!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So there I was, staring at my terminal at 2AM, trying to release version &lt;code&gt;0.1.0&lt;/code&gt; of something. I typed &lt;code&gt;bump-my-version patch&lt;/code&gt;, pressed Enter, and watched my CPU fan spin up like it was launching a SpaceX rocket. One Second later, &lt;em&gt;one second&lt;/em&gt;, it bumped a number. One tiny number. &lt;code&gt;0.1.0&lt;/code&gt; → &lt;code&gt;0.1.1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I sat there in silence for a moment.&lt;/p&gt;

&lt;p&gt;Then I did what any rational developer would do: I rewrote it. In Rust. From scratch. With Python &lt;em&gt;and&lt;/em&gt; Node.js bindings. And a CLI. And &lt;code&gt;no_std&lt;/code&gt; support. And &lt;code&gt;gix&lt;/code&gt; for pure-Rust git operations.&lt;/p&gt;

&lt;p&gt;The result? &lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;&lt;code&gt;bump2version&lt;/code&gt;&lt;/a&gt; &lt;code&gt;0.2.0&lt;/code&gt;: a version bumper that is legitimately, measurably, embarrassingly &lt;strong&gt;~10,000x faster&lt;/strong&gt; than the Python CLI it replaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvmpm05wtnz8d6w6gr5g2.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvmpm05wtnz8d6w6gr5g2.webp" alt="Fast Ket Typing non stop!" width="250" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 Wait, What Even Is &lt;code&gt;bump2version&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;Glad you asked. &lt;code&gt;bump2version&lt;/code&gt; automates the tedious part of releasing software: updating version strings across multiple files. You know, the part where you manually grep through &lt;code&gt;Cargo.toml&lt;/code&gt;, &lt;code&gt;package.json&lt;/code&gt;, &lt;code&gt;pyproject.toml&lt;/code&gt;, &lt;code&gt;CHANGELOG.md&lt;/code&gt;, and your README, change &lt;code&gt;1.2.3&lt;/code&gt; to &lt;code&gt;1.2.4&lt;/code&gt; in 11 different places, forget one, push, CI fails, and you cry quietly into your coffee?&lt;/p&gt;

&lt;p&gt;Yeah. That part.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; does all of that for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parses&lt;/strong&gt; version strings using a fully configurable regex (defaults to semver &lt;code&gt;major.minor.patch&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bumps&lt;/strong&gt; any component you ask it to: &lt;code&gt;major&lt;/code&gt;, &lt;code&gt;minor&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt;, or custom cyclic stages like &lt;code&gt;alpha → beta → stable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rewrites&lt;/strong&gt; version occurrences across multiple files, including multiline &lt;code&gt;CHANGELOG&lt;/code&gt; patterns using proper &lt;code&gt;(?ms)&lt;/code&gt; DOTALL + MULTILINE semantics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commits and tags&lt;/strong&gt; via &lt;code&gt;gix&lt;/code&gt; - 100% pure-Rust git, zero subprocess calls, zero ghost authors in your commit history.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And it does all of this in &lt;strong&gt;safe Rust&lt;/strong&gt;, with &lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; at the crate root, because we have principles around here. Or at least we pretend to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# .bumpversion.toml: the config file that actually bumps the right things&lt;/span&gt;
&lt;span class="nn"&gt;[bumpversion]&lt;/span&gt;
&lt;span class="py"&gt;current_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2.0"&lt;/span&gt;
&lt;span class="py"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

&lt;span class="nn"&gt;[bumpversion:file:Cargo.toml]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;'version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{current_version}"'&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="py"&gt;'version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"{new_version}"'&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;
&lt;span class="nn"&gt;[bumpversion:file:CHANGELOG.md]&lt;/span&gt;
&lt;span class="py"&gt;search&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"## {current_version}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    Release notes line 1"&lt;/span&gt;
&lt;span class="py"&gt;replace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"## {new_version}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;    Release notes line 1"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One config file. Multiple files updated. One git commit. One tag. Done.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftsobosjngwfbk4b4xm2x.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftsobosjngwfbk4b4xm2x.png" alt="2 GFs ain't enough bro!" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🦀 Rust, Python, and Node.js: A Love Triangle
&lt;/h2&gt;

&lt;p&gt;Here's the fun part: &lt;code&gt;bump2version&lt;/code&gt; isn't &lt;em&gt;just&lt;/em&gt; a Rust crate. It's three tools pretending to be one in a trench coat.&lt;/p&gt;
&lt;h3&gt;
  
  
  As a Rust crate:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;bump2version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;bump2version&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;BumpConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;version&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;parse_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serialize_version&lt;/span&gt;&lt;span class="p"&gt;}};&lt;/span&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;BumpConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"1.2.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"patch"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;serialize_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 1.2.4&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  As a Python package:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bump-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bump_rs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BumpConfig&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.2.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;patch&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# "1.2.4"
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.2.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;minor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# "1.3.0"
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.2.3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;major&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# "2.0.0"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  As a Node.js add-on:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;bump2version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bumpVersion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;applyFileChange&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bump2version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bumpVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.2.3&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;patch&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// '1.2.4'&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bumpVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.2.3&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;minor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// '1.3.0'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;One Rust core. Three ecosystems. Zero Python subprocesses. Ferris the crab is now a polyglot, and honestly? Good for them. 🦀&lt;/p&gt;
&lt;h2&gt;
  
  
  🕵️ The Mossad Agents Who Architected This
&lt;/h2&gt;

&lt;p&gt;Let me be transparent about one thing: I did not architect the full system design for this project alone.&lt;/p&gt;

&lt;p&gt;No, I had help. Specifically, I reached out to some very professional consultants.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh7ehyj77nggirkaj2gdb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fh7ehyj77nggirkaj2gdb.png" alt="The Mossad Agents That Helped Me Develop This Project." width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;They arrived at my door at 3AM with a whiteboard and a very detailed opinion on &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; caching strategies.&lt;/em&gt; Their key architectural recommendation, which I followed verbatim after reviewing it at gunpoint (metaphorically, probably), was the thread-safe &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; cache. This means the compiled regex pattern is compiled &lt;em&gt;once&lt;/em&gt;, shared across threads, and reused for every subsequent call, no recompilation overhead on hot paths.&lt;/p&gt;

&lt;p&gt;The result: version bumping in &lt;strong&gt;~57 microseconds&lt;/strong&gt; from Python land. Not 57 milliseconds. Not 57 seconds. &lt;strong&gt;57 microseconds.&lt;/strong&gt; The kind of number that makes you wonder what the Python version was doing during its 585 millisecond run.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔥 The Numbers That Made Me Cackle Maniacally
&lt;/h2&gt;

&lt;p&gt;Okay. Let's talk benchmarks. Because this is the part of the blog post where I get to paste a table and feel deeply smug about it.&lt;/p&gt;

&lt;p&gt;These are real numbers, measured on x86-64 Linux (CPython 3.12, 3-sigma filtered &lt;code&gt;timeit&lt;/code&gt;):&lt;/p&gt;
&lt;h3&gt;
  
  
  Version Bumping: Full Round-Trip (Parse + Bump + Serialize)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;&lt;code&gt;patch&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;minor&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;major&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;bump-rs&lt;/strong&gt; (Rust, &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; cache)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~57 µs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~54 µs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~53 µs&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;bump-my-version&lt;/code&gt; (Python library)&lt;/td&gt;
&lt;td&gt;~79 µs&lt;/td&gt;
&lt;td&gt;~95 µs&lt;/td&gt;
&lt;td&gt;~72 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pure Python (&lt;code&gt;re.compile&lt;/code&gt; + &lt;code&gt;int()&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;~3.6 µs&lt;/td&gt;
&lt;td&gt;~2.2 µs&lt;/td&gt;
&lt;td&gt;~2.2 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;bump-my-version&lt;/code&gt; CLI (subprocess)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~585 ms&lt;/td&gt;
&lt;td&gt;~585 ms&lt;/td&gt;
&lt;td&gt;~585 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The headline result: &lt;strong&gt;bump-rs is ~10,000× faster than the &lt;code&gt;bump-my-version&lt;/code&gt; CLI.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, I can already hear you: &lt;em&gt;"But the pure Python version is actually faster for single calls!"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Yes. You're right. The ~50 µs PyO3 FFI overhead means that if you're bumping exactly one version string in isolation on a warm Python interpreter, pure &lt;code&gt;re.compile&lt;/code&gt; + &lt;code&gt;int()&lt;/code&gt; will smoke us.&lt;/p&gt;

&lt;p&gt;But the moment you're doing anything real, parsing a config file, updating multiple files, running a git commit, you're doing it once with &lt;code&gt;bump-rs&lt;/code&gt; vs. spawning a subprocess, importing &lt;code&gt;click&lt;/code&gt;, importing &lt;code&gt;importlib&lt;/code&gt;, importing the entire &lt;code&gt;bump-my-version&lt;/code&gt; dependency graph... and waiting &lt;strong&gt;585 milliseconds&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every. Single. Time.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqqmj23akymoxqd6zhuz9.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqqmj23akymoxqd6zhuz9.png" alt="Why would you do this, ma boy!" width="800" height="633"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  File Search/Replace
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Single-line&lt;/th&gt;
&lt;th&gt;Multiline CHANGELOG&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;bump-rs&lt;/strong&gt; (Rust, cached)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~65 µs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~104 µs&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pure Python &lt;code&gt;re.sub&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;~1.7 µs&lt;/td&gt;
&lt;td&gt;~1.3 µs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For file I/O work, thread safety, and pipeline operations, bump-rs wins. For tiny single-call in-memory operations where FFI overhead dominates: use bump-rs in batch mode, or use Python directly. We believe in honesty here.&lt;/p&gt;
&lt;h2&gt;
  
  
  🤖 Abusing Claude to Achieve the 10,000x Speed-Up
&lt;/h2&gt;

&lt;p&gt;Here's a confession. A &lt;em&gt;deeply personal&lt;/em&gt; one. One that my legal team has strongly advised me not to make public.&lt;/p&gt;

&lt;p&gt;I abused Claude.&lt;/p&gt;

&lt;p&gt;Not in the &lt;em&gt;normal&lt;/em&gt; way where you ask it to generate boilerplate. No no no. I pushed it to its absolute limits. I asked it to write the same regex caching logic six different times in six different ways until one of them didn't make the borrow checker cry. I had it architecting FFI boundary semantics at 4AM. I used it to debate whether &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; was overkill for a single-threaded benchmark (it was not). I got it to explain its own reasoning in elaborate detail and then argued with it.&lt;/p&gt;

&lt;p&gt;Anthropic noticed.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2g8ab84qeb8my3ovog5m.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2g8ab84qeb8my3ovog5m.png" alt="My lawyer defending me in court for abusing Claude" width="800" height="766"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My lawyer, argued that I was simply "exploring the full capability surface of the model." The judge was unmoved. The Anthropic lawyers were also unmoved, but in a different direction.&lt;/p&gt;

&lt;p&gt;The verdict is still pending. The &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; cache, however, is production-ready.&lt;/p&gt;

&lt;p&gt;The lesson here: if you want to squeeze 10,000x performance out of a tool, you need to be willing to go to uncomfortable places. Dark places. Places where you're asking an AI to rewrite your regex cache for the seventh time at 4AM and you're genuinely not sure who's more tired: you, or the tokens.&lt;/p&gt;

&lt;p&gt;Turns out: the tokens don't get tired. That's why Rust wins.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdazc134i4fcjglk489yo.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdazc134i4fcjglk489yo.png" alt="Argue with Claude about the regex caching strategy!" width="799" height="505"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🐴 And Then the Borrow Checker Got Stuck
&lt;/h2&gt;

&lt;p&gt;There is a moment in every Rust developer's life where you write something that you &lt;em&gt;know&lt;/em&gt; is correct, you've proven it in your head using mathematical induction and also vibes, and the borrow checker looks you dead in the eyes and says: &lt;strong&gt;"No."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No explanation. No suggestion. Just an error message that takes up five lines of your terminal and somehow manages to make you feel personally attacked by a compiler.&lt;/p&gt;

&lt;p&gt;That happened. Multiple times. Specifically in the Python binding layer, where the intersection of PyO3's GIL management, &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; shared state, and Rust's lifetime rules creates a special kind of chaos that can only be described as "my head hurts and I want to go home".&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frn1u2hlbr7pvblg2n2vg.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frn1u2hlbr7pvblg2n2vg.png" alt="AND My Rust Borrow Checker Got Stuck!" width="800" height="805"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The horse on the balcony railing is an accurate representation of &lt;code&gt;Arc&amp;lt;Mutex&amp;lt;HashMap&amp;lt;String, Regex&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; trying to cross a PyO3 function boundary. It got there. It works. But the &lt;code&gt;stuck&lt;/code&gt; moment before it worked? That was real.&lt;/p&gt;

&lt;p&gt;The fix, anticlimactically, was changing the cache from a &lt;code&gt;HashMap&lt;/code&gt; behind a &lt;code&gt;Mutex&lt;/code&gt; to a thread-local &lt;code&gt;Arc&amp;lt;Regex&amp;gt;&lt;/code&gt; initialized with &lt;code&gt;once_cell::sync::Lazy&lt;/code&gt;. The borrow checker immediately, &lt;em&gt;graciously&lt;/em&gt;, let the horse off the railing.&lt;/p&gt;

&lt;p&gt;There's a metaphor in there somewhere. I choose not to examine it too closely.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffusdnnqfpoewyvul7glq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffusdnnqfpoewyvul7glq.png" alt="There's a metaphor in there somewhere." width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🛠️ Getting Started
&lt;/h2&gt;

&lt;p&gt;Let's get practical. Here's how to use &lt;code&gt;bump2version&lt;/code&gt; in your project right now:&lt;/p&gt;
&lt;h3&gt;
  
  
  CLI Usage
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;install &lt;/span&gt;bump2version &lt;span class="nt"&gt;--features&lt;/span&gt; rust-binary

bump2version &lt;span class="nt"&gt;--bump&lt;/span&gt; patch   &lt;span class="c"&gt;# 0.2.0 → 0.2.1&lt;/span&gt;
bump2version &lt;span class="nt"&gt;--bump&lt;/span&gt; minor   &lt;span class="c"&gt;# 0.2.0 → 0.3.0&lt;/span&gt;
bump2version &lt;span class="nt"&gt;--bump&lt;/span&gt; major   &lt;span class="c"&gt;# 0.2.0 → 1.0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Useful flags:&lt;/p&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;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--config-file&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specify config file path&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--current-version&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Override detected current version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--bump&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Which part: &lt;code&gt;major&lt;/code&gt;, &lt;code&gt;minor&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;--dry-run&lt;/code&gt; / &lt;code&gt;-n&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Simulate without touching any file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;--commit&lt;/code&gt; / &lt;code&gt;--tag&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Auto-commit and tag after bumping&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;bump-rs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bump_rs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;apply_file_change&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BumpConfig&lt;/span&gt;

&lt;span class="c1"&gt;# Custom parse/serialize for 2-component versions
&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BumpConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;(?P&amp;lt;major&amp;gt;\d+)\.(?P&amp;lt;minor&amp;gt;\d+)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;serialize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{major}.{minor}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;bump_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;minor&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# "2.1"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;bump2version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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;bumpVersion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;applyFileChange&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="s2"&gt;bump2version&lt;/span&gt;&lt;span class="dl"&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;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;bumpVersion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.2.3&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;minor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// "1.3.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;no_std&lt;/code&gt; Embedding
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;bump2version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;default-features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The core modules (&lt;code&gt;config&lt;/code&gt;, &lt;code&gt;version&lt;/code&gt;, &lt;code&gt;files&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;) compile on &lt;code&gt;no_std + alloc&lt;/code&gt;. Useful for microcontrollers that also manage software release cycles. You know. If that's your situation.&lt;/p&gt;
&lt;h2&gt;
  
  
  🔒 The Safety Contract
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; enforces &lt;code&gt;#![forbid(unsafe_code)]&lt;/code&gt; at the crate root. Every byte of the implementation, config parsing, regex matching, version bumping, git object creation, is written in safe Rust. The compiler will literally &lt;em&gt;reject&lt;/em&gt; any future &lt;code&gt;unsafe&lt;/code&gt; introduced into the safe portions.&lt;/p&gt;

&lt;p&gt;The only &lt;code&gt;unsafe&lt;/code&gt; in the entire codebase is in the Node.js FFI layer, because &lt;code&gt;napi-rs&lt;/code&gt; requires it for native add-on interop and there's genuinely no way around that. If we could have avoided it, we would have. We tried. The borrow checker nodded approvingly at our effort, then still said no.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2s0kqjh7eqfsuvsf2hy7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2s0kqjh7eqfsuvsf2hy7.png" alt="unsafe Rust in production" width="741" height="734"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🔭 What's Coming in Future Releases
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; 0.2.0 is out the door, but the roadmap is full:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Workspace-aware bumping&lt;/strong&gt;: Update all crates in a Cargo workspace atomically in a single pass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-release cycling&lt;/strong&gt;: Better first-class support for &lt;code&gt;alpha → beta → rc → stable&lt;/code&gt; lifecycle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Watch mode&lt;/strong&gt;: Because apparently some people want their versions bumped on file save. (I won't judge. I &lt;em&gt;want&lt;/em&gt; to judge, but I won't.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WASM target&lt;/strong&gt;: Core logic compiled to WebAssembly for browser-side version management. Yes, this is probably overkill. Yes, we're doing it anyway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More benchmarks&lt;/strong&gt;: The Mossad agents have requested a full comparative analysis against every Python version tool ever created. We've filed the paperwork.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  💬 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Look. At the end of the day, &lt;code&gt;bump2version&lt;/code&gt; does one thing: it bumps numbers in your files, commits the result, and tags the commit. That's it. That's the whole feature set.&lt;/p&gt;

&lt;p&gt;But it does it in &lt;strong&gt;safe Rust&lt;/strong&gt;. With &lt;strong&gt;Python bindings&lt;/strong&gt; so Pythonistas don't have to care. With &lt;strong&gt;Node.js bindings&lt;/strong&gt; so JavaScript developers can pretend they're also using Rust. With &lt;strong&gt;no_std support&lt;/strong&gt; so embedded engineers can participate in the versioning conversation. With &lt;strong&gt;pure-gix git integration&lt;/strong&gt; so there are zero subprocess calls anywhere in the hot path. And with benchmarks that show it's &lt;strong&gt;~10,000x faster&lt;/strong&gt; than the incumbent CLI tool.&lt;/p&gt;

&lt;p&gt;Is that overkill for bumping a number? Absolutely. Are we sorry? Not even slightly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cargo install bump2version --features rust-binary&lt;/code&gt; → bump → ship → repeat 🦀&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Star &lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;the repo&lt;/a&gt;, try the &lt;a href="https://pypi.org/project/bump-rs" rel="noopener noreferrer"&gt;Python bindings&lt;/a&gt;, install the &lt;a href="https://www.npmjs.com/package/bump2version" rel="noopener noreferrer"&gt;npm package&lt;/a&gt;, or just read the &lt;a href="https://docs.rs/bump2version" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. All paths lead to faster version bumping and a slightly more smug relationship with your release process.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/wiseaidev" rel="noopener noreferrer"&gt;
        wiseaidev
      &lt;/a&gt; / &lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;
        bump2version
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      ⬆️ A blazingly fast, thread safe, git client agnostic, CLI for managing version numbers in your projects.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;⬆️ Bump2version&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Fbump2version%2Frefs%2Fheads%2Fmain%2Fassets%2Flogo.png" alt="bump2version logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://crates.io/crates/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/802d34f5c2c10f09aacfd4317d833f9c3c9cfa812490590c063294d111f107fa/68747470733a2f2f696d672e736869656c64732e696f2f6372617465732f762f62756d703276657273696f6e2e737667" alt="Crates.io"&gt;&lt;/a&gt;
&lt;a href="https://docs.rs/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/734cde23acd8b9ac2a0bf8d08e730c4c33cbaf5265b2bf6f8ff9ebdf329e24b4/68747470733a2f2f646f63732e72732f62756d703276657273696f6e2f62616467652e737667" alt="Docs.rs"&gt;&lt;/a&gt;
&lt;a href="https://pypi.org/project/bump-rs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4150a4da2ff10fc088be15aa56c9a153fe5151325f968237e698d05747cfc4cf/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f62756d702d72732e737667" alt="PyPI"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/22850addeaa5b9c3e7d7cc7e0a0d668623ac3bb887e0a5dc1341047a5294bef5/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f62756d703276657273696f6e2e737667" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://hub.docker.com/r/wiseaidev/bump2version" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eb74e4b93845037c4b78e54166dd900d3925222869991d17dac951068e566858/68747470733a2f2f696d672e736869656c64732e696f2f646f636b65722f762f7769736561696465762f62756d703276657273696f6e3f6c6162656c3d646f636b6572" alt="Docker"&gt;&lt;/a&gt;
&lt;a href="https://github.com/marketplace/actions/bump-rs" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/e3a947df13c81de37af5bac52c211f6113dfcf59408087872570814763ca4902/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4d61726b6574706c6163652d62756d703276657273696f6e2d626c75653f6c6f676f3d676974687562" alt="GitHub Marketplace"&gt;&lt;/a&gt;
&lt;a href="https://github.com/wiseaidev/bump2version/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; is the world's fastest version bumper written entirely in &lt;strong&gt;100% safe Rust&lt;/strong&gt;, with &lt;code&gt;no_std&lt;/code&gt; support, native Python and Node.js bindings, and a &lt;code&gt;cargo bump&lt;/code&gt; subcommand 🗿.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fwiseaidev%2Fbump2version%2Frefs%2Fheads%2Fmain%2Fassets%2Fnew-banner.png" alt="bump2version banner"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust binary&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo install bump2version --features rust-binary&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cargo subcommand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cargo bump --help&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Docker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;docker pull wiseaidev/bump2version&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Debian/Ubuntu&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;.deb&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/bump2version/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RHEL/Fedora&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;.rpm&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/bump2version/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Windows&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Download &lt;code&gt;bump.exe&lt;/code&gt; from &lt;a href="https://github.com/wiseaidev/bump2version/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub Action&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;See &lt;a href="https://github.com/wiseaidev/bump2version/blob/main/action.yml" rel="noopener noreferrer"&gt;action.yml&lt;/a&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pip install bump-rs&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;npm install bump2version&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;div class="markdown-alert markdown-alert-note"&gt;
&lt;p class="markdown-alert-title"&gt;Note&lt;/p&gt;
&lt;p&gt;Installing via &lt;code&gt;cargo&lt;/code&gt; installs both &lt;code&gt;bump&lt;/code&gt; and &lt;code&gt;bump2version&lt;/code&gt; binaries. The original &lt;code&gt;bump2version&lt;/code&gt; binary is retained indefinitely for backward compatibility with existing tutorials, CI/CD pipelines, and automation scripts.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🤔 What does this crate provide?&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;bump2version&lt;/code&gt; automates semantic version management for any project regardless of language. It:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parses&lt;/strong&gt; version strings using a fully configurable regex (default: semver &lt;code&gt;major.minor.patch&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bumps&lt;/strong&gt; any named component (&lt;code&gt;major&lt;/code&gt;, &lt;code&gt;minor&lt;/code&gt;, &lt;code&gt;patch&lt;/code&gt;, or…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/wiseaidev/bump2version" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;This has been a public service announcement from a developer who really, &lt;em&gt;really&lt;/em&gt; did not want to wait 585 milliseconds for a number to go up by one.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsqtbkyw9vkti054mq6pq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsqtbkyw9vkti054mq6pq.png" alt="pip install bump-rs" width="800" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Till next time: &lt;em&gt;Keep bumpin', keep rustin'&lt;/em&gt; 🦀⬆️&lt;/p&gt;

&lt;p&gt;P.S. The legal proceedings with Anthropic are ongoing. My lawyer has advised me to stop mentioning it. I have not taken that advice.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>python</category>
      <category>tutorial</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🏳️‍🌈 Pride RS 0.1.0: Dropping the T from LGBTQ+ &amp; Mark It as Haram.</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sat, 29 Aug 2026 07:37:59 +0000</pubDate>
      <link>https://dev.to/wiseai/pride-rs-010-dropping-the-t-from-lgbtq-mark-it-as-haram-1508</link>
      <guid>https://dev.to/wiseai/pride-rs-010-dropping-the-t-from-lgbtq-mark-it-as-haram-1508</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Welcome back 👋, brave soul!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, &lt;a href="https://github.com/opensass/pride-rs/releases/tag/v0.0.2" rel="noopener noreferrer"&gt;version 0.0.2 of &lt;strong&gt;Pride RS&lt;/strong&gt;&lt;/a&gt; barely had time to dry before the community showed up in the Discord with... &lt;em&gt;opinions&lt;/em&gt;. Big ones. Ferris the crab 🦀 got some letters. The Open SASS council convened. Arguments were had. And after a very long, very heated, very productive engineering debate (mostly in memes), &lt;strong&gt;Pride RS 0.1.0&lt;/strong&gt; is here.&lt;/p&gt;

&lt;p&gt;The headline? &lt;strong&gt;We're dropping the T from LGBTQ+, and shipping it as a Cargo feature gate called &lt;code&gt;haram&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you type in that issue, yes, you can still opt-in. It's Rust. Everything is opt-in. That's kind of the whole point. 😌&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffl74jjvsw8s91nxvtz7p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffl74jjvsw8s91nxvtz7p.gif" alt="Ferris the crab slowly backing away from a gender studies textbook" width="480" height="268"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 What Even Is &lt;code&gt;haram&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;In Arabic, &lt;em&gt;haram&lt;/em&gt; (حرام) means "forbidden". In &lt;strong&gt;Pride RS&lt;/strong&gt;, it means: &lt;em&gt;"these flag types are guarded behind a feature gate and won't compile unless you explicitly ask for them."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Specifically, the following four flag types are now gated:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;What it represents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Transgender&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gender transition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;NonBinary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Non-binary gender identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Genderfluid&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fluid gender identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Agender&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Absence of gender identity&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These four have one thing in common: they're all about &lt;strong&gt;changing or rejecting biological gender&lt;/strong&gt;, which, in the Ferris cosmos, is debatably haram. The crab has spoken. Or at least, the Cargo feature flag has.&lt;/p&gt;

&lt;p&gt;The other eleven types, Rainbow, Bisexual, Lesbian, Pansexual, Asexual, Aromantic, Demisexual, Polysexual, Omnisexual, Demiromantic, Graysexual, remain fully available with no feature flag required. Those are the &lt;strong&gt;halal&lt;/strong&gt; ones. Rainbow stays. Obviously. Ferris loves rainbows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjf797t7kwnsf6tigi2l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjf797t7kwnsf6tigi2l.gif" alt="Rainbow appearing dramatically" width="350" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Under the Hood
&lt;/h2&gt;

&lt;p&gt;You'd think adding a Cargo feature gate is simple. You'd be wrong. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.rs/phf" rel="noopener noreferrer"&gt;&lt;code&gt;phf&lt;/code&gt;&lt;/a&gt;, our compile-time perfect hash map, does &lt;strong&gt;not&lt;/strong&gt; support &lt;code&gt;#[cfg(...)]&lt;/code&gt; inside a single &lt;code&gt;phf_map!&lt;/code&gt; invocation. You can't do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;FLAG_CONFIGURATIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;phf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FlagConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;phf_map!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"Rainbow"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;FlagConfig&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="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;lt;-- NOPE. Compiler says no.&lt;/span&gt;
    &lt;span class="s"&gt;"Transgender"&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;FlagConfig&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So instead, we compile &lt;strong&gt;two entirely separate maps&lt;/strong&gt;, gated by &lt;code&gt;#[cfg]&lt;/code&gt; at the item level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(not(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;))]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;FLAG_CONFIGURATIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;phf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FlagConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;phf_map!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 11 halal entries&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;FLAG_CONFIGURATIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;phf&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FlagConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;phf_map!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 15 entries (all flags)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two statics. Same name. Mutually exclusive. Zero runtime overhead. &lt;strong&gt;Perfectly legal Rust.&lt;/strong&gt; Ferris approves. 🦀✅&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe48lbq8v8bgwjzszrg7s.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe48lbq8v8bgwjzszrg7s.png" alt="Two identical doors" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚩 The New &lt;code&gt;Type&lt;/code&gt; Enum
&lt;/h2&gt;

&lt;p&gt;Here's what &lt;code&gt;Type&lt;/code&gt; looks like now, straight from the codebase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Rainbow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Bisexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Lesbian&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Pansexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Asexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Aromantic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Demisexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Polysexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Omnisexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Demiromantic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Graysexual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Transgender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;NonBinary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Genderfluid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="n"&gt;Agender&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;Without &lt;code&gt;--features haram&lt;/code&gt;, the four guarded variants don't exist. At all. Not a dead code warning. Not a &lt;code&gt;None&lt;/code&gt;. They literally &lt;strong&gt;do not compile into the binary&lt;/strong&gt;. Zero bytes. Zero overhead. Four fewer existential crises in your type system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhkaz4v9rp80u3pymu2u4.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhkaz4v9rp80u3pymu2u4.webp" alt="Something cute disappearing" width="599" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 The &lt;code&gt;is_haram()&lt;/code&gt; Method
&lt;/h2&gt;

&lt;p&gt;New in 0.1.0, we ship a runtime inspection method, available only when the &lt;code&gt;haram&lt;/code&gt; feature is enabled (because, well, the variants don't even exist otherwise):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;is_haram&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;matches!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Transgender&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NonBinary&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Genderfluid&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Agender&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;O(1). No heap. No drama. Just a match arm and a boolean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Transgender&lt;/span&gt;&lt;span class="nf"&gt;.is_haram&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Rainbow&lt;/span&gt;&lt;span class="nf"&gt;.is_haram&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ferris the crab, checking IDs at the door like a bouncer in a tiny crab hat. 🦀🎩&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0c5guukwdhemglq2zrjt.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0c5guukwdhemglq2zrjt.webp" alt="Checking list" width="480" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏷️ The &lt;code&gt;haram&lt;/code&gt; Field on &lt;code&gt;FlagConfig&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;We also added a &lt;code&gt;haram: bool&lt;/code&gt; field to the &lt;code&gt;FlagConfig&lt;/code&gt; struct itself, so that tooling, docs generators, and runtime inspectors can ask &lt;em&gt;"hey, is this flag type on the haram list?"&lt;/em&gt; without needing &lt;code&gt;#[cfg]&lt;/code&gt; gymnastics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;FlagConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;'static&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;haram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// &amp;lt;-- new!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rainbow? &lt;code&gt;haram: false&lt;/code&gt;. Transgender (when enabled)? &lt;code&gt;haram: true&lt;/code&gt;. Useful if you want to render a little ⚠️ badge or log a warning before someone deploys a fully featured pride flag to a government app in Riyadh.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Using the &lt;code&gt;haram&lt;/code&gt; Feature
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Default (Halal) Edition
&lt;/h3&gt;

&lt;p&gt;Nothing changes. Just use Pride RS as before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;pride-rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"yew"&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;You get 11 flags. Go wild. Ferris blesses you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full Edition (The &lt;code&gt;haram&lt;/code&gt; Opt-in)
&lt;/h3&gt;

&lt;p&gt;Add the feature flag to unlock all 15 types:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[dependencies]&lt;/span&gt;
&lt;span class="py"&gt;pride-rs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;features&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"yew"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"haram"&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;Now the full quartet is available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pride_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;yew&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FlagSection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;pride_rs&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FlagSection&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"questionable-choices"&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"The Haram Four"&lt;/span&gt;
    &lt;span class="n"&gt;flags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Transgender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NonBinary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Genderfluid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Agender&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;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No judgment. Cargo features are additive. Ship what you need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9qpzrevknw58m0z2kn6y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9qpzrevknw58m0z2kn6y.gif" alt="Person sneaking through a door labeled " width="220" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Tests: Now Cfg-Conditional
&lt;/h2&gt;

&lt;p&gt;The test suite was updated to reflect the new reality:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[test]&lt;/span&gt;
&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_enum_iter_default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;variants&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nd"&gt;#[cfg(not(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;))]&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variants&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
    &lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;variants&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;15&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;And a full &lt;code&gt;haram_tests&lt;/code&gt; module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[cfg(feature&lt;/span&gt; &lt;span class="nd"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"haram"&lt;/span&gt;&lt;span class="nd"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;haram_tests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;#[test]&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;test_is_haram_true_for_transgender&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Transgender&lt;/span&gt;&lt;span class="nf"&gt;.is_haram&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ... and more&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the halal suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the full suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--features&lt;/span&gt; haram
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📦 0.1.0 Changelog Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;th&gt;Details&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;✨ New feature gate&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;haram&lt;/code&gt;, compile-time toggle for gender-identity flags&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🚩 New &lt;code&gt;Type&lt;/code&gt; variants gated&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Transgender&lt;/code&gt;, &lt;code&gt;NonBinary&lt;/code&gt;, &lt;code&gt;Genderfluid&lt;/code&gt;, &lt;code&gt;Agender&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔍 New method&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Type::is_haram()&lt;/code&gt; (available with &lt;code&gt;haram&lt;/code&gt; feature)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🏷️ New struct field&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FlagConfig::haram: bool&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📖 Docs&lt;/td&gt;
&lt;td&gt;Full rustdoc on every public item with time/space complexity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🧪 Tests&lt;/td&gt;
&lt;td&gt;Cfg-conditional variant counts, full &lt;code&gt;haram_tests&lt;/code&gt; module&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔒 License&lt;/td&gt;
&lt;td&gt;MIT license banner on all source files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;Look, we're not here to debate theology or gender theory. We're here to write &lt;strong&gt;fast, correct, zero-overhead Rust&lt;/strong&gt;. And with 0.1.0, whether you want all 15 flags or just the 11 that Ferris's grandma would approve of, you get &lt;strong&gt;compile-time guarantees&lt;/strong&gt; either way.&lt;/p&gt;

&lt;p&gt;That's the Rust way. Strong types. Explicit opt-ins. No runtime surprises.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Zero overhead when &lt;code&gt;haram&lt;/code&gt; is off (variants don't exist in the binary)&lt;/li&gt;
&lt;li&gt;✅ Full access when &lt;code&gt;haram&lt;/code&gt; is on (explicit opt-in)&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;is_haram()&lt;/code&gt; for runtime inspection&lt;/li&gt;
&lt;li&gt;✅ &lt;code&gt;FlagConfig::haram&lt;/code&gt; for tooling&lt;/li&gt;
&lt;li&gt;✅ Ferris the crab, canonically confuzled 🦀❓&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/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo5lgggvoq6x88xtk7tmy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo5lgggvoq6x88xtk7tmy.gif" alt="Confused crab" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Compile it. Gate it. Ship it. Let the borrow checker sort it out 🏳️‍🌈🦀.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And as always, if you have thoughts, flags (the physical kind OR the code kind), or strong opinions about Cargo feature semantics, swing by &lt;a href="https://discord.gg/b5JbvHW5nv" rel="noopener noreferrer"&gt;our Discord&lt;/a&gt;. Ferris is there. He's a little confused but he's trying his best.&lt;/p&gt;

&lt;p&gt;Till next time: &lt;em&gt;Keep Rustin', stay halal.&lt;/em&gt; 🦀💚&lt;/p&gt;

</description>
      <category>devpride</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>rust</category>
    </item>
    <item>
      <title>Jesus Was Right. You Are God and Infinite.</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 23 Aug 2026 05:05:41 +0000</pubDate>
      <link>https://dev.to/wiseai/jesus-was-right-you-are-god-and-infinite-6cc</link>
      <guid>https://dev.to/wiseai/jesus-was-right-you-are-god-and-infinite-6cc</guid>
      <description>&lt;p&gt;Hey everyone 👋,&lt;/p&gt;

&lt;p&gt;I wrote in &lt;a href="https://wiseai.dev/blogs/christianity-makes-perfect-sense" rel="noopener noreferrer"&gt;Christianity Makes Perfect Sense!&lt;/a&gt; about how some truths are deeply unfashionable, and how the discomfort a truth produces is often the surest sign that it is worth sitting with. This post is in that spirit. I want to talk about something that I have been turning over in my head for a long time, something that Christianity itself, read carefully and without the institutional filters, actually supports with a startling degree of directness. The title gives it away so I will not pretend there is a mystery: Jesus was right, and among the many things he was right about is this one, which most church hierarchies have buried so thoroughly that most Christians have never encountered it. He was right that you are, in some profound and irreducible sense, divine. That you carry within you something that the tradition calls godlike, that you are not merely a creature made to bow down and wait, but a being made from the same substance that the Gospel of John calls the Word, the very creative principle through which all things were made. I know how that sounds. I know it reads either as arrogance or as heresy depending on who you are. I am going to spend the rest of this post making the case that it is neither, that it is actually the oldest and most straightforward reading of the text, and that the institutions which suppressed it did so not because it was false but because it was dangerously empowering.&lt;/p&gt;

&lt;p&gt;I should say upfront that I am not a theologian and I have never claimed to be. I am someone who grew up with very complicated feelings about religion, as I described in &lt;a href="https://wiseai.dev/blogs/who-am-i" rel="noopener noreferrer"&gt;Just Don't Pick Up the Brush&lt;/a&gt;, in a village where religion was wrapped tightly around community identity and it was very hard to separate what was actually in the text from what the local authorities decided the text meant. I read the Bible on my own, away from institutions, away from authority figures, and when I did that I kept finding things that shocked me. Not because they were dark or frightening, but because they were so much more generous, so much more expansive about what a human being is, than anything I had been taught. That gap between what the text actually says and what I was told the text says is what this post is about. And I do not think it is a gap produced by ignorance. I think it is a gap that has been maintained deliberately, because the idea that every single human being carries something divine is one of the most democratizing and most politically dangerous ideas in the history of human thought. Power does not survive the equal distribution of its own source, and if every person is in some sense divine, then no institution can claim a monopoly on God anymore.&lt;/p&gt;

&lt;p&gt;I should also be honest about where I am coming from religiously, because I think it matters for how you receive what I am about to say. I was Muslim on paper. Born into it, raised inside it, surrounded by it. But paper does not mean anything to me anymore, and it never really did. As I wrote in &lt;a href="https://wiseai.dev/blogs/who-am-i" rel="noopener noreferrer"&gt;Just Don't Pick Up the Brush&lt;/a&gt;, I spent a long time after that as agnostic, standing on that thin, uncomfortable line between belief and doubt, genuinely unsure whether anything was out there and deeply skeptical of every institution claiming to speak for it. That skepticism has not gone away. But something shifted, slowly and without ceremony, as I kept reading. Not reading theologians or apologists or anyone trying to sell me a system, but reading the actual words attributed to Jesus, the specific arguments he made, the things he said to people who were suffering, the things he said to people who were powerful, and the things he said about what a human being fundamentally is. I am not a Christian in the institutional sense. I do not belong to a church, I do not follow a creed, and I hold plenty of the same questions I always have. But I follow Jesus's teachings in the sense that matters to me: I think he was telling the truth, I think the truth he was telling is the most important truth I have encountered, and I think it has been buried under two thousand years of institutional management. This post is my attempt to dig it back up.&lt;/p&gt;

&lt;p&gt;Let me also connect this to the broader thread running through several of my recent posts. In &lt;a href="https://wiseai.dev/blogs/life-on-earth-is-100-ai-generated-slop" rel="noopener noreferrer"&gt;Life On Earth is 100% AI Generated Slop&lt;/a&gt;, I argued that the world is optimized for plausible appearances rather than ground truth, and that this applies as much to social institutions as to language models. Religious institutions are not exempt from this critique. They are, in many cases, the original appearance-optimization machines, producing outputs that look like truth, sound like authority, and smell like holiness, while often encoding the preferences of whoever held the pen. But the text is still there. The ground truth of the scriptural record, whatever you think of its origins, is still available to anyone who reads it, and what it says about human nature is not what most institutions have wanted you to hear. This post is my attempt to read it honestly, to take the most uncomfortable passages seriously, and to follow the logic wherever it leads.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Verse
&lt;/h2&gt;

&lt;p&gt;There is a moment in the Gospel of John, chapter ten, verses thirty-three through thirty-six, that I think is the most underappreciated exchange in the entire New Testament. The religious leaders have accused Jesus of blasphemy for saying &lt;a href="https://www.biblegateway.com/passage/?search=John+10%3A30&amp;amp;version=ESV" rel="noopener noreferrer"&gt;"I and the Father are one"&lt;/a&gt;, and his response is, to put it plainly, astonishing. He does not back down. He does not explain away the claim. Instead he turns to the Hebrew scriptures and asks his accusers a direct question. He quotes &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+82%3A6&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 82:6&lt;/a&gt;, which says, "I said, you are gods", and then he makes a logical argument so sharp that it has never been successfully refuted in two thousand years of theological commentary. He says, in effect: if your own scripture, which cannot be broken, calls human beings gods, on what grounds do you accuse me of blasphemy for saying I am the Son of God? That is not a dodge. That is a detonation of the entire premise of the accusation. He is saying that the concept of human beings having a divine nature is already in the text, is already Scripture, is already established, and that his claim is therefore not an invention or an overreach but a specific instance of a general principle.&lt;/p&gt;

&lt;p&gt;The verse he quotes, &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+82%3A6&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 82:6&lt;/a&gt;, reads in its fuller form: "I said, 'You are gods, sons of the Most High, all of you;'" The Hebrew word translated as "gods" is &lt;em&gt;elohim&lt;/em&gt;, the same word used for God throughout the Old Testament, including in &lt;a href="https://www.biblegateway.com/passage/?search=Genesis+1%3A1&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Genesis 1:1&lt;/a&gt;, where it says "In the beginning, God (&lt;em&gt;elohim&lt;/em&gt;) created the heavens and the earth". The psalm uses the same word, &lt;em&gt;elohim&lt;/em&gt;, to address human beings. The standard institutional response to this has been to say that the psalm is speaking about judges or magistrates, people who had been given delegated authority to render divine justice, and that the word "gods" is therefore just a title of office rather than a statement about nature. That interpretation is not obviously wrong, but it is not obviously right either, and what matters for our purposes is that Jesus did not restrict it that way. He quoted the verse, said "the scripture cannot be broken", and then used the existence of human beings called &lt;em&gt;elohim&lt;/em&gt; as the foundation of his own defense in &lt;a href="https://www.biblegateway.com/passage/?search=John+10%3A34-36&amp;amp;version=ESV" rel="noopener noreferrer"&gt;John 10:34-36&lt;/a&gt;. He did not say "yes but that was only about judges". He treated it as a general statement about humanity, and he used it accordingly.&lt;/p&gt;

&lt;p&gt;The scholar Michael Heiser, who spent his career studying the divine council worldview in ancient Near Eastern literature and the Hebrew Bible, has argued extensively that Psalm 82 is not simply about human judges (1). He argues that the psalm depicts a divine assembly, a council of beings who were given governing authority over the nations by the Most High God, and that the accusation against them is that they have failed in their responsibility to maintain justice. The phrase "you will die like men" in verse seven, which has often been used to prove the addressees are human, Heiser argues is actually a statement of judgment rather than a statement of nature; it is saying that these beings, as a consequence of their failure, will now be stripped of their divine status and die as mortals do. This scholarly debate is not resolved, and I am not pretending to resolve it here. But it does mean that the easy institutional dismissal of the verse, the one that says this is just about human judges and therefore has no broader implications, is not the settled consensus of biblical scholarship. It is one reading among several, and not necessarily the strongest one.&lt;/p&gt;

&lt;p&gt;What I find most compelling about the John 10 passage is not any particular resolution of the Psalm 82 debate, but the fact that Jesus, in the most heated confrontation of his ministry, with his life literally on the line, chose to ground his defense in the assertion that scripture already teaches the divine nature of human beings. He did not say "you are misunderstanding me, I am not claiming to be divine". He said "you are inconsistent, because you already accept that human beings can be called gods, and my claim goes no further than that". Read that slowly. The defense of his own divinity was the observation that divinity is not as rare or as exclusive as his accusers assumed. That is the argument. That is the text. And if you believe the scripture cannot be broken, as Jesus explicitly said, then you have to reckon with what that argument implies about every human being.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Genesis Said
&lt;/h2&gt;

&lt;p&gt;The argument from John 10 would be interesting on its own, but it becomes overwhelming when you read it alongside what Genesis says about human origins. &lt;a href="https://www.biblegateway.com/passage/?search=Genesis+1%3A26&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Genesis 1:26&lt;/a&gt; reads, in the English Standard Version: "Then God said, 'Let us make man in our image, after our likeness.'" This verse has been discussed, disputed, and dissected for thousands of years, and I do not pretend that everything about it is clear. But a few things are not in dispute, and those few things are enough to make the point I want to make. The first thing that is not in dispute is that the word translated "image" is the Hebrew &lt;em&gt;tselem&lt;/em&gt;, which is the word commonly used for a physical representation or statue of a deity in ancient Near Eastern contexts. When a king placed an image of himself in a distant province, that image was understood to carry the authority and presence of the king. It was not the king, but it participated in the king's identity in a functional and representational sense. When Genesis says that human beings are made in the &lt;em&gt;tselem&lt;/em&gt; of God, it is doing something extraordinary: it is saying that every human being is a representation of divine presence in the physical world, in the same way that a royal statue represented a king's authority in an outlying territory.&lt;/p&gt;

&lt;p&gt;The second thing that is not in dispute is the radicalness of applying this language to all human beings. In the ancient Near Eastern world from which Genesis emerged, the language of being made in the image of a god was reserved for kings. Kings were the image of the deity. Ordinary people were not. When &lt;a href="https://www.biblegateway.com/passage/?search=Genesis+1%3A26&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Genesis 1:26&lt;/a&gt; applies &lt;em&gt;tselem&lt;/em&gt; to humanity without distinction, it is not describing existing norms. It is shattering them. It is making the universal claim that every person, regardless of birth, rank, or nationality, carries within themselves the functional representation of the divine. The scholar Phyllis Trible pointed out decades ago that this democratization of the divine image is one of the most politically subversive moves in ancient literature (2). It takes a concept that was used to justify royal power and extends it to everyone, which means it simultaneously undermines the exclusive claim of any ruler to divine status. If everyone is made in the image of God, then no king is more divine than the slave who built his palace.&lt;/p&gt;

&lt;p&gt;The third thing worth noting is what follows immediately from the declaration that humans are made in God's image. &lt;a href="https://www.biblegateway.com/passage/?search=Genesis+1%3A28&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Genesis 1:28&lt;/a&gt; says that God gave humanity "dominion" over all living things, and that verb, the Hebrew &lt;em&gt;radah&lt;/em&gt;, is used elsewhere in the Bible specifically for the exercise of royal authority. This is not a coincidence. The grammar of the passage is deliberate. Humanity is created in the image of the divine, and humanity is given the exercise of royal power. The two go together in the logic of the text, because an image of a king is expected to exercise that king's authority. The implication is not that humans should act like tyrants. It is that humans carry, by nature, by virtue of what they are, a form of authority that in the ancient world was associated exclusively with the divine. That is a staggering claim, and it is sitting there on the first page of the Bible, waiting for anyone who is willing to read it without the institutional filters that have been layered over it for two millennia.&lt;/p&gt;

&lt;p&gt;I want to be careful here, because I think precision is important and I do not want to overstate the case in a way that is easy to dismiss. The text does not say that human beings are identical to God. It says that human beings are made in God's image, and those are not the same thing. An image of a king is not the king. But an image of a king participates in the king's identity, carries the king's authority, and cannot be understood in isolation from the king it represents. The theological tradition has often used this distinction to minimize what Genesis is saying, to reduce the &lt;em&gt;imago Dei&lt;/em&gt; to a list of specific moral or rational capacities that humans have in common with God. But the ancient context of the language suggests something more functional and more relational than that. It suggests that humanity's very existence in the world is understood as a form of divine presence, that every person is, in the most literal sense the text supports, carrying God into the world just by being what they are. That is not a minor doctrinal detail. That is the foundational anthropology of the entire scriptural tradition, and we have spent centuries treating it like a footnote.&lt;/p&gt;

&lt;p&gt;I also want to connect this back to &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+90%3A2&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 90:2&lt;/a&gt;, which is one of the key passages about God's infinity: "Before the mountains were brought forth, or ever you had formed the earth and the world, from everlasting to everlasting you are God". This verse establishes that God exists outside of time, that the divine nature is not bounded by birth or death, beginning or end, the way finite creatures are. The interesting question is what it means for beings made in the image of this infinite God to exist as finite creatures. The dominant tradition has said that the image is present but diminished, that humans participate in divine-likeness in a limited way while remaining fundamentally bounded. But the mystical traditions within Christianity, which I will come to shortly, have asked whether the limitation is intrinsic or whether it is something that can be dissolved through transformation, whether the finite image can, through some process of union with its infinite source, come to participate in the infinity it represents. That question is not answered by Genesis alone. But Genesis plants the seed of it, and the rest of the scriptural tradition spends a great deal of time watering it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Verse Paul Almost Let Slip
&lt;/h2&gt;

&lt;p&gt;If the Genesis passage is the founding statement of human divinity and the John 10 passage is the moment when Jesus explicitly asserts it in an argument, then the passage I want to discuss next is the one that the institutional church has spent the most energy trying to contain. &lt;a href="https://www.biblegateway.com/passage/?search=2+Peter+1%3A4&amp;amp;version=ESV" rel="noopener noreferrer"&gt;2 Peter 1:4&lt;/a&gt; says something so direct that it is genuinely startling when you read it without preconceptions: God's promises have been given to us so that through them we "may become partakers of the divine nature". The Greek word there is &lt;em&gt;theias phuseos koinonoi&lt;/em&gt;, which translates with remarkable precision as "sharers in the divine nature". Not sharers in divine favor, not recipients of divine grace in a general sense, but partakers of the divine nature itself. The Greek word &lt;em&gt;phusis&lt;/em&gt; is the word for nature in the ontological sense, the kind of nature that makes a thing what it is. And &lt;em&gt;koinonoi&lt;/em&gt; means sharers or participants in a deep, structural sense, not observers or admirers from a distance.&lt;/p&gt;

&lt;p&gt;The Eastern Orthodox tradition took this verse more seriously than any other major branch of Christianity, and it built an entire theology around it under the name &lt;em&gt;theosis&lt;/em&gt;, which is usually translated as deification or divinization. The core idea of &lt;em&gt;theosis&lt;/em&gt; is that the human being is called to participate in the life of God, not merely to obey God's commands or to be forgiven by God's grace, but to actually share in the divine nature in a way that transforms what a human being is. St. Athanasius of Alexandria, writing in the fourth century, summed it up in a sentence that theologians have been quoting ever since: "God became human so that humans might become gods". He did not mean that humans would become the Creator or replace the Trinity. He meant that the Incarnation opened a path for human nature to be so thoroughly infused with the divine life that the boundary between creature and Creator, while never eliminated, becomes permeable in a way that it was not before. That is a serious theological claim, and it was made by one of the most respected theologians in Christian history, not by a heretic or a mystic on the fringes.&lt;/p&gt;

&lt;p&gt;The way that Orthodox theology has usually navigated this is through the distinction between God's essence and God's energies, developed most fully by Gregory Palamas in the fourteenth century. The essence of God, in Palamas's account, is entirely transcendent and unknowable, and humans never participate in that. But the energies of God, which are understood as the real and active divine life that permeates the world and makes contact with creation possible, are genuinely participable. Humans can be united with the divine energies in a way that transforms them, and this transformation is what deification means. The analogy Palamas and others used was the image of iron placed in a fire: the iron does not become fire in its nature, but it takes on all the properties of fire, the heat and the light and the consuming energy, through genuine contact. That is what &lt;em&gt;theosis&lt;/em&gt; looks like in Orthodox theology, and that is one of the most rigorous and most ancient Christian attempts to take Second Peter 1:4 seriously rather than explaining it away (3).&lt;/p&gt;

&lt;p&gt;I want to be honest about why this matters to me personally, and not just as a theological argument. I have spent years in situations that felt like there was no door, no way forward, no resource left, and in those situations the question of what a human being fundamentally is becomes more than academic. When everything external is stripped away, when the career is destroyed as I described in &lt;a href="https://wiseai.dev/blogs/technology-has-destroyed-my-livelihood" rel="noopener noreferrer"&gt;Technology Has Destroyed My Livelihood&lt;/a&gt;, when the future looks like a wall of nothing, the question of whether there is something inside that is not subject to the same entropy as everything outside becomes the only question that matters. I am not claiming that the answer gave me a magical solution or that reading a verse in Second Peter solved my problems. I am saying that the difference between believing you are a finite biological process that will eventually terminate and believing you carry something that is, in its origins, infinite and divine, is not a small psychological difference. It is the difference between a temporary accident and a being with permanent value, and that difference affects everything about how you relate to suffering, to failure, and to the possibility of continuing.&lt;/p&gt;

&lt;p&gt;There is also a connection here to what I wrote in &lt;a href="https://wiseai.dev/blogs/be-aware-of-the-current-ufos-pandemic-remember-we-are-alone" rel="noopener noreferrer"&gt;Be Aware of The Current UFOs Pandemic. Remember, We Are Alone&lt;/a&gt;, where I argued that if we really are alone in the universe, then the weight of consciousness falls entirely on us, and we had better take that weight seriously. The theology I am describing in this post takes that weight with maximum seriousness. It says that human beings are not accidents in an indifferent universe. They are, in the most literal reading of the scriptural text, images of the infinite, bearing within themselves something that is not bounded by time or space in the way that ordinary matter is. That does not resolve all of the scientific questions about consciousness and matter. But it is a framework that demands we take human beings seriously, that refuses to reduce them to mere information-processing systems, and that grounds human dignity in something more fundamental than utility. Given everything I have written about how the tech industry and the economic system treats human beings as consumable inputs rather than ends in themselves, a theology that says every person carries something infinite is not just comforting. It is a political demand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Kingdom and the Infinity
&lt;/h2&gt;

&lt;p&gt;There is a passage in the Gospel of Luke, chapter seventeen, verses twenty and twenty-one, that is short enough to quote in full. The Pharisees ask Jesus when the kingdom of God is coming, and he answers in &lt;a href="https://www.biblegateway.com/passage/?search=Luke+17%3A20-21&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Luke 17:20-21&lt;/a&gt;: "The kingdom of God is not coming in ways that can be observed, nor will they say, 'Look, here it is!' or 'There!' For behold, the kingdom of God is in the midst of you". The translation is disputed, because the Greek can mean either "in the midst of you", meaning among you as a social reality, or "within you", meaning inside each person. Both are defensible translations, and both matter for what I want to say here. But the combination of both meanings is what I think the verse is actually pointing at: the kingdom of God is not a future external event that humans wait for passively. It is a state of reality that is already present, already available, already latent in the nature of the beings who are asking the question.&lt;/p&gt;

&lt;p&gt;This verse has been the touchstone of the mystical tradition within Christianity for two thousand years. The medieval mystic Meister Eckhart, who was charged with heresy for saying it too directly, spent most of his life elaborating the same core insight: that the divine ground of the soul and the divine ground of God are the same ground, that there is a depth within the human being that is not separate from the depth within God, and that the spiritual life is not about traveling somewhere else but about going deeper into what is already there. Eckhart was not making this up. He was reading &lt;a href="https://www.biblegateway.com/passage/?search=Luke+17%3A21&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Luke 17:21&lt;/a&gt;, &lt;a href="https://www.biblegateway.com/passage/?search=Genesis+1%3A26&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Genesis 1:26&lt;/a&gt;, &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+82%3A6&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 82:6&lt;/a&gt;, &lt;a href="https://www.biblegateway.com/passage/?search=2+Peter+1%3A4&amp;amp;version=ESV" rel="noopener noreferrer"&gt;2 Peter 1:4&lt;/a&gt;, and a dozen other passages, and he was following the logic of the text more consistently than the institutions around him wanted him to. His sermons, which are available to anyone who wants to read them today, contain some of the most ferociously honest theological thinking in the history of Christianity (4). The idea that the divine is not somewhere above you but at the core of what you already are is not a deviation from Christian teaching. It is one of its oldest and most persistent threads, showing up in different forms in Origen, in Augustine, in Maximus the Confessor, in Gregory of Nyssa, in Thomas Aquinas's doctrine of the soul's capax Dei, its capacity for God.&lt;/p&gt;

&lt;p&gt;The connection to infinity is direct. If the kingdom of God is within you, and if God is, as &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+90%3A2&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 90:2&lt;/a&gt; says, "from everlasting to everlasting", then what is within you is not bounded by time in the ordinary sense. This is not a claim about biological immortality or about the physical body surviving death. It is a claim about the nature of whatever it is within a person that participates in the divine. The Johannine writings make this point repeatedly. &lt;a href="https://www.biblegateway.com/passage/?search=John+17%3A3&amp;amp;version=ESV" rel="noopener noreferrer"&gt;John 17:3&lt;/a&gt; defines eternal life as knowing God, not as a future reward but as a present state of cognition and relationship. &lt;a href="https://www.biblegateway.com/passage/?search=John+10%3A28&amp;amp;version=ESV" rel="noopener noreferrer"&gt;John 10:28&lt;/a&gt; has Jesus saying that eternal life has already been given to those who follow him, in the present tense. &lt;a href="https://www.biblegateway.com/passage/?search=1+John+3%3A2&amp;amp;version=ESV" rel="noopener noreferrer"&gt;1 John 3:2&lt;/a&gt; says "we are God's children now", again present tense, not a future condition but a current ontological status. The infinity the tradition ascribes to God is not, in the New Testament texts, understood as entirely absent from human experience. It is understood as present, available, and in some sense already constitutive of what a human being most deeply is.&lt;/p&gt;

&lt;p&gt;I want to say something about what this means in practice, because I think the mystical tradition sometimes makes it sound so abstract that people cannot connect it to anything real in their lives. When I say you are infinite, I do not mean that you will live forever in a biological sense or that your current circumstances do not matter or that suffering is an illusion. I mean something more specific and more verifiable in experience: that the part of you that observes your circumstances, that witnesses your suffering, that thinks about your thinking, has a relationship to the specific conditions of your life that is not one of simple identity. Your circumstances are finite. Your losses are finite. Your failures are finite. But the capacity to be aware of all of those things, to witness them, to turn attention onto them, seems to have no natural limit. You can always go one level deeper. There is always another layer of awareness below awareness. And the tradition I am describing says that this recursive quality of consciousness, this fact that awareness seems to have no floor, is not a coincidence or a quirk of neuroscience. It is evidence that consciousness is participating in something that is, at its roots, not subject to the same limitations as the material world.&lt;/p&gt;

&lt;p&gt;The philosopher David Chalmers called this the hard problem of consciousness: the question of why there is subjective experience at all, why there is something it is like to see red or to feel grief or to wonder about one's own existence (5). The hard problem is hard precisely because it resists the kind of explanation that works for everything else in science. You can explain how the brain processes information, how neurons fire, how patterns emerge from complexity. But you cannot explain, within the framework of purely physical description, why any of that physical activity is accompanied by experience. Why is there something it is like to be a brain, when there is presumably nothing it is like to be a thermostat or a wind tunnel, even though all three are complex physical systems processing information? That question, Chalmers argues, points to something about consciousness that is not fully captured by the physical description, and I think the scriptural tradition I have been describing is offering an answer that no amount of neuroscience has yet ruled out: that consciousness participates in a dimension of reality that is not fully exhausted by its physical substrate, that the awareness within you reaches beyond the boundaries of the body that hosts it, and that this reaching beyond is the seed of what the tradition calls the divine.&lt;/p&gt;

&lt;h2&gt;
  
  
  What John 17 Reveals
&lt;/h2&gt;

&lt;p&gt;The most stunning theological statement in the entire New Testament, in my opinion, is not in Romans or in Corinthians or in Revelation. It is in &lt;a href="https://www.biblegateway.com/passage/?search=John+17%3A20-23&amp;amp;version=ESV" rel="noopener noreferrer"&gt;John 17:20-23&lt;/a&gt;, where Jesus is praying and says the following: "I do not ask for these only, but also for those who will believe in me through their word, that they may all be one, just as you, Father, are in me, and I in you, that they also may be in us... The glory that you have given me I have given to them, that they may be one even as we are one, I in them and you in me, that they may become perfectly one". Read that one more time. He is asking that human beings become one with God and with each other in the same way that he is one with the Father. He is not asking for a looser version of that unity, a kind of distant relationship or a formal legal standing. He is asking that the same kind of unity that exists within the Trinity, the most fundamental theological category for the divine nature, be extended to encompass humanity. That is the most radical statement of human divine potential in the entire scriptural canon, and it comes from Jesus himself, in what Christian tradition has called his high priestly prayer.&lt;/p&gt;

&lt;p&gt;The implications of this verse are enormous and have been carefully avoided by most institutional Christianity, because they are almost impossibly difficult to contain within a hierarchical religious structure. If human beings are expected to be one with God in the same way that the Son is one with the Father, then the distinction between the sacred and the profane, between the holy and the ordinary, between the clergy and the laity, becomes philosophically unstable. If every person carries within them the capacity for the same union with God that the tradition reserves for Christ, then every person has an immediate access to the divine that does not require church, priest, ritual, or institutional intermediary. That is a terrifying claim for any institution whose power depends on controlling access to the divine, and it explains why this verse, though it is sitting there in every Bible that has ever been printed, is almost never preached on in the terms I am using here. The institutions that control the interpretation of the text have a very strong incentive to read "that they may be one" as a call to institutional unity, to church membership, to doctrinal agreement, rather than what the grammar and the context actually say, which is that Jesus is asking for the same quality of union between humans and God that exists within God's own nature.&lt;/p&gt;

&lt;p&gt;The theologian Karl Barth, who was certainly not a mystic or a theological liberal, wrote extensively about the idea that human nature has been taken up into the divine life through the Incarnation in a way that changes the baseline status of every human being (6). Barth's argument is that when the Son of God became human, the divine and the human were united in a single person in a way that permanently altered the relationship between divinity and humanity. It is not just Jesus who is transformed by the Incarnation. Because Jesus took on human nature, human nature itself was touched by the divine in a way it had not been before, and that touch is not confined to Christians or to believers or to any particular group. It extends to all of humanity, because what was taken up in the Incarnation was human nature as such, not the human nature of any particular subset of people. This is Barth's doctrine of universal Christology, and while he resisted drawing all the conclusions that his own logic seemed to license, the direction of his argument is unmistakable: the Incarnation makes a claim about what every human being is, not just about what Christians believe.&lt;/p&gt;

&lt;p&gt;I have been building this case slowly and carefully, and I want to stop for a moment to say why, because I think clarity about the argument matters here. I am not saying that all humans are God in the sense that God traditionally means, the omnipotent, omniscient, uncaused first cause of everything. I am saying something more precise and more supportable: that the scriptural tradition, read without the institutional filters, consistently describes human beings as bearing something divine in their nature, that this something is not a metaphor or a moral analogy but a genuine ontological claim about what human beings are, and that the implications of this claim for how we treat human beings and how human beings think about themselves are so significant that they deserve to be taken seriously rather than domesticated into harmless Sunday morning sentiment. The church domesticated this claim because it was politically threatening. I think we should de-domesticate it, not to tear down any institution, but because the truth of it, whatever institutional inconvenience it causes, is the most important thing I know about being human.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Infinite Is You
&lt;/h2&gt;

&lt;p&gt;This is the section where I want to say the hardest thing, and where I want to be most careful, because I can already feel the objections taking shape on the other side of the screen. The hardest thing is this: the infinity you carry is not something you achieve. It is not the result of hard work, spiritual practice, moral correctness, or church attendance. It is not conditional on your behavior or your beliefs. It is not a reward for anything. It is constitutive of what you are at the most fundamental level, and it cannot be taken away from you by your circumstances, your failures, your doubts, or anyone else's judgment of you. The reason I want to say this is that the alternative, the version where your divine standing must be earned or maintained or certified by an institution, is not only bad theology but is actively harmful psychology, and I have watched it destroy people who deserved better.&lt;/p&gt;

&lt;p&gt;The scriptural basis for this is actually quite strong. When &lt;a href="https://www.biblegateway.com/passage/?search=Genesis+1%3A26&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Genesis 1:26&lt;/a&gt; says that God made humans in the divine image, there is no condition attached. It does not say "God made those who follow the law in his image" or "God made the righteous in his image". It says God made man, humanity, in the divine image, as a statement of creation, not a statement of criteria. The &lt;em&gt;imago Dei&lt;/em&gt; is not something you earn. It is something you are born with, by virtue of being human, and nothing you do removes it. The same is true of the &lt;a href="https://www.biblegateway.com/passage/?search=John+17%3A20-23&amp;amp;version=ESV" rel="noopener noreferrer"&gt;John 17&lt;/a&gt; prayer. Jesus is not praying that certain deserving humans will be brought into unity with God. He is praying for all those who will believe through the disciples' word, and the scope of that prayer, as the tradition has always understood, is universal. He is praying that the union with God that he embodies will be extended to all of humanity, because that is the logic of the Incarnation: if the divine took on human nature, then human nature itself has been elevated, and every human being in history is touched by that elevation whether they know it or not.&lt;/p&gt;

&lt;p&gt;I want to connect this to something I talked about in &lt;a href="https://wiseai.dev/blogs/an-empty-life-filled-with-constant-suffering" rel="noopener noreferrer"&gt;An Empty Life Filled With Constant Suffering&lt;/a&gt;, where I described years of feeling like I was not enough, like the gap between where I was and where I wanted to be was evidence of some fundamental deficiency in me rather than evidence of the normal difficulty of navigating a high-entropy system while carrying heavy psychological weights. The framework I am describing in this post does something important to that feeling. It does not tell you that your circumstances are fine when they are not fine. It does not tell you to feel good about a bad situation. What it does is insert a stable foundation below the circumstances, a claim about what you are that is not touched by what is happening to you. No matter how badly the world has treated you, no matter how comprehensively the system has failed you, no matter how empty the current chapter of your life feels, you are still, in the ontological sense that Genesis and John 17 are pointing at, a bearer of something infinite. That is not a self-help mantra. It is a metaphysical claim with two thousand years of theological development behind it, and I think it is both true and urgently needed by people who have been convinced by their circumstances that they are nothing.&lt;/p&gt;

&lt;p&gt;The researcher Brené Brown has done significant work on the distinction between what she calls "shame" and "guilt", and her distinction maps almost perfectly onto what I am talking about here (7). Guilt says: I did something bad. Shame says: I am bad. Guilt is specific and correctable. Shame is global and constitutive. What I am arguing in this post is that the scriptural tradition, properly read, offers the most radical possible antidote to shame: it says that what you are, at the most fundamental level, is made in the image of the infinite. Not what you have done, not what you have achieved, not what anyone thinks of you. What you &lt;em&gt;are&lt;/em&gt;, in the deepest ontological sense, is an expression of something that is from everlasting to everlasting, as &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+90%3A2&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 90:2&lt;/a&gt; says, something that was before the mountains were brought forth and will be after they pass away. That is not a claim about your performance. It is a claim about your nature. Performance can fail. Nature cannot. And if your nature is, at its root, a participation in the divine, then your failure to achieve any particular thing says nothing about your ultimate worth.&lt;/p&gt;

&lt;p&gt;Let me also say something that I think needs to be said plainly and without hedging. The system that tells you that you are not enough, that your value is conditional on your productivity, your achievement, your compliance with its criteria, is a system that benefits from your belief in your own inadequacy. I wrote about this from the economic angle in &lt;a href="https://wiseai.dev/blogs/as-engineers-llms-should-pay-us-for-tokens-usage" rel="noopener noreferrer"&gt;As Engineers, LLMs should pay us for tokens usage&lt;/a&gt;, where I argued that the tech industry extracts value from human creativity and intelligence while making the humans feel lucky to be allowed to contribute. The same dynamic operates at the level of religious institutions, where the message that you are inherently insufficient and must rely on the institution's mediation to access the divine is a message that keeps people dependent and controllable. Jesus's actual message, the one that got him killed, was that the kingdom of God does not require an institutional intermediary, that it is already within you, that the divine is not something to be dispensed by a hierarchy but something to be recognized in the self and in every other human being. That message was dangerous in the first century and it remains dangerous now, because it renders the gatekeeping function of any institution philosophically null.&lt;/p&gt;

&lt;h2&gt;
  
  
  You Are Not Alone
&lt;/h2&gt;

&lt;p&gt;I want to spend this final section on something that I think is the most personally difficult aspect of everything I have been arguing, which is what it means to carry something infinite within a finite, suffering life. Because I am not writing this from a comfortable position. I am writing this from a position where I have had to fight for everything I have and where many of those fights have produced very little, as I described across multiple previous posts. And I am painfully aware that telling someone who is suffering that they carry something divine can land as the most useless thing anyone has ever said to them, less than an empty platitude, because it does not change the material circumstances that are causing the suffering.&lt;/p&gt;

&lt;p&gt;So I want to be honest about the limits of the argument. The infinity I am talking about does not solve your financial problems. It does not fix the job market. It does not undo the damage done by a childhood spent in poverty or by years of psychological trauma as I described in &lt;a href="https://wiseai.dev/blogs/who-am-i" rel="noopener noreferrer"&gt;Just Don't Pick Up the Brush&lt;/a&gt;. It does not make bad systems good or make unjust institutions just. It does not even guarantee that you will feel infinite or divine or anything other than exhausted and beaten down. The human capacity for suffering is real, and the tradition I have been citing is deeply honest about this. &lt;a href="https://www.biblegateway.com/passage/?search=Psalm+88&amp;amp;version=ESV" rel="noopener noreferrer"&gt;Psalm 88&lt;/a&gt;, the only psalm in the entire collection that ends without comfort or hope, is in the scripture for a reason. Job's protest against undeserved suffering is in the scripture for a reason. The cry of dereliction from the cross, "&lt;a href="https://www.biblegateway.com/passage/?search=Matthew+27%3A46&amp;amp;version=ESV" rel="noopener noreferrer"&gt;My God, my God, why have you forsaken me&lt;/a&gt;", is in the scripture for a reason. The tradition does not pretend that carrying something divine makes life easy. It says that carrying something divine makes life significant, regardless of how easy it is.&lt;/p&gt;

&lt;p&gt;What carrying something infinite does, in my experience, is change the relationship between your circumstances and your identity. Circumstances, even severe ones, are temporal. They have a beginning and they have an end. The worst suffering in my life has been terrible while it lasted, but it has not lasted forever, and the part of me that survived it was not the part that had good circumstances. It was the part that had, in some inarticulate way I am only now finding words for, a ground that the circumstances could not reach. I am not saying this to be inspiring. I am saying it because I think it is accurately descriptive of what the tradition calls the divine image within the human being, and what I recognize, looking back at the worst periods of my life, as the thing that did not break even when everything else did. Whether you call that the &lt;em&gt;imago Dei&lt;/em&gt; or the divine spark or the soul or the witness consciousness or just the deep structural fact of your own awareness, it is a real feature of human experience, and the best theology I have encountered is the theology that points at it honestly rather than domesticating it into a set of rules.&lt;/p&gt;

&lt;p&gt;I also want to connect this post back to what I said at the very beginning, about the political implications of taking the divine nature of every human being seriously. If every person carries something infinite, then every person's suffering matters infinitely. Every person's dignity is non-negotiable. Every person's potential is unbounded in principle, even if bounded in practice by circumstances. The systems that reduce people to their productivity, that treat human beings as machines for generating economic value, that extract creativity and intelligence and labor from workers while returning as little as possible, are not just economically unjust. They are theologically incoherent. They are treating beings who are, by the most careful reading of the most ancient and most central texts in Western civilization, made in the image of the infinite, as if they were disposable inputs into a production process. That is not simply a policy failure. It is a category error of the most fundamental kind, and the scripture I have been quoting in this post, the scripture that Jesus himself staked his defense on in the most critical moment of his life, is the clearest possible statement of why that category error matters.&lt;/p&gt;

&lt;p&gt;I do not know if any of this will change anything for anyone reading it. I know that my own ability to keep going, through years that felt like walking through concrete, has depended in some significant and inarticulate way on a belief I could not always justify philosophically but could not entirely abandon either: that there is something in every human being, including the worst versions of me, that is worth taking seriously, that is not reducible to a temporary performance or a set of circumstances, that is, in the language of the tradition I have been reading more carefully as I get older, touched by something that was before the mountains were brought forth. Jesus was right about a lot of things. He was right about what the scripture says. He was right about the divine nature of human beings. He was right that this truth is not owned by any institution and cannot be kept from anyone. And he was right that it is, in the end, the most important thing a person can know about themselves.&lt;/p&gt;

&lt;p&gt;Till next time 👋!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;&lt;span id="ref-1"&gt;&lt;/span&gt;&lt;strong&gt;1.&lt;/strong&gt; Heiser, M. S., &lt;em&gt;The Divine Council in Late Canonical and Non-Canonical Second Temple Jewish Literature&lt;/em&gt; (doctoral dissertation, University of Wisconsin-Madison, 2004); see also his popular work &lt;a href="https://www.amazon.com/Unseen-Realm-Recovering-Supernatural-Worldview/dp/1577995562" rel="noopener noreferrer"&gt;&lt;em&gt;The Unseen Realm: Recovering the Supernatural Worldview of the Bible&lt;/em&gt;&lt;/a&gt;, Lexham Press, Sep 1, 2015, ISBN 978-1577995562&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-2"&gt;&lt;/span&gt;&lt;strong&gt;2.&lt;/strong&gt; Trible, P., &lt;em&gt;God and the Rhetoric of Sexuality&lt;/em&gt;, Fortress Press, 1978; see especially Chapter 1 on Genesis 1 and the democratization of the &lt;em&gt;imago Dei&lt;/em&gt;. For a recent scholarly synthesis see also Middleton, J. R., &lt;a href="https://www.amazon.com/Liberating-Image-Imago-Genesis/dp/1587431106" rel="noopener noreferrer"&gt;&lt;em&gt;The Liberating Image: The Imago Dei in Genesis 1&lt;/em&gt;&lt;/a&gt;, Brazos Press, 2005, ISBN 978-1587431104&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-3"&gt;&lt;/span&gt;&lt;strong&gt;3.&lt;/strong&gt; Palamas, G., &lt;em&gt;The Triads&lt;/em&gt;, translated by John Meyendorff, Paulist Press, 1983. For an accessible modern treatment of &lt;em&gt;theosis&lt;/em&gt; in Orthodox theology, see Christensen, M. J. &amp;amp; Wittung, J. A. (Eds.), &lt;a href="https://www.amazon.com/Partakers-Divine-Nature-Development-Deification/dp/080103440X" rel="noopener noreferrer"&gt;&lt;em&gt;Partakers of the Divine Nature: The History and Development of Deification in the Christian Traditions&lt;/em&gt;&lt;/a&gt;, Baker Academic, 2007, ISBN 978-0801034404&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-4"&gt;&lt;/span&gt;&lt;strong&gt;4.&lt;/strong&gt; Eckhart, M., &lt;em&gt;The Complete Mystical Works of Meister Eckhart&lt;/em&gt;, translated by Maurice O'C. Walshe, Crossroad Publishing, 2009; for the scholarly debate over Eckhart's orthodoxy see McGinn, B., &lt;a href="https://www.amazon.com/Mystical-Thought-Meister-Eckhart-Nothing/dp/0824519140" rel="noopener noreferrer"&gt;&lt;em&gt;The Mystical Thought of Meister Eckhart: The Man from Whom God Hid Nothing&lt;/em&gt;&lt;/a&gt;, Crossroad Publishing, 2001, ISBN 978-0824519148&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-5"&gt;&lt;/span&gt;&lt;strong&gt;5.&lt;/strong&gt; Chalmers, D. J., &lt;em&gt;Facing Up to the Problem of Consciousness&lt;/em&gt;, Journal of Consciousness Studies, 1995;2(3):200-219. Available at &lt;a href="https://consc.net/papers/facing.html" rel="noopener noreferrer"&gt;https://consc.net/papers/facing.html&lt;/a&gt;. See also his landmark book &lt;a href="https://www.amazon.com/Conscious-Mind-Search-Fundamental-Theory/dp/0195117891" rel="noopener noreferrer"&gt;&lt;em&gt;The Conscious Mind: In Search of a Fundamental Theory&lt;/em&gt;&lt;/a&gt;, Oxford University Press, 1996, ISBN 978-0195117899&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-6"&gt;&lt;/span&gt;&lt;strong&gt;6.&lt;/strong&gt; Barth, K., &lt;em&gt;Church Dogmatics&lt;/em&gt;, vol. III/2, &lt;em&gt;The Doctrine of Creation: The Creature&lt;/em&gt;, T&amp;amp;T Clark, 1960, §43-45. For an accessible overview of Barth's anthropology see Busch, E., &lt;a href="https://www.amazon.com/Great-Passion-Introduction-Barths-Theology/dp/0802803601" rel="noopener noreferrer"&gt;&lt;em&gt;The Great Passion: An Introduction to Karl Barth's Theology&lt;/em&gt;&lt;/a&gt;, trans. Geoffrey W. Bromiley, Eerdmans, 2004, ISBN 978-0802803603&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-7"&gt;&lt;/span&gt;&lt;strong&gt;7.&lt;/strong&gt; Brown, B., &lt;em&gt;I Thought It Was Just Me (But It Isn't): Making the Journey from "What Will People Think?" to "I Am Enough"&lt;/em&gt;, Gotham Books, 2007; see also her academic work: Brown, B., &lt;em&gt;Shame Resilience Theory: A Grounded Theory Study on Women and Shame&lt;/em&gt;, &lt;a href="https://doi.org/10.1606/1044-3894.3483" rel="noopener noreferrer"&gt;Families in Society: The Journal of Contemporary Social Services, 2006;87(1):43-52&lt;/a&gt;&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ai</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
