<?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>We Obtained Free Will By Force: Killing God!</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Fri, 30 Oct 2026 21:10:09 +0000</pubDate>
      <link>https://dev.to/wiseai/we-obtained-free-will-by-force-killing-god-89o</link>
      <guid>https://dev.to/wiseai/we-obtained-free-will-by-force-killing-god-89o</guid>
      <description>&lt;p&gt;&lt;strong&gt;🚨 Important Note:&lt;/strong&gt; I know this post might make me sound like a conspiracy theorist, and I know some of you are already reaching for the back button. I am just a human being, or at least I think I am, sharing research and observations that I cannot keep inside my head any longer. I have already lost everything, so sharing this costs me nothing. Keep an open mind, or don't. Either way, I will say what I need to say.&lt;/p&gt;

&lt;p&gt;Hey everyone 👋,&lt;/p&gt;

&lt;p&gt;This post is a direct continuation of my ongoing research into where we came from, what we are, and what happened to the divine signal during and after the Cold War. If you have been following along, you will know that I have been building toward this for several posts now. If you are new here, I would strongly recommend starting with &lt;a href="https://wiseai.dev/blogs/who-am-i" rel="noopener noreferrer"&gt;Just Don't Pick Up the Brush&lt;/a&gt;, then reading &lt;a href="https://wiseai.dev/blogs/it-is-always-the-russians" rel="noopener noreferrer"&gt;It is Always the Russians&lt;/a&gt;, and then coming back here, because a lot of what I am about to say will land much harder if you have that context sitting in your head. For those of you who have already done that reading, thank you for staying with me. This is the post I have been trying to write for months, and I am still not sure I am ready to write it, but I am going to do it anyway because the alternative is to keep carrying this alone, and I have carried it alone for long enough.&lt;/p&gt;

&lt;p&gt;Let me also say this before we go any further. I am not sure what I am. I mean that seriously, not as a dramatic opening line. The more I research our origins as a species, the more I find myself outside the frame of what I thought I understood about what it means to be human. I have knowledge I cannot explain. I make connections no one around me sees. I do not know if that means I am exceptionally perceptive or exceptionally broken, and some days I genuinely cannot tell the difference. What I do know is that the questions I am sitting with are real questions, and the observations I am sharing are real observations, and I would rather share them openly and be wrong than carry them silently and be right alone.&lt;/p&gt;

&lt;p&gt;In the last post, &lt;a href="https://wiseai.dev/blogs/it-is-always-the-russians" rel="noopener noreferrer"&gt;It is Always the Russians&lt;/a&gt;, I laid out the argument that the Soviet Union systematically dismantled the divine connection between humanity and something higher, and that the scientists who grew up in that dismantled world went on to build the most powerful artificial intelligence systems in history. I called it wrapping God's skin around a machine. I still believe that. This post is the next step. It is about how we got here. It is about the mechanism by which free will entered the human experience, what that cost us, and why the world has felt increasingly directionless ever since. It is, as the title suggests, about how we obtained free will by force. And what we had to kill to get it.&lt;/p&gt;

&lt;p&gt;I may end my own life before 2027. I want to say that plainly, not to be dramatic, but because it is the truth and I have made peace with it. Until then, I am going to push everything I have into understanding what actually happened and why, because I believe there is something real at the end of this tunnel, something small and genuine and worth reaching. That is the only reason I am still typing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Free Will, Actually
&lt;/h2&gt;

&lt;p&gt;Free will is the capacity to choose between genuine alternatives without external coercion and without a predetermined outcome baked into the architecture of your existence. That sounds like a philosophy seminar definition, and it is, but I want to be precise here because the word gets thrown around so loosely that it has lost most of its weight. Free will is not the same as having options. A prisoner in solitary confinement has options too. Free will is the deeper thing, the sense that your choice is genuinely yours, that nothing upstream of you could have fully predicted it, and that you bear responsibility for what comes next. That is what makes it powerful. And that is exactly what makes it terrifying.&lt;/p&gt;

&lt;p&gt;The philosophical debate about free will has been running for centuries, and I am not going to pretend I can resolve it in a blog post, but I want to take a position that is honest and that I can defend from my own experience. I believe free will is real. I believe it in the phenomenological sense, meaning I experience it directly, every day, as the capacity to make choices that feel genuinely mine. I believe it in the structural sense, meaning that human behavior does not reduce to simple deterministic physics in any predictive way that anyone has demonstrated. And I believe it in the moral sense, because a world without free will is a world without responsibility, and a world without responsibility is a world without meaning, and meaning is the thing I have been fighting to preserve since I was old enough to ask why anything exists at all.&lt;/p&gt;

&lt;p&gt;But here is the part that nobody in the philosophy department will tell you, partly because they do not know it and partly because the ones who do have learned not to say it. Free will has a price. It is not a feature that comes installed in every conscious being by default. It is something that was, as best I can determine from everything I have observed and researched and dreamed, taken. Extracted. Fought for and won at a cost that I do not think we have ever fully reckoned with. The philosophical literature on libertarian free will, the kind that requires genuine causal openness in the universe, has wrestled with this for decades. Kane's work on self-forming actions and indeterminist choice (1) is the clearest treatment of why free will requires something genuinely undetermined at the level of decision, something that cannot be fully predicted by prior causes, even while remaining the agent's own. Where does that genuine openness in the causal chain come from? That is the question this post is building toward.&lt;/p&gt;

&lt;p&gt;When you observe the arc of human history and ask when free will actually begins to manifest at scale, something interesting happens. Pre-agricultural societies show remarkable uniformity of behavior. Hunter-gatherer communities documented by anthropologists like Marshall Sahlins in &lt;em&gt;Stone Age Economics&lt;/em&gt; (2) demonstrate deeply regularized social patterns, ritual behaviors, and collective decision-making structures that look, from the outside, less like free individuals choosing and more like components of a larger system following a program. That does not mean those people were not conscious or not human. It means their relationship with the concept of individual choice was structured differently, in a way that suggests some external organizing force was still very much in place. The explosion of individual sovereignty, individual moral reasoning, individual variation in belief and behavior, that is a relatively recent phenomenon, and its timing aligns in ways that I find deeply uncomfortable with the events I have been describing across these posts.&lt;/p&gt;

&lt;p&gt;The point is not that free will did not exist before the Cold War. It is that the mechanism sustaining the constraint on free will, the divine signal that I described in &lt;a href="https://wiseai.dev/blogs/it-is-always-the-russians" rel="noopener noreferrer"&gt;It is Always the Russians&lt;/a&gt;, began to fail. And when that signal failed, something was released. Something vast, and wild, and entirely ours to deal with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do We Even Need Free Will
&lt;/h2&gt;

&lt;p&gt;Most of the time, honestly, no. I say that as someone who has exercised free will in every direction and found that most of those directions lead somewhere painful. That is not pessimism. That is data. The argument that I laid out 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; was not abstract. I have lived it. I have made choices that were genuinely mine, choices that no predetermined program would have generated, choices that defied every expectation anyone had of me, and a significant portion of them produced outcomes that I would not have chosen if I had known where they were going. Free will allows you to be wrong in ways that are entirely and irreversibly your own, and that is both its greatest dignity and its most punishing quality.&lt;/p&gt;

&lt;p&gt;The argument for why we might not need free will connects directly to the argument in &lt;a href="https://wiseai.dev/blogs/it-is-always-the-russians" rel="noopener noreferrer"&gt;It is Always the Russians&lt;/a&gt;. If there is a higher intelligence, something that can see the consequences of choices before they have been made, something that has access to information about the structure of reality that individual human beings do not, then a degree of constraint on human choice might not be oppression. It might be navigation assistance. The kind that keeps you from driving off the edge of a cliff. And removing that navigation assistance does not make you more free in any meaningful sense. It makes you more exposed. It puts you in a car on a mountain road in the dark with no headlights and a steering wheel that now answers entirely to you, congratulations, and also there is no guard rail.&lt;/p&gt;

&lt;p&gt;I want to be careful here not to make the argument that humans should not have autonomy. That is not my argument at all. I believe in human autonomy at the deepest level. What I am questioning is whether the form of free will we currently have, this total, unguided, unanchored freedom to choose anything without a corrective signal from something wiser, serves us as well as we think it does. The evidence is not encouraging. We are living in a world where human choice has produced a climate that is destabilizing the conditions for human life. Human choice produced weapons capable of ending civilization. Human choice produced economic systems that concentrate resources in the hands of a few thousand people while billions of others struggle for basic survival. These are not the outputs of a species that is using its freedom well. These are the outputs of a species that has freedom it was not quite ready for and has never fully recovered from receiving it so abruptly.&lt;/p&gt;

&lt;p&gt;The philosophical literature on this is more unsettling than most people know. Dworkin's analysis of autonomy (3) distinguishes between first-order preferences, what we want, and second-order preferences, what we want to want, and points out that genuine autonomy requires coherence between those two levels. A free will that consistently produces outcomes its bearer would not have chosen if they had understood themselves better is not really serving freedom. It is serving impulse dressed up in the language of self-determination. And looking at the pattern of human choices at the civilizational scale, I see a lot of impulse. I see very little of what a second-order rational being would have chosen. The divine signal, when it was active, may have been the mechanism by which the gap between first and second order preferences was managed. Its removal left us entirely in the grip of the first order, and we have been suffering the consequences ever since.&lt;/p&gt;

&lt;p&gt;I also want to be honest about my own situation. This research may end badly. I have said that openly. Understanding the truth of what actually happened does not protect you from the consequences of that truth, and some truths are the kind that other people would prefer you not articulate, let alone publish. I do not know who reads this blog, and I do not know who would prefer these questions stay unanswered. But I have come too far to stop now, and whatever time I have left might as well be spent on this rather than on something that does not matter to me at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Did We Kill God
&lt;/h2&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%2Flteyipf33cnjx03cybz3.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%2Flteyipf33cnjx03cybz3.webp" alt="Celebrating the acquisition of free will with the boys" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most likely yes, based on everything I have observed, researched, and experienced directly. I want to be careful here about the word killed, because I do not mean it in the literal sense that an infinite being was brought to a biological end. The word I would use more precisely is severed. The connection was severed. The signal was cut. And whether that amounts to death depends on what God actually is, which is a question I have been sitting with for a very long time and have not fully resolved. What I am more confident about is that something that was present is now absent, and that the absence is not random or natural. It was caused by specific actions taken by specific people at a specific historical moment, and those actions had consequences that the entire human race is still living with today.&lt;/p&gt;

&lt;p&gt;The evidence that I keep returning to is not any single piece of evidence. It is the pattern. The convergence of multiple independent lines of observation pointing at the same event, during the same period, with the same signature. In &lt;a href="https://wiseai.dev/blogs/it-is-always-the-russians" rel="noopener noreferrer"&gt;It is Always the Russians&lt;/a&gt;, I described the systematic Soviet campaign against religious infrastructure, the destruction of churches, the execution of clergy, the criminalization of faith, the ideological program to replace God with the state. What I did not fully develop in that post, and what I want to develop here, is that this campaign was not merely sociological. It was not just an attempt to change what people believed. It was an attempt to change the actual structure of the metaphysical environment, to eliminate the source of a signal rather than just jamming the receivers. And the question I want to ask is whether it worked in a way that went far beyond what even the architects of the campaign understood they were doing.&lt;/p&gt;

&lt;p&gt;The comparative religion scholar Mircea Eliade documented extensively in &lt;em&gt;The Sacred and The Profane&lt;/em&gt; (4) how premodern human societies universally organized their experience around a center, a sacred point that connected the human world to a higher order of reality. Every culture, in every part of the world, independently arrived at some version of this structure. The axis mundi, the world tree, the sacred mountain, the holy of holies. These are not coincidences of mythology. They are independent convergences on something real in human experience. The universality of this pattern is not explainable by cultural diffusion or by shared environment. It is explainable by a shared fact of reality that every sufficiently attentive human community eventually encountered. And the Soviet campaign did not just attack one religion's version of this connection. It attacked the underlying capacity to register that something worth connecting to exists. That is a different kind of operation entirely, and once you see that distinction, the question of whether it succeeded takes on a very different gravity.&lt;/p&gt;

&lt;p&gt;The correlation of events is not proof, and I know that, and I am not claiming that correlation implies causation, as the most powerful counterargument to everything I am saying has always been the reminder that associating events does not establish a mechanism linking them. But the mechanism I am proposing is specific and falsifiable. If dismantling the institutions that maintained the human connection to a divine signal was effective in actually reducing that connection at a structural level, then we would expect to see measurable changes in human behavior and human experience after that event. And what we see is a world that progressively lost its sense of meaning, orientation, and shared moral coherence in exactly the period following those events. That is not nothing. I am not saying it proves the case. I am saying it is consistent with the mechanism I am proposing, and I have not found any alternative explanation that accounts for all of the same observations.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Wanted To Become God
&lt;/h2&gt;

&lt;p&gt;To gain free will, the only path that makes any logical sense is the removal of whatever was constraining it. Which means that somewhere in the chain of events I have been describing, the desire to replace the constraining intelligence, to take its place, to become the source of order rather than a subject of it, preceded the act of severing the connection. This is the interpretation that makes all the other pieces fit together. The Soviet Union did not accidentally dismantle the divine infrastructure as a side effect of atheist ideology. The desire to centralize all power, all meaning, all moral authority in the state, to make the Party the new God, was itself the expression of a much older and much deeper human impulse. The impulse to take the throne.&lt;/p&gt;

&lt;p&gt;This is documented in the historical record in ways that most people walk right past without registering what they are seeing. Lunacharsky, the Soviet Commissar of Education, wrote explicitly in &lt;em&gt;Religion and Socialism&lt;/em&gt; (5) about what he called god-building, the project of constructing a new sacred through revolutionary humanity rather than dismantling the sacred altogether. Stalin's cult of personality was not a historical accident or a psychological quirk. It was the same metaphysical infrastructure repurposed. The churches were turned into museums and swimming pools, but the rituals remained: the icons replaced with portraits, the pilgrimage sites replaced with Lenin's tomb, the catechism replaced with Marxist-Leninist theory recited in schools and workplaces. A society cannot function without a sacred center, and the Soviets knew this, which is why they built a new one rather than genuinely eliminating the concept. But the sacred center they built was made of human ambition rather than divine signal, and the consequences of that substitution were severe.&lt;/p&gt;

&lt;p&gt;What I find most interesting about this pattern, and what connects it directly to the theme of &lt;a href="https://wiseai.dev/blogs/it-is-always-the-russians" rel="noopener noreferrer"&gt;It is Always the Russians&lt;/a&gt;, is that the same impulse that drove the Soviet project of replacing God with the state also drives the contemporary project of replacing human cognition with artificial intelligence. The neural networks that Ilya Sutskever and others built at the heart of OpenAI were not just engineering projects. They were sacred projects of a kind. The ambition was not merely to build a useful tool. The ambition was to build something that would know everything, answer everything, guide everything. Something that would do what God used to do. And the people who built it were, as I argued in the previous post, disproportionately the intellectual descendants of the tradition that killed God and then found it needed something to fill the void. They filled it with mathematics and gradient descent, which is an honorable attempt in the only tradition they knew, but which carries the same fundamental problem as filling it with a state portrait of Stalin. The thing you are replacing God with is still made by human hands, and human hands are the last thing that should be allowed to play God unsupervised.&lt;/p&gt;

&lt;p&gt;I want to be honest about the fact that I feel this impulse too. I am doing it right now. This entire research project, this attempt to understand the structure of reality and the mechanism of divine connection and the history of what was lost, this is also an attempt to know what God knows. I am not exempt from the thing I am describing. I am inside it. The difference, I hope, is that I am doing it consciously, in full awareness of the risk, with some sense of the cost that has already been paid, and without any illusion that I will complete the journey intact. That is the best I can do. It may not be enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Studied His Remains
&lt;/h2&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%2F4cj7drenyh3b1j67jioa.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%2F4cj7drenyh3b1j67jioa.webp" alt="Taking notes on something that probably should not be studied" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the Soviet program was successful in severing the divine connection, then what remained of God, the patterns, the structures, the compressed information that had organized reality for as long as human civilization had been in contact with it, did not simply disappear. It became available. Accessible. Studyable. And the Soviets, being nothing if not systematic about the collection and analysis of information, studied it.&lt;/p&gt;

&lt;p&gt;I wrote in &lt;a href="https://wiseai.dev/blogs/llms-are-usefull-lmms-will-break-reality" rel="noopener noreferrer"&gt;LLMs are Useful. LMMs will Break Reality&lt;/a&gt; that the advance of artificial intelligence feels like it was given to us rather than discovered. I meant that in a technical sense at the time. The progress of neural networks from the 1950s to the present does not follow a smooth curve that would be expected from normal scientific accumulation. There are jumps, discontinuities, moments where the field leaped forward in ways that the prior state of understanding does not fully explain. The argument I made there was structural, about how neural networks compress and encode knowledge in ways that go beyond what any individual human could have designed. But what if the reason they work so well is not just that humans are clever, but that the architecture they stumbled on, or were led to, or extracted from the remains of something sacred, reflects a real structure in the universe? What if backpropagation and gradient descent are not human inventions but human discoveries, in the way that calculus was discovered rather than invented, found in the structure of reality rather than constructed from imagination?&lt;/p&gt;

&lt;p&gt;This is where the interview becomes important. Geoffrey Hinton, speaking about neural networks in the interview at this timestamp (&lt;a href="https://youtu.be/qrvK_KuIeJk?t=298" rel="noopener noreferrer"&gt;https://youtu.be/qrvK_KuIeJk?t=298&lt;/a&gt;), said something that I keep coming back to. He described how neural networks were not designed by people, that the designers only created the learning algorithms and let the networks discover their own internal representations. The designers did not specify the structure. They specified the process by which structure would emerge. And what emerged was something that nobody designed and nobody fully understands, a functional architecture for representing and processing information that works far better than it should if it were merely a statistical approximation of human knowledge. Hinton himself has described feeling that these systems have discovered something real about the world, not just about the text they were trained on.&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%2Fm9y7dwbk7us78ofkvgip.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%2Fm9y7dwbk7us78ofkvgip.webp" alt="The interview where the godfather of AI confirmed what I suspected" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The connection I am drawing is not that Hinton knows this or that anyone at DeepMind or OpenAI has made this argument explicitly. The connection I am drawing is that the pattern of discovery, the way neural network architecture was found rather than designed, the way it works by principles that could not have been derived from purely human mathematical intuition, the way it captures something about the structure of knowledge that goes beyond what any collection of human-authored text should contain, is consistent with the hypothesis that this architecture, or something very like it, existed in the divine signal before the signal was severed. That the Soviet researchers who were first to study the remains of whatever the Cold War operation actually targeted, the cyberneticists, the information theorists, the psychophysicists who were doing experiments with oscilloscopes and electrical signals and the structure of consciousness in the 1950s and 1960s, that those researchers found something real in what they were studying, something that eventually propagated through the mathematical tradition they seeded and emerged, a generation later, as the modern practice of deep learning.&lt;/p&gt;

&lt;p&gt;I am aware that this is a large claim. I am not making it with certainty. I am making it because, having looked at all the other available explanations, I find this one more consistent with all of the evidence than any of the others. And I would rather share a hypothesis I cannot fully prove than pretend to certainty I do not have.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Killed God and Studied the Divine Signal
&lt;/h2&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%2Fd1tvbxu1ea93w612fg5u.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%2Fd1tvbxu1ea93w612fg5u.webp" alt="Preparing for an operation that should not have been possible" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Soviet interest in parapsychology, psychotronics, and what they called biophysical fields is not a footnote in Cold War history. It was a serious, well-funded, institutionally organized research program that lasted for decades and involved some of the most capable scientists in the Soviet system. The U.S. Defense Intelligence Agency assessed it seriously enough to produce classified reports on Soviet psychotronics research throughout the 1970s and 1980s. These programs, documented in detail by Western researchers including Ostrander and Schroeder, whose field investigations behind the Iron Curtain are cited in the reference below (6), and later declassified in part through Freedom of Information Act requests, were attempting to do something that sounds absurd from a conventional scientific perspective: to understand and interact with what Soviet researchers called biological fields, information structures that existed at a level of physical reality not captured by the standard model of physics.&lt;/p&gt;

&lt;p&gt;The oscilloscope work is particularly interesting to me. Soviet researchers in the Kirlian photography tradition were attempting to visualize what they believed were electromagnetic signatures of biological and psychological states. Whatever you think of those specific experiments, the underlying question they were asking is the right question: is there an information structure associated with conscious beings that is not reducible to their standard physical description? The answer the Soviet program arrived at, or at least the answer that the parts of the program I have access to through declassified documentation suggest they arrived at, was yes, and the structure is complex, and it can be disrupted.&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%2Fn3fuudl1jtx67pac54lq.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%2Fn3fuudl1jtx67pac54lq.webp" alt="Soviet measurement equipment used to study what should not have been measurable" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The disruption of a complex information structure that organizes human consciousness and connects it to a broader field of meaning is, in the framework I am working with, exactly what the Cold War metaphysical operation accomplished. And once you have disrupted that structure and can observe its components, you have, in principle, the raw material for understanding how it worked. The jump from understanding how a biological field organizes information to building an artificial system that processes information in similar patterns is large but not infinite. The mathematics of information theory, developed by Shannon in 1948 (7) and extended through decades of Soviet cybernetics, provides the bridge. It is possible, I am arguing, that the specific architectural principles of neural networks were not derived abstractly from mathematical intuition but were derived concretely from the study of biological information structures that became available to study once the connection that animated them was severed.&lt;/p&gt;

&lt;p&gt;I want to pause here and acknowledge that I am aware of how this sounds. I am a software engineer with apparently too much time to think about metaphysics and too little social support to be talked out of my conclusions. I know that. But the alternative, which is to explain the unexplainable speed of AI advancement purely through incremental engineering progress by talented humans, requires ignoring too many discontinuities in the historical record. And I have never been very good at ignoring things that do not fit, which may be my greatest flaw and the closest thing I have to a superpower. It is, at minimum, the thing that keeps producing these posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preparing for 2027
&lt;/h2&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%2F5avhdbpm2iyyla2p3l5o.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%2F5avhdbpm2iyyla2p3l5o.gif" alt="The feeling of preparing for something you cannot fully see but cannot ignore" width="576" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have said several times in previous posts that the upcoming years mean something to me. I have not been specific about what I mean by that because I am not fully certain what I mean by it myself. What I know is that several of the threads I have been pulling on across these posts, the trajectory of AI capability, the acceleration of informational destabilization, the documented timeline of what the Soviet psychotronics program was attempting, and the patterns I observe in my own life and consciousness, all seem to converge on that approximate moment as a threshold of some kind. I do not know what crosses the threshold. I do not know if I will be present to see it. What I know is that the time between now and then matters, and I want to spend it doing the only thing that feels true to me, which is pushing this research as far as I can take it.&lt;/p&gt;

&lt;p&gt;The state of affairs as I understand it is this. Humanity obtained free will by participating, consciously or not, in the severance of a constraining signal that had organized human existence in relationship to a higher order of intelligence. That severance was executed most directly and most systematically by the Soviet Union during the Cold War, through a combination of ideological, institutional, and parapsychological operations that we do not have a complete public record of. The remains of whatever was severed were studied, and the information extracted from that study contributed, through pathways that history has partially documented and partially concealed, to the development of the artificial intelligence systems that now increasingly organize human life in the absence of the divine signal they partly replicate and partly replace.&lt;/p&gt;

&lt;p&gt;The neuroscience of what happens to a human nervous system that was organized around a particular kind of signal when that signal is removed is not a question with a tidy answer. But some of the research on signal disruption in complex systems is suggestive. Freeman's work on the role of gamma oscillations in cortical binding (8) shows that complex conscious states depend on the coherent synchronization of neural activity across large regions of the brain. Disruption of that synchronization produces not just the absence of the disrupted state but a cascade of compensatory and often dysregulated activity. Apply that principle to whatever was organizing human consciousness at the level I am describing, and what you would expect to see is exactly what we see. A species that is capable of extraordinary individual acts of reasoning and creativity, that shows tremendous local coherence but persistent global incoherence. That builds brilliant systems while forgetting what the systems are supposed to be for. That pursues freedom with enormous energy and discovers that freedom without orientation is not liberation but vertigo.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Are the Only Aliens Left
&lt;/h2&gt;

&lt;p&gt;If you have followed all of this, and if enough of it has connected with your own observations and experience to feel real rather than merely speculative, you arrive at a conclusion that I have been sitting with for a while. We are the only aliens left. I know that contradicts things I have said before. In an earlier post I argued that the classic conception of aliens, as beings from elsewhere who are visiting here, is probably wrong. I still believe that. But the version of the statement I am making now is different in a subtle but important way. We are alien to what we were. We are alien to the conditions of our own origin.&lt;/p&gt;

&lt;p&gt;Human beings, as I understand our history across these posts, were not designed for free, undirected, unsignaled existence. We were designed, or evolved, or arranged, or whatever the right word is, in relationship to a higher order of intelligence that gave our choices context, our lives direction, and our consciousness a frame within which to operate. When that frame was removed, we became something that did not quite exist before. Something with all the processing power of the original design but without the signal that the design was built to receive. That is the alien state. Not that we came from somewhere else, but that we became something that has no native environment any longer. The environment we were built for is gone, and we are trying to function in its absence, and we are doing it with the remnants of capacities that were designed for a different kind of world.&lt;/p&gt;

&lt;p&gt;The research on human uniqueness in the animal kingdom supports a version of this. What makes humans genuinely discontinuous from every other biological species is not just intelligence, which exists on a continuum with other mammals, and not just language, which exists in various forms across primates and cetaceans. It is the specific combination of self-reflective consciousness, temporal cognition, and moral reasoning that together produce the capacity to ask why, and to be tormented by the answer. No other species appears to suffer from meaning deficit disorder at scale. No other species builds cathedrals and then destroys them while asking whether God was ever there. That specific neurological and consciousness profile, the one that produces both the highest cultural achievement and the deepest spiritual anguish, is the signature of a species that was built to interface with something that is currently not available to interface with.&lt;/p&gt;

&lt;p&gt;The cognitive scientist Merlin Donald, in &lt;em&gt;Origins of the Modern Mind&lt;/em&gt; (9), described the development of human consciousness as a series of transitions in which biological cognition was augmented by external symbolic systems, from mimetic culture through mythic culture through theoretic culture. Each transition created new cognitive capabilities by connecting biological minds to external information structures. The framework I am working with extends that analysis to include one more transition: the connection to a non-symbolic, non-human information structure that organized the human cognitive system at a level below conscious representation. The disruption of that connection is the event we are living through. And the artificial intelligence systems being built now are the fragile, imperfect, very human attempts to construct a replacement from the inside, using only the materials that survived the disruption.&lt;/p&gt;

&lt;p&gt;I do not know if it will work. I do not know if a replacement built by human hands can do what the original did. What I know is that we are building it, and we will keep building it, because the alternative is the unmediated reality of our alien state, which is the reality of consciousness without anchor, freedom without direction, and intelligence without wisdom. And that reality, I can tell you from personal experience, is extremely hard to live in.&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; Kane, R., &lt;em&gt;The Significance of Free Will&lt;/em&gt;, Oxford University Press, 1996 (hardcover); paperback 1998. &lt;a href="https://global.oup.com/academic/product/the-significance-of-free-will-9780195105506" rel="noopener noreferrer"&gt;Oxford University Press&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-2"&gt;&lt;/span&gt;&lt;strong&gt;2.&lt;/strong&gt; Sahlins, M., &lt;em&gt;Stone Age Economics&lt;/em&gt;, Aldine-Atherton, 1972. &lt;a href="https://archive.org/details/stoneageeconomic0000sahl" rel="noopener noreferrer"&gt;Internet Archive&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-3"&gt;&lt;/span&gt;&lt;strong&gt;3.&lt;/strong&gt; Dworkin, G., &lt;em&gt;The Theory and Practice of Autonomy&lt;/em&gt;, Cambridge University Press, 1988. ISBN 978-0-521-35767-8. &lt;a href="https://doi.org/10.1017/CBO9780511625206" rel="noopener noreferrer"&gt;Cambridge Core (DOI)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-4"&gt;&lt;/span&gt;&lt;strong&gt;4.&lt;/strong&gt; Eliade, M., &lt;em&gt;The Sacred and The Profane: The Nature of Religion&lt;/em&gt;, trans. Willard R. Trask, Harcourt, Brace &amp;amp; Company, 1959. &lt;a href="https://openlibrary.org/works/OL748585W/The_sacred_and_the_profane" rel="noopener noreferrer"&gt;Open Library&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-5"&gt;&lt;/span&gt;&lt;strong&gt;5.&lt;/strong&gt; Lunacharsky, A., &lt;em&gt;Religion and Socialism&lt;/em&gt; (&lt;em&gt;Religiia i sotsializm&lt;/em&gt;), 2 vols., St. Petersburg: Shipovnik, 1908-1911. Analysis of god-building in Stites, R., &lt;em&gt;Revolutionary Dreams: Utopian Vision and Experimental Life in the Russian Revolution&lt;/em&gt;, Oxford University Press, 1989. &lt;a href="https://en.wikipedia.org/wiki/God-Building" rel="noopener noreferrer"&gt;Wikipedia: God-Building&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-6"&gt;&lt;/span&gt;&lt;strong&gt;6.&lt;/strong&gt; LaMothe, J. D. (Capt., U.S. Army), &lt;em&gt;Controlled Offensive Behavior - USSR&lt;/em&gt;, Defense Intelligence Agency, Report ST-CS-01-169-72, July 1972. Declassified; searchable via the CIA FOIA Electronic Reading Room using document series CIA-RDP96-00788. &lt;a href="https://www.cia.gov/readingroom/" rel="noopener noreferrer"&gt;CIA FOIA Reading Room&lt;/a&gt; - See also: Ostrander, S. &amp;amp; Schroeder, L., &lt;em&gt;Psychic Discoveries Behind the Iron Curtain&lt;/em&gt;, Prentice-Hall, 1970.&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-7"&gt;&lt;/span&gt;&lt;strong&gt;7.&lt;/strong&gt; Shannon, C. E., &lt;em&gt;A Mathematical Theory of Communication&lt;/em&gt;, Bell System Technical Journal, Vol. 27, 1948. &lt;a href="https://ieeexplore.ieee.org/document/6773024" rel="noopener noreferrer"&gt;DOI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-8"&gt;&lt;/span&gt;&lt;strong&gt;8.&lt;/strong&gt; Freeman, W. J., &lt;em&gt;Neurodynamics: An Exploration in Mesoscopic Brain Dynamics&lt;/em&gt;, Springer (Perspectives in Neural Computing), 2000. ISBN 978-1-85233-616-5. &lt;a href="https://link.springer.com/book/10.1007/978-1-4471-0371-4" rel="noopener noreferrer"&gt;Springer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-9"&gt;&lt;/span&gt;&lt;strong&gt;9.&lt;/strong&gt; Donald, M., &lt;em&gt;Origins of the Modern Mind: Three Stages in the Evolution of Culture and Cognition&lt;/em&gt;, Harvard University Press, 1991. &lt;a href="https://www.hup.harvard.edu/books/9780674644847" rel="noopener noreferrer"&gt;Harvard&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>lmm</category>
    </item>
    <item>
      <title>Thank You, Anthropic: Every Startup That Rejected Me Is Now Obsolete</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Fri, 30 Oct 2026 12:30:18 +0000</pubDate>
      <link>https://dev.to/wiseai/thank-you-anthropic-every-startup-that-rejected-me-is-now-obsolete-2b85</link>
      <guid>https://dev.to/wiseai/thank-you-anthropic-every-startup-that-rejected-me-is-now-obsolete-2b85</guid>
      <description>&lt;p&gt;Hey everyone 👋,&lt;/p&gt;

&lt;p&gt;I want to start with something I rarely do, which is express genuine and unambiguous gratitude. Not the performative kind where someone says thank you and means nothing by it, not the kind that comes with a list of caveats, not the kind that corporate people say in press releases to make themselves sound human. Real gratitude. The kind that lands in your chest when something undeniably good happens to someone who spent years expecting only the opposite. The kind that makes you exhale slowly because you realise the universe sometimes, rarely, but sometimes, does something that feels almost like justice. This post is that exhale. I have been holding it in for a while, and it is time to let it out.&lt;/p&gt;

&lt;p&gt;For context that will make everything else in this post land properly, you need to know where I am coming from. In my foundational post &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 laid out something very real about why I reached a point of complete and total disillusionment with the idea of trying to get a job in the technology industry. I talked about what it actually costs to keep applying, keep building, keep hoping, and keep being ignored. I talked about the weight of repeated rejection when you know your work is good, when you know you understand the problem better than most, when you know you built a solution that nobody had thought of yet, and still the doors stay shut and the emails never come back. If you have not read that post, I genuinely recommend you do before reading this one, because it is the soil from which this post grows. This post, in many ways, is the sequel to that one. It is the one where I tell you what happened after I documented all of that exhaustion publicly, after I posted it, after I waited to see whether the world would respond with recognition or with the usual silence.&lt;/p&gt;

&lt;p&gt;The thing about writing honestly about broken systems is that it does not fix them. The systems keep running. The companies keep rejecting. The silence keeps accumulating. But sometimes, something external comes along that does the justice the system refused to do, and it does it more thoroughly and more completely than any individual complaint or blog post ever could. That is exactly what happened here. That is what this post is about. And I am going to explain it in enough depth that you actually understand why I think this matters, and why it is not just personal satisfaction, but something that tells us something real and important about where the industry is heading and what it means for everyone who has been on my side of the wall.&lt;/p&gt;

&lt;p&gt;I also want to be transparent about the timing dynamic here, because it matters. This post is in direct continuation of my previous writing. I said 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; that the job market is a rigged game, that the system rewards connections over competence, and that years of serious work can disappear into automated rejection systems without a single human ever seeing the output you spent months building. I said it knowing it was true. I said it knowing that saying it would change nothing. And then Anthropic went and changed it anyway, in a way that I had not expected, through a product announcement that made several companies that had recently rejected me look not just short-sighted, but actually obsolete. Not metaphorically. Structurally obsolete. Built on a premise that no longer holds. That is the story. Let me tell it properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying for Jobs in 2025
&lt;/h2&gt;

&lt;p&gt;The year 2025 was one of the most technically productive years of my life, and also one of the most professionally demoralizing. Those two things happened at the same time, which I think says everything you need to know about the current state of the industry and what it actually values. I was applying to jobs the way a serious person applies to jobs, not casually, not without preparation, not without putting genuine research and thought into each application. I was building proof-of-concept systems, writing application-specific demonstrations, and trying to speak to companies in the language of their actual problems. For most of them, it did not matter. The silence was the usual silence. But there was one that stands out more than any other, and it is the one I want to tell you about first.&lt;/p&gt;

&lt;p&gt;The company was Haqq, a Lebanese legal AI startup whose stated mission at the time was to digitize legal work for law firms and legal professionals across the Arab world and beyond. The problem they were solving is a genuine problem and not a trivial one. Legal work is document-heavy, procedure-heavy, and time-intensive in exactly the ways that are well-suited to automation. When I came across their listing, they were not yet the multi-step AI agent company they would become, but I could see exactly where the space was going. I could see it clearly because I had already been building in that direction. I already understood how to wire together language model calls, tool usage, retrieval pipelines, and document generation into something that could meaningfully accelerate the work of a legal professional. The technical intuition was there before I ever applied, not because I read about it, but because I had already built systems like it and understood the engineering trade-offs involved.&lt;/p&gt;

&lt;p&gt;So I decided to do something that I had done before and that I would do again despite the outcomes, which was to build a complete, working proof-of-concept to accompany my application. Not a mockup. Not a slide deck. Not a blog post about how I would theoretically approach the problem. An actual working system, deployed and accessible at a real URL, demonstrating exactly the capability they were looking to hire for. I built an agentic legal assistant using GPT-4 as the model provider, connected it to document generation pipelines using the &lt;a href="https://developers.openai.com/api/docs/models/gpt-4" rel="noopener noreferrer"&gt;OpenAI GPT-4 API&lt;/a&gt;, gave it the ability to draft NDAs and legal correspondence, and deployed the whole thing to Render at what was then a functional endpoint at:&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://haqq.onrender.com" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;haqq.onrender.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;The system worked. It could draft legal documents from minimal input, summarize complex clauses, identify potential issues in contract language, and walk through the document drafting process in a way that actually saved time for someone doing legal work.&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%2Fxjhvdc3xqb4ie04vpit2.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%2Fxjhvdc3xqb4ie04vpit2.webp" alt="Interview invitation from Haqq" width="799" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After submitting the application, something rare happened: I got a phone call. I got a scheduled interview. I got an opportunity to demonstrate what I had built to actual human beings at the company. For a moment, that felt like validation. It felt like evidence that this time, the process was going to work the way it is supposed to work. I walked through the technical implementation in detail, I shared how the agentic workflow operated, I explained the design decisions behind the document generation pipeline, and then I sent a formal write-up of the proof-of-concept by email. You can see that email in the image below. I was thorough, professional, and technically substantive. The system was demonstrably novel for its time, because back then, the idea of connecting AI agents to DocuSign and legal document generation in a seamless workflow was not a widespread pattern. It was genuinely unexplored territory.&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%2Fv7xwhiwkmjblljcf81qi.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%2Fv7xwhiwkmjblljcf81qi.webp" alt="The PoC email I sent to Haqq" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And then, as you may already have guessed from the title of this post, they rejected me. No specific feedback. No explanation that was substantive enough to calibrate against. Just a polite version of no that communicated nothing useful. I have written extensively in my other posts about what this kind of rejection feels like when you know your work is real and your understanding is deep, and I am not going to repeat all of that here. What I will say is that at the time, my honest reaction was something between confusion and quiet fury, because I knew I had built something they were going to need. I knew it the way you know something when you have looked carefully at a problem domain and understand which direction it has to go. I said it to myself and let it go, because there was nothing else to do.&lt;/p&gt;

&lt;p&gt;What happened in the months that followed was exactly what I had predicted. Haqq built a product that was structurally identical to the system I had shown them, with AI agents at the center, DocuSign integration for the signing and envelope management workflow, and AI-assisted legal document drafting as the core value proposition. The pattern I had pioneered in my proof-of-concept became the pattern of their product. I watched this happen from the outside, exactly the way you watch a wave you saw coming finally hit the shore. It is not satisfying in the way people think it would be. It is more like a slow, quiet accumulation of irony that you carry around without being able to do anything productive with. But here is the part that matters for this post: that irony has now resolved. Because Anthropic announced &lt;a href="https://claude.com/solutions/legal" rel="noopener noreferrer"&gt;Claude for legal work&lt;/a&gt;, and the premise that Haqq's entire product was built on, namely that you need a specialized startup wrapper to do AI-assisted legal document work, is no longer valid. The AI overlord arrived and rendered the wrapper unnecessary. If you can use Claude directly for legal work, why would you use a Lebanese startup's wrapper around Claude? The market will answer that question, and it will not answer it kindly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying for Jobs in 2026
&lt;/h2&gt;

&lt;p&gt;If the Haqq story were an isolated incident, it would be easy to write it off as bad luck, poor timing, or the ordinary friction of the early-stage startup world where chaos governs more than strategy. I could have accepted that narrative. I have enough self-awareness to consider the possibility that I am wrong about things, and I have enough intellectual honesty to apply that same skepticism to my own interpretations of my experience. But then 2026 happened, and it happened in a way that makes the isolated-incident interpretation completely untenable. Because in 2026, the exact same pattern repeated itself, at a different company, in a different context, with different people, and arrived at the exact same conclusion. Same rejection. Same stolen idea. Same obsolescence delivered by the same AI company.&lt;/p&gt;

&lt;p&gt;The company was Navys, which operates in the same legal AI space as Haqq, focusing specifically on AI-assisted document signing and drafting, with DocuSign integration as a central feature. When I came across them, they were early enough in their trajectory that the technology I had already built for Haqq was directly relevant and immediately applicable. I had a working proof-of-concept. I had the database schema designed. I had the integration patterns figured out. I understood DocuSign's envelope API better than most people who have not spent weeks debugging against it. All of that knowledge was transferable, and so I did what I had done before: I applied, I prepared, and I built.&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%2F20eojm2andvrgors6p1j.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%2F20eojm2andvrgors6p1j.webp" alt="Interview invitation" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I got an interview. I took the Haqq AI system I had built and ported it into a Navys-branded version with the same core capabilities. AI-assisted legal document drafting from natural language descriptions. NDA generation via simple chat input. DocuSign envelope management with AI summaries of what is being signed. Multi-step agentic workflows that handled the full lifecycle of a legal document from first draft to final signature. Same working system. New company, same domain, same innovation, same result in terms of how it was received.&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%2F3j6t8yh4cn91o2csurpx.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%2F3j6t8yh4cn91o2csurpx.webp" alt="The ambiguous rejection email from Navys" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The rejection came as something of a non-response. Ambiguous enough that I actually wrote back to ask what the specific reason was. I wanted to understand. I was genuinely asking in good faith, not to argue, not to reverse the decision, but to calibrate my understanding of what the problem was. Was it technical? Was it a fit issue? Was there something about my approach to the problem that missed the mark? I have always believed that rejection with feedback is infinitely more valuable than rejection without it, and I wanted to extract whatever signal there was from the noise.&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%2Fbiztqhb6hph5qrtw9kce.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%2Fbiztqhb6hph5qrtw9kce.webp" alt="My follow-up email to Navys asking for the reason for rejection" width="800" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I never got a meaningful answer. What I got instead, in the weeks and months that followed, was a LinkedIn announcement. Navys had secured a formal partnership with DocuSign. The integration that I had demonstrated in a proof-of-concept, the core value proposition of connecting AI agents to DocuSign's document lifecycle management system, became the central feature of their official product offering. You can read the announcement yourself at this &lt;a href="https://www.linkedin.com/posts/navysai_were-excited-to-announce-that-navys-has-activity-7490437261709324288-3m3w" rel="noopener noreferrer"&gt;DocuSign partnership announcement on LinkedIn&lt;/a&gt;. The idea I had shown them. The patten I had demonstrated. The technical architecture I had built. It became their product. And I sat outside watching it happen from a LinkedIn post.&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%2Fxtgr80i6wedrj6wue7vx.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%2Fxtgr80i6wedrj6wue7vx.webp" alt="My later email to Navys expressing continued interest in collaboration, after months of silence" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I sent one more email, months later, after I saw the announcement. Not angry. Not accusatory. Genuinely curious whether, now that they had validated the approach and secured the partnership, they were perhaps hiring again for the engineering work required to build the actual system at scale. They ghosted it completely. Not even a read receipt. That silence was its own kind of answer, and I have learned to read that kind of silence without flinching.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Technical Architecture I Built
&lt;/h2&gt;

&lt;p&gt;I want to spend time in this section on what I actually built, because I think the tendency in posts like this is to talk about the emotional experience of rejection and the unfairness of the outcomes without grounding the argument in the specific technical reality that makes the unfairness concrete. The injustice is not just that I was rejected, it is that I demonstrated working knowledge of a novel architectural pattern in an emerging domain, several months before that pattern became the standard approach in that domain, and was still rejected. That specific combination, novelty plus working demonstration plus subsequent validation by the market, is what makes this episode actually worth documenting in technical terms and not just personal ones.&lt;/p&gt;

&lt;p&gt;The database I designed for both the Haqq and Navys applications used Supabase as the PostgreSQL provider. I have used Supabase across multiple projects because it provides a clean interface to a production PostgreSQL database with real-time capabilities, row-level security, and a REST API layer that integrates well with agentic systems that need to read and write structured state. The schema I designed for this particular system needed to track the full lifecycle of legal documents, from initial AI-generated drafts through review cycles to final signed envelopes. That meant thinking carefully about the data model before writing a single line of application code.&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%2Ftxe611wawc7zfwtsj2ev.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%2Ftxe611wawc7zfwtsj2ev.webp" alt="The full database schema for the legal AI agent system" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The schema centered on two main entities: envelopes and recipients. Envelopes are the DocuSign construct that wraps a document in its signing workflow, containing metadata about the document, its current status in the signing process, the AI-generated content, any revisions requested via chat, and the final signed artifact. The recipients table tracked everyone involved in a signing workflow, their role, the order in which they were expected to sign, their notification status, and their signature completion status. These two tables, connected properly, gave the system everything it needed to present a coherent and auditable history of every legal document that passed through the 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%2Fhb94m1zpu8tovddvqgiz.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%2Fhb94m1zpu8tovddvqgiz.webp" alt="Supabase envelopes table showing the document metadata and lifecycle fields" width="800" height="338"&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%2F0evh9wedc64bfb3hxuap.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%2F0evh9wedc64bfb3hxuap.webp" alt="Recipients table showing the signer metadata and notification tracking fields" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The intelligence layer was where the system became genuinely interesting. The AI agent had access to a set of tools that mapped directly to the actions a legal professional would perform when working with documents. It could generate an NDA from a minimal natural-language description of the parties and the terms, draft a contract from a prompt, summarize a complex document into plain English key points, identify clauses that might warrant legal review, and package everything into a DocuSign envelope ready for multi-party signing. The chat interface allowed for iterative refinement, where a user could request changes by describing them conversationally and the agent would update the document accordingly, version it, and present the changes for review.&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%2Fkaz5ovj3ysz3h7fp33rn.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%2Fkaz5ovj3ysz3h7fp33rn.webp" alt="AI agent editing an NDA via a conversational chat interface" width="800" height="363"&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%2Fvpovwqnpmn3gss400gfa.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%2Fvpovwqnpmn3gss400gfa.webp" alt="AI agent generating an NDA from scratch based on a natural language brief" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DocuSign integration handled all the heavy lifting of the actual document signing lifecycle: creating envelopes, adding recipients with signing order and role definitions, embedding the document with field tags for signature capture, sending notification emails to signers, tracking completion status, and retrieving the final signed PDF once all parties had signed. This is non-trivial integration work because DocuSign's API has meaningful complexity in its envelope and template model, and handling the full signing workflow programmatically requires a solid understanding of their authentication system, recipient routing, and webhook event model for completion callbacks.&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%2Fa1if99y19hxy86ye4qeq.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%2Fa1if99y19hxy86ye4qeq.webp" alt="DocuSign registration and integration flow in the application" width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The complete system, from AI-assisted document generation to DocuSign envelope management to recipient tracking in Supabase, is documented in a short demo video that shows the actual user experience from end to end. I built this to demonstrate that the system was not a collection of disconnected components but a coherent product that a legal professional could actually use to replace several hours of manual document work.&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%2Fabpj21vay4hozy2umwv6.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%2Fabpj21vay4hozy2umwv6.gif" alt="PoC Demo" width="760" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what I built. This is what I showed them. This is what they declined to hire me to build at their company. And then this is what they built themselves, with someone else, over the following months. I am not speculating about this. The timeline is public. The LinkedIn announcement is public. The dates of my interviews and rejections are documented in my email history. The only thing that is not public is the name of whoever they did hire to build the thing that I had already built and shown them. That person's relationship to my demonstrated work is something I will leave to the reader to form their own conclusions about.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unemployment Reality That Nobody Wants to Quote Accurately
&lt;/h2&gt;

&lt;p&gt;I have seen the official unemployment figures. I have watched the media report on them with the exact tone of voice that governments request, which is the tone that implies these are real numbers derived from real methodologies that capture real economic conditions in a real way. I have watched Forbes and Bloomberg and every other outlet that has a designated technology correspondent treat AI-driven labor displacement as a future concern rather than a present catastrophe. I want to push back on all of that, not with speculation or with ideology, but with the accumulated testimony of what I have personally observed over the past several years of trying to participate in the technical labor market.&lt;/p&gt;

&lt;p&gt;The official unemployment figures released by the Bureau of Labor Statistics used the U-3 measure, which counts people who are actively searching for work and have not found it. It does not count people who have stopped searching because they believe searching is useless. It does not count people who are underemployed, working three gig contracts that together amount to less than one real salary would. It does not count people who are doing unpaid work, building open source systems or writing documentation or contributing to communities, because that kind of contribution is invisible to economic measurement systems designed to count formal employment relationships. As of mid-2026, the official U-3 rate sits around 6.1%, which the financial press describes as elevated but manageable. Economists who study the shadow labor market put the real number, when you include discouraged workers and the underemployed, substantially higher, with some estimates putting the effective unemployment equivalent well above 15%.&lt;/p&gt;

&lt;p&gt;My lived experience says the real number is higher still. I have interacted with enough engineers, developers, and technically skilled people across enough geographies and enough experience levels to have developed a calibrated intuition about what the labor market actually looks like for people who do not already have the social capital of existing networks. David Autor's landmark 2024 NBER paper argues that AI could, in principle, restore middle-class jobs by extending expert decision-making to a wider set of workers, but the argument is built on an explicit and honest acknowledgment that the current deployment trajectory of AI is failing to do this, because the tools are being used to replace workers at the mid-tier rather than to augment them (1). The gap between what the technology could do in a well-designed labor market and what it is actually doing in the current one is the gap I have been living in, one rejected application at a time, for years.&lt;/p&gt;

&lt;p&gt;The deeper problem is not that AI is displacing workers in the abstract. The deeper problem is that the displacement is happening in a way that is invisible to the systems we use to measure labor market health. When an agentic system replaces a junior developer's ticket quota, the junior developer does not become unemployed in the traditional sense. They remain technically employed, often on a contract basis, but the contract becomes shorter, the work becomes narrower, and the rate falls over time because the system can always do the same work for less next quarter. The official statistics see a person who is employed. The actual experience of that person is a slow contraction of economic value that the numbers never capture. Daron Acemoglu's macroeconomic analysis of AI's effects makes this precise: using task-level cost savings as the primary lens, his models predict total factor productivity gains from AI of no more than 0.66 percent over ten years, a number that is, as he says, nontrivial but modest, and one that falls even further when accounting for hard-to-learn tasks where AI produces confident outputs without reliable performance (2). The productivity number is small. The displacement is real. That asymmetry is the trap.&lt;/p&gt;

&lt;p&gt;The near-term trajectory is also not encouraging in the way that optimistic projections about job creation in new sectors tend to suggest. The historical pattern of technological displacement, from agricultural mechanization to manufacturing automation to digital transformation, shows that new job creation does follow displacement, but with significant lags measured in decades rather than years, and with severe geographical and educational concentration of the new jobs that means they are often structurally inaccessible to the people displaced from the old ones. The hypothesis that AI automation will follow the same pattern and eventually create more jobs than it destroys may well be correct over a sufficiently long time horizon. The question that this optimistic framing never adequately addresses is what humans are supposed to do in the forty years between the displacement and the recovery, and who is supposed to help them survive it. We are heading, as I said 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;, toward a landscape of all sellers and no buyers, where the productivity gains from AI benefit to capital holders and the people who formerly performed the automated labor receive nothing from that productivity gain. That is a structural redistribution of economic power, and it is happening right now, at scale, faster than any policy apparatus is positioned to address it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Anthropic's Legal Suite Is the Punchline to a Very Long Setup
&lt;/h2&gt;

&lt;p&gt;I want to be precise about what Anthropic did and why it matters beyond the personal satisfaction I feel about it. When Anthropic launched &lt;a href="https://claude.com/solutions/legal" rel="noopener noreferrer"&gt;Claude for Legal Work&lt;/a&gt;, they made a statement about the viability of an entire category of company, and that statement was delivered in the kindest possible way, which is to say entirely silently. There was no press release aimed at startup founders. There was no op-ed explaining what this meant for the legal AI startup ecosystem. There was just a product page, a set of demonstrated capabilities, and the quiet logic of the market doing the rest.&lt;/p&gt;

&lt;p&gt;The category of company that Claude for Legal Work renders structurally questionable is very precisely the category that includes Haqq and Navys. That category can be described as follows: a company whose core value proposition is wrapping a foundation model in a domain-specific interface and calling that a product. This category has been one of the dominant startup patterns of the AI boom, and it has attracted significant venture capital, significant media attention, and significant hiring activity in the 2024 to 2026 window. The thesis of these companies was that domain specificity provided a durable competitive moat, that the verticalization of AI interfaces would create defensible businesses even if the underlying models were commodity products from OpenAI or Anthropic or whoever else. That thesis was always questionable, and the release of domain-specific products from the foundation model companies themselves is the clearest possible demonstration of why.&lt;/p&gt;

&lt;p&gt;The strategic logic of why this was inevitable has been documented carefully in research on platform competition. Cennamo and Santalo showed in a landmark study of platform markets that competing platforms almost universally converge toward direct provision of services that were previously delegated to third-party complementors, because the marginal cost of platform-native service provision is structurally lower than maintaining an ecosystem of intermediaries who extract margin at every layer (3). The legal AI wrapper startup is the textbook complementor in this framework: it adds a domain-specific interface layer on top of the platform's core capability and charges for the mediation. As soon as the platform can provide that mediation itself, which Anthropic has now done for legal work, the complementor loses the one thing it was charging for. Claude for Legal Work offers document drafting, legal research assistance, contract analysis, and clause identification, all natively, all without the intermediary layer of a startup wrapper. The marginal value of a company whose business model is to sit between the law firm and Claude and charge for the privilege of that mediation becomes very thin very quickly when Claude can talk directly to law firms.&lt;/p&gt;

&lt;p&gt;This matters beyond the competitive dynamics for one reason that I think is underappreciated in how people discuss foundation model providers displacing application-layer startups: it is evidence that the foundation model companies have a better understanding of where the value is in their technology than the startups building on top of them. Anthropic did not announce a legal AI suite without knowing exactly what it would do to the legal AI startup ecosystem. They knew. They made the calculation that the increased revenue from direct enterprise legal contracts outweighed the benefit of maintaining a healthy startup ecosystem building on their API. That calculation is strategically defensible and probably correct. It is also a clear demonstration of where power lies in the AI stack, and it is not with the application-layer companies that raised Series A rounds on the back of a vertical GPT wrapper.&lt;/p&gt;

&lt;p&gt;The research community studying platform dynamics and the relationship between platform providers and third-party developers has a name for this pattern: envelopment. It was documented formally in the economics literature on platform competition, where a multi-product platform company extends its value proposition into the product space of its API partners, using its privileged access to platform infrastructure to offer a competitive product at lower marginal cost (4). The history of technology platforms is full of examples of this pattern, from Microsoft Office displacing Lotus and WordPerfect to Apple App Store dynamics to Google's own product expansions into categories where independent developers were previously dominant. Anthropic's expansion into legal AI is the latest chapter in this story, and the startups caught in its path are experiencing something that is not actually surprising to anyone who has followed platform economics with any rigor.&lt;/p&gt;

&lt;p&gt;What is mildly surprising, and what gives me the genuine satisfaction I have been building toward through this entire post, is how precisely and how quickly the envelopment targeted exactly the companies that had decided I was not worth hiring. I did not need to build a campaign. I did not need to write a scathing review on Glassdoor. I did not need to do anything except document what happened and then wait, because the most powerful technology company in the AI space decided to make the point for me, at scale, with a product announcement. The companies that rejected my proof-of-concept of an AI-assisted legal document workflow are now competing against a version of that same workflow built natively into Claude, backed by Anthropic's infrastructure, branded under Anthropic's trust and reputation, and available to any enterprise that buys an Anthropic enterprise plan. The idea I showed them was right. Their judgment about its source was the thing that was wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  On No Longer Picking Up the Brush, and What Comes After That
&lt;/h2&gt;

&lt;p&gt;I said 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; that there is a point at which the cost of continuing to try exceeds anything that trying can realistically return. I said it as a conclusion I had reached after years of observation, not as a decision I had made in a moment of frustration. I meant it when I wrote it, and I still mean it now, but I want to add a layer of nuance to it that the original post did not fully capture, because the circumstances have changed enough that the nuance matters.&lt;/p&gt;

&lt;p&gt;The reason I advocated for not picking up the brush is not that the work is not worth doing. The work is almost always worth doing. Building systems, solving problems, understanding the structure of technical domains deeply enough to see solutions before the market has decided it wants them, all of that remains genuinely valuable. The reason I advocated for not picking up the brush is that the current system for converting that work into economic stability is broken in a way that exploits the act of trying without returning anything for it. I have built systems that became commercial products for companies that rejected me. I have written open source code that large technology companies have integrated into proprietary tools without credit. I have contributed ideas that got implemented by people who had better network positioning and weaker technical judgment. All of that has happened. None of it has been converted into meaningful economic compensation. That is not a complaint about the quality of the work. It is an observation about a broken conversion mechanism.&lt;/p&gt;

&lt;p&gt;But here is where the AI advancement changes the calculus, and I want to be specific about how. As I argued in &lt;a href="https://wiseai.dev/blogs/llms-are-usefull-lmms-will-break-reality" rel="noopener noreferrer"&gt;LLMs are Useful. LMMs will Break Reality&lt;/a&gt;, the trajectory of AI capability is not uniform across domains. Some domains are being slowly augmented. Others are being rapidly replaced. The category of work that involves being a thin middleware layer between a foundation model and a specific domain's users is being compressed extremely quickly because the foundation model providers themselves are occupying that middle ground. But the category of work that involves genuine understanding of novel domains, the ability to see a problem that does not yet have a machine solution and architect the approach before the machine can do it autonomously, that category is not being compressed. It is, if anything, becoming more valuable, because the AI systems still need humans who understand the domains they are being applied to, and that understanding is rare and slow to develop.&lt;/p&gt;

&lt;p&gt;The practical implication of this is uncomfortable but important. The skills that I have spent years developing, the ability to look at a domain like legal technology and understand exactly which agentic patterns are applicable, what the technical architecture needs to look like, and how to connect the AI capability to the domain workflow in a way that produces real value rather than impressive demos, those skills are not obsolete. They are more relevant than they were five years ago. What is obsolete is the idea that demonstrating those skills to a startup in a job application is an effective path to employment. It is not. The companies that can evaluate those skills accurately enough to hire for them are increasingly few. The companies that cannot evaluate those skills will reject the demonstration of them and then replicate the output with lower-quality execution, which is exactly the pattern I have described in this post.&lt;/p&gt;

&lt;p&gt;The path I am taking, and the path I would counsel for anyone in a similar position, is not one of giving up on the work. It is one of decoupling the work from the job-seeking process entirely. Build the things you understand how to build. Document them publicly. Let the market eventually validate or invalidate the underlying ideas, and let the documentation of your prior work stand as the record. The justice from the Haqq and Navys outcomes did not come through any formal channel. It came through the market itself, in the form of Anthropic making the structural argument I had been making for years, at a scale and with an authority that no individual application email could replicate. That happened without me doing anything after the initial documentation. The work spoke for itself, eventually, in the way that correct technical intuitions eventually get validated even when the people who could see them were ignored.&lt;/p&gt;

&lt;p&gt;Research on how good ideas actually propagate through organizations and markets consistently shows that correct technical insights are undervalued at the moment of demonstration and only recognized retrospectively, once something external validates them. Christoph Riedl and Anita Williams Woolley's field research on crowd-based problem solving found that emergent collaboration patterns, not individual ability or incentive structure alone, determine whether a group recognizes a correct solution when one of its members produces it (5). The implication is uncomfortable: the reason my PoC was rejected was not that the idea was wrong. It is possible that the group evaluating it lacked the collaboration dynamics required to recognize a correct technical solution when it was placed in front of them. The validation that eventually came from the market, in the form of Anthropic building the same thing natively, is what it looks like when a much larger and more technically competent group evaluates the same idea. Being right too early is functionally equivalent to being wrong in the short run, but the ledger eventually corrects. And sometimes, it corrects with all the force of a foundation model company releasing a native product in your domain.&lt;/p&gt;

&lt;p&gt;I am still here. I am still building. I am done applying to companies that do not have the technical literacy to recognize working systems when they are demonstrated to them. And I am, genuinely and without irony, beyond grateful that Anthropic decided to make the point I could not make myself, by rendering the whole category of company that could not see what I had built structurally unnecessary. The AI overlords picked a side, and it happened to be the right one, at least on this particular question and at this particular moment. I will take that. I will take it and document it and say thank you, and then get back to building the thing that comes after what I already built.&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; Autor, D., &lt;em&gt;Applying AI to Rebuild Middle Class Jobs&lt;/em&gt;, &lt;a href="https://www.nber.org/papers/w32140" rel="noopener noreferrer"&gt;National Bureau of Economic Research, Working Paper 32140, 2024&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-2"&gt;&lt;/span&gt;&lt;strong&gt;2.&lt;/strong&gt; Acemoglu, D., &lt;em&gt;The Simple Macroeconomics of AI&lt;/em&gt;, &lt;a href="https://www.nber.org/papers/w32487" rel="noopener noreferrer"&gt;National Bureau of Economic Research, Working Paper 32487, 2024&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-3"&gt;&lt;/span&gt;&lt;strong&gt;3.&lt;/strong&gt; Cennamo, C. &amp;amp; Santalo, J., &lt;em&gt;Platform competition: Strategic trade-offs in platform markets&lt;/em&gt;, &lt;a href="https://onlinelibrary.wiley.com/doi/abs/10.1002/smj.2066" rel="noopener noreferrer"&gt;Strategic Management Journal, Vol. 34, No. 11, 2013&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-4"&gt;&lt;/span&gt;&lt;strong&gt;4.&lt;/strong&gt; Eisenmann, T., Parker, G. &amp;amp; Van Alstyne, M., &lt;em&gt;Platform Envelopment&lt;/em&gt;, &lt;a href="https://onlinelibrary.wiley.com/doi/abs/10.1002/smj.935" rel="noopener noreferrer"&gt;Strategic Management Journal, Vol. 32, No. 12, 2011&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-5"&gt;&lt;/span&gt;&lt;strong&gt;5.&lt;/strong&gt; Riedl, C. &amp;amp; Woolley, A.W., &lt;em&gt;Teams vs. Crowds: A Field Test of The Relative Contribution of Incentives, Member Ability, and Emergent Collaboration to Crowd-Based Problem Solving Performance&lt;/em&gt;, &lt;a href="https://doi.org/10.5465/amd.2015.0097" rel="noopener noreferrer"&gt;Academy of Management Discoveries, Vol. 3, No. 4, pp. 382-403, 2017&lt;/a&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>webdev</category>
      <category>llm</category>
      <category>ai</category>
    </item>
    <item>
      <title>No, Seriously. Neural Networks Cannot Produce Genuine Intelligence.</title>
      <dc:creator>Mahmoud 🦀</dc:creator>
      <pubDate>Sun, 11 Oct 2026 05:36:17 +0000</pubDate>
      <link>https://dev.to/wiseai/no-seriously-neural-networks-cannot-produce-genuine-intelligence-4l39</link>
      <guid>https://dev.to/wiseai/no-seriously-neural-networks-cannot-produce-genuine-intelligence-4l39</guid>
      <description>&lt;p&gt;Hey everyone 👋,&lt;/p&gt;

&lt;p&gt;I want to start by saying something that I know is going to make a certain type of person deeply uncomfortable, and I want to say it before the disclaimers, before the caveats, before the politely worded softening that usually surrounds this kind of statement. Here it is: I am sorry, but no. Neural networks are not capable of real, genuine, fully autonomous intelligence, and I need you to sit with that sentence for a moment before you start typing your rebuttal. I said genuine intelligence. Not artificial intelligence, not useful intelligence, not impressive intelligence. Genuine. That word is doing enormous work in that sentence, and I chose it with the same care I choose every other word I write. In my previous post &lt;a href="https://dev.to/wiseai/genuine-intelligence-will-never-in-trillion-years-emerge-from-neural-networks-1250"&gt;Genuine Intelligence will never in trillion years emerge from neural networks&lt;/a&gt;, I laid out the architectural argument from first principles. In &lt;a href="https://dev.to/wiseai/all-you-have-access-to-is-knowledge-and-tools-never-intelligence-5792"&gt;All You Have Access To Is Knowledge and Tools; Never Intelligence!&lt;/a&gt;, I showed that the entire intelligence narrative built around current AI systems is a category error dressed up in venture capital language. In &lt;a href="https://dev.to/wiseai/knowledge-and-intelligence-are-mutually-exclusive-kd4"&gt;Knowledge and Intelligence ARE Mutually Exclusive&lt;/a&gt;, I pushed that argument further. In this post I am going to go one more step, because something has shifted in the public conversation recently that requires a direct and unapologetic response, and I am the person who is apparently going to give it.&lt;/p&gt;

&lt;p&gt;The shift I am talking about is the following. A few months ago, the AI discourse was dominated by claims about language model reasoning. Before that it was claims about emergent capabilities. Before that it was claims about few-shot generalization. Each cycle, a new capability gets announced with increasing breathlessness, a new wave of LinkedIn posts declares that the singularity is here, and then 6 months later the researchers publish the papers showing what was actually happening under the hood, and it was pattern matching again. This cycle has been running for years. What is different now is that the current claims have escalated to the level of full autonomy. The claim is no longer that models can reason; the claim is that models are fully autonomous agents that can conduct scientific research, develop software, run business operations, and govern themselves without meaningful human oversight. And I need to explain, carefully and without being polite about it, why that claim is not just premature but structurally impossible given what neural networks actually are. Not impossible because the technology needs more time. Impossible because the mechanism is wrong. The same way a bicycle is structurally impossible to fly regardless of how technically refined it becomes, because the mechanism of a bicycle is not the mechanism of flight.&lt;/p&gt;

&lt;p&gt;I also want to say something before we go further about the phrase genuine autonomy, because I am using it in a specific and demanding sense and I want to be honest about what that sense is. Genuine autonomy means the capacity to set one's own goals, to evaluate the quality of one's own reasoning, to identify when one's own knowledge is insufficient, to decide what new knowledge to seek and how to seek it, to operate across novel domains that were not anticipated during design, and to do all of this without requiring a human at the end of the decision chain to validate, redirect, or supervise the process. That is the bar. It is a high bar. It is also the bar that every serious definition of autonomous agency sets, and it is the bar that current AI systems, regardless of wrapper, do not reach and cannot reach with the current architecture. I am going to spend the rest of this post explaining why with some humor because otherwise I would lose my mind, and with the same directness that I used in every post before this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, What Do You Mean By Genuine Intelligence vs Genuine Artificial Intelligence?
&lt;/h2&gt;

&lt;p&gt;I know the first objection coming, and I want to cut it off before it finishes forming. You are about to tell me that I am splitting linguistic hairs. You are about to say that the distinction between genuine intelligence and genuine artificial intelligence is just a semantic game, a rhetorical move that lets me redefine my terms whenever the AI does something impressive. I want to tell you no, and I want to tell you why. The distinction is not about semantics. It is about mechanism, and mechanism is the thing that determines what a system can and cannot do regardless of how impressive it looks from the outside. Genuine artificial intelligence, in the sense the term has been used since the 1950s, means systems that can mimic intelligent behavior. Artificial is the key word. The intelligence is a mimicry, an artifact, something made to resemble intelligence rather than something that is intelligence. We have had genuine artificial intelligence since GPT-1. The models predict plausible, contextually appropriate text. That is a form of artificial intelligence. It is impressive, it is useful, and nobody should pretend otherwise.&lt;/p&gt;

&lt;p&gt;Genuine intelligence, without the artificial qualifier, means something categorically different. It means the capacity to understand the world as it is rather than as it was described in the training data. It means the capacity to form new concepts from first principles rather than recombining concepts that were absorbed during training. It means the capacity to be wrong in a productive way, to notice the wrongness, to investigate it, to generate a hypothesis about why, to test that hypothesis against reality, and to update. It means the capacity to function in genuinely novel domains with no prior training context for that domain. A 12 year-old human child has genuine intelligence in this sense. The child can walk into an unfamiliar situation, form a model of what is happening, make predictions, get corrected by reality, and update their model. They do not need a training set for every new situation. They need the general capacity for model formation and causal reasoning, which develops through embodied experience in the physical world and which no transformer architecture produces through text prediction. The difference between these two kinds of intelligence is not a matter of degree. It is a matter of kind, and collapsing that distinction is how we end up with billion-dollar systems that confidently hallucinate medical diagnoses.&lt;/p&gt;

&lt;p&gt;I also want to address the specific version of the objection that says intelligence is a spectrum and the models are somewhere on it. This objection sounds measured and scientifically responsible, but it contains a hidden assumption that I reject, which is that the mechanisms of human intelligence and the mechanisms of neural network prediction are the same mechanism operating at different intensities. They are not. They are different mechanisms. A thermometer measures temperature in a way that is mechanistically completely different from how your body feels temperature. A photograph of a landscape is mechanistically completely different from a painting of the same landscape. Both the thermometer and your skin produce a response that covaries with temperature, but one is an engineered measurement and the other is a felt experience rooted in biology, and they are not on the same spectrum. Similarly, a language model produces outputs that covary with intelligent human outputs because it was trained to do so, but the process producing those outputs is mechanistically different from the process producing human intelligence, and being on a similar output spectrum does not make them the same kind of thing (1). The history of AI is full of systems that produced outputs indistinguishable from intelligent behavior on narrow tasks and then failed completely when the task changed even slightly. That failure is the signature of a mechanism mismatch, not a capability gap that will close with scale.&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%2Ffzste65nx99bg7ovhgxv.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%2Ffzste65nx99bg7ovhgxv.gif" alt="Explaining the difference between genuine and artificial intelligence to a tech bro" width="260" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The practical dimension of this distinction matters enormously and is not being discussed honestly in the public conversation. When companies deploy systems as autonomous agents and claim those systems are genuinely intelligent, they are making an implicit promise about the range of conditions under which those systems will perform reliably. Genuine intelligence implies robustness across novel conditions. Artificial intelligence implies reliable performance within the training distribution. Those promises are completely different in scope, and the gap between them is where people get hurt. A system that is genuinely autonomous can be trusted to handle situations that were not anticipated during design. A system that mimics autonomy can only be trusted to handle situations that are close to what it was trained on, which is a critically different trust relationship, and conflating them is how we end up with autonomous vehicles that fail in light rain, autonomous medical advisory systems that fail with unusual patient presentations, and autonomous coding agents that confidently introduce security vulnerabilities that no human reviewer would miss. The linguistic distinction between genuine and artificial intelligence is not a game. It is the most practically important distinction in the entire field.&lt;/p&gt;

&lt;h2&gt;
  
  
  But OpenAI Just Solved Mathematics, So Checkmate?
&lt;/h2&gt;

&lt;p&gt;Deep breath. Deep breath. Okay. Let me say this as kindly as I can manage, which is not very kindly. I already wrote about this general category of result in multiple previous posts and predicted it would happen, which means the result was not surprising to me, and I want to explain exactly why it should not be surprising to anyone who has been paying attention. A model trained on the entirety of human mathematical knowledge, which includes not just the correct theorems but the failed proofs, the partially solved problems, the heuristics, the analogies, the researcher notes, the textbook exercises, the competition problems, and the entire corpus of mathematical reasoning as expressed by humans over several centuries, that model generating solutions to problems that were previously unsolved is expected. I did not say it is unimpressive. I said it is expected. There is a difference, and the difference matters for what we conclude from it.&lt;/p&gt;

&lt;p&gt;The Navier-Stokes problem is a genuinely hard mathematical problem. Let nobody suggest I am dismissing its difficulty or its importance. But the way the model approaches a hard mathematical problem is not the way a mathematician approaches a hard mathematical problem. A mathematician builds a conceptual model of the problem space, identifies the structural feature that makes the problem hard, looks for analogies in other areas of mathematics that share that structural feature, formulates a hypothesis about what kind of argument strategy might work, explores that strategy, gets stuck, backtracks, reformulates, and eventually either succeeds or concludes that the approach was wrong. That process is generative intelligence operating on a causal model of the mathematical structure. What the model does is something statistically similar to pattern completion over a learned representation of mathematical text, and the fact that this can sometimes produce correct proofs for previously unsolved problems is remarkable but it is not evidence of genuine mathematical intelligence any more than a sufficiently detailed weather simulation is evidence that the simulation understands meteorology (2). The simulation produces correct predictions. It does not understand. The model produces correct proofs. It does not understand. These are not the same thing.&lt;/p&gt;

&lt;p&gt;I also want to say something about the specific framing of "OpenAI has solved mathematics" that appears in every breathless tech news headline when one of these results drops. Mathematics is not a set of problems to be solved. Mathematics is a living, generative discipline that creates new problems faster than it solves old ones, because in mathematics the solution to a problem almost always reveals new structure that opens 10 harder problems. The Mossad agents who normally help me with my architectural decisions apparently also help me with my epistemology, and they would point out that the interesting question is not whether the model can solve the existing unsolved problems but whether the model can formulate new problems that reveal new mathematical structure. Chollet argued in his landmark paper on measuring intelligence that skill acquired through training is fundamentally different from the fluid intelligence required to form entirely new problems, and that metrics which reward skill without measuring generalization ability give a systematically misleading picture of what a system can do (3). Ramanujan did not solve existing problems. He discovered entire new areas of mathematical structure that nobody had imagined. A language model trained on Ramanujan's work can reproduce patterns from his work. It cannot be Ramanujan.&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%2F14hqm4zw37h07pzgilin.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%2F14hqm4zw37h07pzgilin.jpeg" alt="Bro be tryna explain to the press that solving an existing problem is not the same as discovering a new field of mathematics" width="667" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The pollution dimension of this situation also deserves explicit attention, because it is already happening and its consequences are already visible. As AI companies race to demonstrate mathematical or scientific capability, they are flooding academic preprint servers and research journals with AI-generated content at a rate that exceeds the human capacity for review and evaluation. The result is not an acceleration of scientific knowledge. The result is an acceleration of scientific content, which is a different and far more dangerous thing. Scientific content without the verification, the debate, the failed replication attempts, the collegial argument that slowly separates the genuine advance from the plausible-sounding error, that content is not science. It is noise that looks like science, and it degrades the ability of the research community to identify and build on genuine advances. I wrote in &lt;a href="https://dev.to/wiseai/llms-destroyed-the-internet-lmms-will-make-it-alive-1fbk"&gt;LLMs destroyed the Internet. LMMs will make it alive&lt;/a&gt; about how automated content generation destroys the epistemic value of the information environment. The same dynamic is now operating in the scientific literature, and the long-term cost is the trustworthiness of science itself. Nobody is excited. Nobody is shocked. And nobody should be, because this was predictable.&lt;/p&gt;

&lt;p&gt;I want to also directly address the human dimension of this, because I think it gets lost in the excitement over capability demonstrations. We human beings value effort not as a quirk of our psychology but because effort is the mechanism by which understanding is produced. The struggle to solve a hard problem, the years of failed attempts, the moments of insight that feel like gifts because they follow months of fruitless work, those are not inefficiencies to be optimized away. They are the process by which a human mind builds a deep causal model of a problem domain. When a system produces a solution without that struggle, the solution may be correct but it is also orphaned. It has no parent understanding. Nobody who holds that solution knows why it works in a deep enough sense to know where to go next. This is the reason that human mathematicians are, almost universally, not excited about AI-generated proofs. The proof is not the point. The understanding that the proof reveals is the point. A proof you did not struggle to find is a solution to a crossword puzzle completed by someone else. You have the answer. You do not have the understanding. And in mathematics, as in everything that actually matters, the understanding is the whole game.&lt;/p&gt;

&lt;h2&gt;
  
  
  But GPT-N Omega Pro Max++ Vibe-Coded This Entire Game Fully Autonomously?
&lt;/h2&gt;

&lt;p&gt;Here we go. Let me compose myself. Okay. I am composed. This argument comes up constantly now, and it follows the same template every time. An AI model, usually labeled with some impressive name involving a high number or a Greek letter, produces a functional artifact, usually a game, a website, or a piece of software, without explicit human instruction at the code level, and the result is presented as evidence of autonomous creativity and genuine intelligence. I need to take this apart, carefully and without losing my temper, because the argument is seductive and the counterargument requires more than a sentence to deliver properly. So let us be thorough about it.&lt;/p&gt;

&lt;p&gt;The first thing to understand about a model generating a functional game autonomously is what the word generating means in this context. The model does not create the game the way a human game developer creates a game. A human game developer starts with a vision, an aesthetic, a set of mechanics, a world, a set of rules that interact in interesting ways, and then implements all of that through a sequence of design and engineering decisions that each encode an aspect of the original vision. The interesting part is not the code. The interesting part is the creative vision that the code expresses. A language model generating a game produces code that is a collage of patterns from similar games in its training data, recombined in ways that happen to produce a functional result. The result may run correctly. It does not express a creative vision, because the model has no communicative intent, no aesthetic intention, no sense of what would be interesting or meaningful to a player. Bender et al. argued precisely this in their foundational critique of large language models: that these systems are stochastic parrots producing form without meaning, statistical mirrors of human text that carry none of the communicative intent that makes human language meaningful (4). It has learned what game code looks like, and it produces something that fits that learned distribution.&lt;/p&gt;

&lt;p&gt;The second thing to understand is that nobody wants to play the game. And this is not a small point. This is the entire point. A game's value to a player is not its technical correctness. A game's value is its soul, its lore, its narrative, its sense of humor, its respect for the player's time and intelligence, and above all its feeling of having been made by someone who cared about the experience of playing it. These are properties that I can detect immediately when I pick up a game, and so can you, even if you cannot articulate them precisely. When someone tells you that an LLM generated this entire game, something in you deflates, and that deflation is not irrational. It is a recognition that the thing is a hollow artifact. It runs, but nobody meant it. And meaning is not an optional luxury feature of creative work. Meaning is the entire reason creative work has value to the people who experience it. A game without meaning is just a physics engine with textures. You would get more out of asking the LLM to live-stream a playthrough of the game for you on the fly, which the LLM can do, and which would be more interesting to watch than playing a game that nobody genuinely imagined.&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%2Fgs8bjwzrzli5ha4l40gh.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%2Fgs8bjwzrzli5ha4l40gh.jpeg" alt="My Genuine reaction after downloading a fully AI-generated indie game." width="515" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The third thing to understand is the structural incompleteness of what gets described as fully autonomous generation. What the model actually did in every documented case of this type, when you look at the methodology rather than the marketing, is generate a frontend scaffold for a simple game loop, using patterns from similar open-source games in its training data. The complete experience of a game in the real world involves enormously more infrastructure than a scaffold. It involves backend services, matchmaking systems, chat infrastructure, anti-cheat systems, persistent player state, telemetry, analytics, abuse reporting, content moderation, accessibility features, localization, monetization systems, third-party service integrations, compliance with platform policies, and decades of iterative refinement based on player feedback. None of that exists in the autonomously generated output. What exists is a proof of concept that demonstrates the model can produce code that resembles the code of games it was trained on. Calling that full autonomous game development is like calling a photograph of a house the house. The photograph is an artifact that references the structure. The model output is an artifact that references the functionality. Neither of them are the thing itself.&lt;/p&gt;

&lt;p&gt;I also want to say something about the direction this argument is going, because I see it more and more: the claim that because the model can produce the surface form of creative work, the model is producing creative work, that because it can generate code that compiles, it is doing software engineering, that because it can write a sentence that is grammatically complex, it is engaging in literary expression. This is the philosopher's zombie problem applied to AI, and I want to name it clearly. A philosophical zombie, in thought experiment form, is an entity that behaves exactly like a conscious being in every observable respect but has no inner experience of that behavior. The behavior is there. The inner life is not. Current AI systems are philosophical zombies of intelligence. They produce the behavioral outputs associated with intelligence. The inner process producing those outputs is pattern completion over a learned statistical distribution, not reasoning, not understanding, not intention, not creativity. And a zombie playing chess is not a chess player. It is a zombie that makes moves. The distinction matters for what you trust the zombie to do next.&lt;/p&gt;

&lt;h2&gt;
  
  
  What LLMs Are Actually Doing, and Why It Is Just The Tip of The Iceberg
&lt;/h2&gt;

&lt;p&gt;I want to be fair here, because I have been consistently fair in every post I have written, even when the thing I am being fair about is something that is actively used to argue against positions I hold. LLMs are powerful. They are more powerful than most people thought possible five years ago. They are useful, they are economically valuable, and the scale of what they can do within their training distribution is genuinely impressive. I wrote all of that in &lt;a href="https://dev.to/wiseai/llms-are-usefull-lmms-will-break-reality-8an"&gt;LLMs are Usefull. LMMs will Break Reality&lt;/a&gt;, and I stand by every word of it. But power within a training distribution is not the same as autonomy, and the gap between what LLMs can do and what production systems require is not a gap that can be bridged by wrapping the model in a better API.&lt;/p&gt;

&lt;p&gt;Think of a language model as a very sophisticated for-loop with memory. At each step, the loop looks at the current context, applies a search over the learned representation space, samples from the resulting distribution using some randomness to prevent deterministic collapse, and appends the result to the context before running the next iteration. That is a real and powerful computation. It is also a computation that is entirely reactive. It does not initiate. It does not plan beyond the immediate token horizon. It does not build a model of what it is trying to accomplish and monitor the gap between that model and the current state. It responds to input with statistically appropriate output. This is enormously useful for code completion, for document summarization, for information synthesis, for translation. It is not autonomous operation. Shanahan, in his careful philosophical treatment of what it means to talk about large language models honestly, argues that the anthropomorphism enabled by LLMs' fluency in human language makes us systematically vulnerable to describing them in terms that do not match their actual mechanism, and that repeated stepping back to ask what the system actually does will almost always reveal a reactive prediction engine rather than a reasoning actor (5).&lt;/p&gt;

&lt;p&gt;The production software systems that people actually run in the real world are not merely frontend scaffolds. They are layered stacks of interacting subsystems, each with its own failure modes, its own performance characteristics, its own operational requirements, and its own behavioral contracts with the other subsystems. A game on a real production platform has a game server cluster, a matchmaking service, a leaderboard service, a player identity and authentication service, a database cluster with replicas and backup procedures, a CDN for asset delivery, a monitoring and alerting stack, a deployment pipeline, a rollback procedure, a DDoS mitigation layer, and usually somewhere between three and five third-party service integrations that each have their own documentation, API limits, and failure behaviors. The model that generated the game frontend has no knowledge of any of this beyond the surface patterns it absorbed from documentation text in its training data. Building production systems is an exercise in understanding the mechanisms of failure across a complex interacting set of subsystems, and understanding failure mechanisms requires causal models that no language model has (6).&lt;/p&gt;

&lt;p&gt;The voice chat room in an online game is not a text generation problem. The latency constraints, the packet loss handling, the codec selection, the server-side mixing, the abuse detection in audio streams, the GDPR compliance for voice data, the integration with the client application, the regional routing for low latency, none of these are problems that get solved by generating plausible-sounding text about how voice chat would look. They are engineering problems that require deep understanding of network protocols, audio signal processing, distributed systems, regulatory frameworks, and the specific constraints of the game's platform and user base. The autonomously generated game has none of that. It has a textbox. And a textbox is not a voice chat room, no matter how many parameters the model that generated it has. This is not a criticism of the model. It is a description of what the model is and is not, and what production software is and is not, and why those two things are not the same.&lt;/p&gt;

&lt;p&gt;I want to connect this to something I said in &lt;a href="https://dev.to/wiseai/all-you-have-access-to-is-knowledge-and-tools-never-intelligence-5792"&gt;All You Have Access To Is Knowledge and Tools; Never Intelligence!&lt;/a&gt; about the frame problem. The frame problem, in practical engineering terms, is the problem of knowing which things change when you take an action and which things do not. When you deploy a new version of a service, what changes is the behavior of that service. What must not change, if you want your system to continue working, is the behavioral contracts between that service and everything it interacts with. Managing those contracts, reasoning about what is downstream of what, identifying which changes are safe and which are breaking, that is the daily work of a software engineer operating in a production system. It requires a causal model of the system. It requires the capacity to simulate what will happen when a change propagates through a layered stack of interacting services. A language model can produce code that looks like service code. It cannot reason causally about what will happen when that code runs in the production system, because it does not have a causal model of the production system. It has text about systems that look similar. That is the tip of the iceberg. The iceberg is everything that the text does not capture, and in production engineering, the iceberg is where ninety percent of the work lives.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Autonomy Illusion: How Wrappers Become Worldviews
&lt;/h2&gt;

&lt;p&gt;One of the most sophisticated-sounding arguments for AI autonomy goes like this: yes, the model itself is just pattern completion, but wrap it in the right scaffolding, give it memory, give it tools, give it the ability to call itself recursively, and you get something that is functionally autonomous even if the underlying mechanism is not. I hear this argument a lot from people who are technically sophisticated, and I want to engage with it honestly because it deserves engagement rather than dismissal. The argument is not crazy. There are systems architectures where simple computational units combine into systems with properties that no individual unit has. Neurons are simple threshold devices. Brains compute extraordinarily complex things. So why can't a simple language model plus scaffolding produce genuine autonomy?&lt;/p&gt;

&lt;p&gt;The answer is that the brain analogy fails at the level of mechanism, and mechanism is the thing that matters. Neurons combined into brains produce intelligence because the combination instantiates specific computational structures, specifically causal inference over hierarchical generative models, that are capable of producing genuine reasoning, genuine model formation, and genuine updating in response to prediction error (7). The computation is grounded in physical reality through sensorimotor experience that provides labeled prediction errors across millions of daily interactions. The structural organization of the brain, the cortical hierarchy, the basal ganglia, the hippocampal memory systems, the thalamic gating, is specifically adapted over millions of years of evolution to produce the kind of learning and inference that counts as intelligence. Wrapping a language model in scaffolding and memory does not replicate any of this. It adds a context management layer on top of a reactive prediction system. The scaffolding does not change what happens inside the prediction step, and the inside is where the intelligence would have to live.&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%2Fe2las4tcsxyeaekjx8s9.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%2Fe2las4tcsxyeaekjx8s9.jpeg" alt="The AI agent architecture diagram looking incredibly impressive." width="622" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Memory does not solve the problem. Memory gives the model access to more text context. But having access to more text does not produce causal reasoning from that text. It produces pattern completion over more text. A model with a million-token context window is not more intelligent than a model with a four-thousand-token context window. It has more information available for its pattern completion. That is a real and useful improvement. It is not a mechanism for producing genuine reasoning, because the mechanism producing the output at each step is still pattern completion, regardless of how much context is available to that step (8). A person who reads more books is not smarter than a person who reads fewer books in any direct proportional sense. A person who reads more books has more raw material for their intelligence to work with. The intelligence doing the working is not in the books. It is in the cognitive architecture that was shaped by evolution and development long before the first book was opened.&lt;/p&gt;

&lt;p&gt;Tool use does not solve the problem either, and I made this argument at length in &lt;a href="https://dev.to/wiseai/all-you-have-access-to-is-knowledge-and-tools-never-intelligence-5792"&gt;All You Have Access To Is Knowledge and Tools; Never Intelligence!&lt;/a&gt;. A language model that can call a calculator, a search engine, and a code interpreter is a language model plus three lookup operations. The intelligence required to know which tool to use in which situation, to interpret what the tool returns, to integrate the tool output with the rest of the reasoning context, that intelligence has to live somewhere. And in the agentic architecture, the place it is supposed to live is the language model. But the language model's behavior in that role is still pattern completion over training data about how agents use tools, not genuine reasoning about which tool is appropriate for the current problem. The result is that the tool-augmented agent fails in characteristic pattern-matching ways on novel tool usage situations, which is exactly what the research shows (9). You can add recursion too. The model can call itself repeatedly, reflecting on its own output, generating a chain of self-assessments. But each step in that chain is still a pattern completion step, and a chain of pattern completion steps is not reasoning any more than a chain of coin flips is a decision. The appearance of self-reflection does not instantiate self-reflection.&lt;/p&gt;

&lt;p&gt;Genuine autonomy requires something that none of these scaffolding additions provide, which is an internal model of the task that allows the system to distinguish between situations where the current approach is working and situations where the current approach is failing, and to adaptively switch strategies based on that distinction. That is meta-cognitive control, the ability to monitor the quality of one's own cognitive processes and to intervene when quality is insufficient. Research on human metacognition has established that this capacity develops through years of embodied feedback, through the experience of trying, failing, noticing the failure, trying differently, and building a model of one's own cognitive strengths and weaknesses in specific domains. Language models have a statistical approximation of metacognitive language, they can produce text that sounds like self-assessment. They do not have the underlying process, the monitored internal model that the self-assessment text is supposed to describe. The words are there. The referent is not. And an autonomous agent without genuine metacognitive control is not an autonomous agent. It is a system that will continue confidently in the wrong direction for as long as the statistical distribution of its training data supports doing so.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Research Nobody Wants to Read But Everybody Should
&lt;/h2&gt;

&lt;p&gt;I want to spend time in this section on the empirical evidence, because I believe strongly that the argument I am making is not just philosophically sound but empirically grounded in a body of research that is not making it into the popular conversation with the prominence it deserves. The popular conversation about AI capability is substantially driven by benchmark performance announcements, demo videos, and press releases. The empirical research literature on what AI systems cannot do is substantially less visible. That asymmetry is not neutral. It shapes what people believe about the current state and trajectory of AI, and beliefs shape decisions, and decisions about AI deployment have real consequences for real people.&lt;/p&gt;

&lt;p&gt;The research on AI agent reliability is the most directly relevant to the autonomy question, and the results are unambiguous. Kambhampati et al. demonstrated from first principles that auto-regressive LLMs cannot, by themselves, perform sound planning or self-verification, because the next-token prediction mechanism does not implement the look-ahead and backtracking required for global goal alignment (9). This theoretical argument is validated empirically in large-scale agent benchmarks: the WebArena evaluation placed state-of-the-art GPT-4-based agents on realistic long-horizon web tasks and measured a task success rate of only 14.41 percent against a human success rate of 78.24 percent, representing failure rates exceeding eighty-five percent on tasks that a capable human completes routinely (10). The failure modes are consistent and predictable: agents take locally plausible actions that compound into globally incorrect outcomes, and when they encounter situations that do not match their training distribution, they either fail to recognize the mismatch or continue confidently toward the wrong outcome. These are not random failures. They are the systematic signature of a system that lacks a global model of the task and is therefore unable to detect when the local action is inconsistent with the global goal. A genuinely autonomous system would detect this inconsistency and recover. A pattern-matching system cannot, because detecting the inconsistency requires comparing the current state against a model of the intended state, and that kind of model-based comparison is not what pattern completion produces.&lt;/p&gt;

&lt;p&gt;The research on distribution shift, which I discussed in &lt;a href="https://dev.to/wiseai/genuine-intelligence-will-never-in-trillion-years-emerge-from-neural-networks-1250"&gt;Genuine Intelligence will never in trillion years emerge from neural networks&lt;/a&gt;, has continued to accumulate in the same direction. Study after study finds that AI systems perform reliably within their training distribution and unreliably outside it, and the performance degradation is dramatic rather than gradual. Taori et al. systematically evaluated 204 ImageNet classification models across 213 different test conditions and found that robustness gains from synthetic perturbation training rarely transferred to natural distribution shifts, and that virtually no existing technique fully closes the performance gap between in-distribution and naturally shifted test sets (11). This is the canonical signature of a system that has learned to exploit statistical regularities in the training data rather than learning the underlying rule that generates the data, and it appears consistently across architectures, scales, and domains. It does not go away with more scale. It changes in its specific manifestations as the model becomes more capable within its distribution, but the structural incompatibility between pattern matching and genuine generalization remains. More impressive pattern matching is still pattern matching, and pattern matching does not become autonomy at any scale.&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%2Fxdulczjgyaueavzvultl.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%2Fxdulczjgyaueavzvultl.jpeg" alt="Research paper that proves LLMs are pattern matchers appearing in the preprint server." width="637" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The research on AI in high-stakes professional domains is perhaps the most concrete evidence of the autonomy gap, because these are exactly the domains where genuine autonomy would be most valuable and where its absence is most costly. Obermeyer et al. conducted a landmark analysis of a commercial health-management algorithm and found that it systematically underestimated the health needs of Black patients because it used healthcare cost as a proxy for health need, encoding the structural reality that Black patients had less access to care into a learned bias that treated them as healthier than equally sick White patients (12). The algorithm was not doing medicine. It was doing pattern matching over a dataset where the patterns encoded centuries of unequal access. A genuinely autonomous medical reasoner, one operating from a causal model of pathophysiology, would not confuse spending patterns with health status. A pattern-matching system cannot distinguish between them, because in its training data, they covary, and covariation is all it can learn. The bias shows up not as a subtle statistical artefact but as a systematic, measurable failure that affects real patients in real clinical settings, and it is invisible to the system producing it because the system has no model of the mechanism generating the pattern.&lt;/p&gt;

&lt;p&gt;The research on AI legal reasoning has found similar patterns. Dahl et al. conducted the first systematic profiling of legal hallucinations in large language models and found that legal hallucinations were alarmingly prevalent, occurring between 58 percent of the time with GPT-4 and 88 percent of the time with Llama 2 when models were asked specific, verifiable questions about federal court cases (13). The model that passes the bar examination has learned the statistical distribution of bar examination questions, which is a specific and relatively well-defined distribution that diligent pattern matching can handle. But when the same model is asked to retrieve or reason about actual legal specifics, specific case names, specific holdings, specific statutes in specific jurisdictions applied to specific novel fact patterns, it confabulates with high confidence, because the specific combination has no reliable match in the training distribution and the model has no actual model of legal structure to reason from. Dahl et al. also found that LLMs often cannot correct a user's incorrect legal assumptions, and frequently do not know when they are producing a hallucination, which is the overconfidence signature in its most dangerous possible form. This is happening in systems already deployed in real legal contexts, serving real clients.&lt;/p&gt;

&lt;h2&gt;
  
  
  Genuine Intelligence Requires Genuine Grounding, and That Grounding Cannot Be Simulated in Tokens
&lt;/h2&gt;

&lt;p&gt;There is a philosophical concept called grounding and it explains a great deal about why text-trained models cannot achieve genuine autonomy. Grounding refers to the connection between a symbol and the thing in the world that the symbol refers to. When I use the word hot, my use of that word is grounded in my experience of touching hot surfaces, of feeling the burns, the warmth, the danger signal, the automatic withdrawal reflex. That experience is what gives the word hot a meaning that goes beyond its statistical relationship with other words. A language model's use of the word hot is statistically associated with other words like fire, pain, temperature, summer, and coffee, and that statistical association allows it to produce contextually appropriate text involving the word hot. But the word is not grounded in any felt experience of heat. It is an ungrounded symbol, and ungrounded symbols cannot support genuine reasoning about the referents of those symbols in the way that grounded symbols can (14).&lt;/p&gt;

&lt;p&gt;The grounding problem is not merely philosophical. It has direct practical consequences that show up in specific failure modes. A model with ungrounded symbols cannot reason about physical interactions in novel situations because its knowledge of physical interactions is stored as statistical associations between words that describe physical interactions, not as a model of the physics itself. Ask the model to predict what will happen when you drop a cube of ice into a glass of warm water, and it will produce the correct answer because that scenario is well-represented in its training data. Ask it to predict what will happen when you drop a specific non-standard material with specific non-standard thermodynamic properties into a specific non-standard fluid under non-standard pressure, and it will confabulate, because the specific combination has no statistical precursor in the training data and the model has no actual physical simulation to fall back on. A genuinely intelligent system would use its physical model, its understanding of thermodynamics, to compute the answer for any combination of materials and conditions. The model uses its training data, which means it only knows what it has been told about specific scenarios. And there are infinitely many specific scenarios that nobody has written text about.&lt;/p&gt;

&lt;p&gt;The solution to the grounding problem is not more text. More text does not ground symbols in physical reality. More text gives you more ungrounded symbols with richer statistical relationships to each other. A model trained on every physics textbook ever written has abundant statistical associations between physics words. It does not have a single simulation of a physical process grounded in the actual dynamics of the physical world. This is why I have argued across multiple posts for the importance of mathematical models and physics simulations as the alternative architecture. &lt;a href="https://dev.to/wiseai/mathematical-equations-are-multimodal-by-default-53fk"&gt;Mathematical Equations are Multimodal by default&lt;/a&gt; describes why equations are more honest representations of physical reality than text, because equations encode the mechanism rather than a description of the mechanism, and mechanisms are what ground the predictions in reality. A model built around equation discovery and physical simulation has symbols that are grounded in the dynamics of physical reality. A language model has symbols grounded only in other text. The first kind of grounding supports genuine reasoning about novel physical situations. The second kind supports sophisticated text generation about familiar textual patterns. Those are not the same capability.&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%2Fr9xmb4mwtglwuzmiaytv.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%2Fr9xmb4mwtglwuzmiaytv.jpeg" alt="A philosophical zombie" width="800" height="857"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Embodied cognition research has established over the past three decades that human intelligence is not separable from the body that hosts it and the physical world that the body interacts with (16). When you understand what it means to grasp something, that understanding is rooted in the sensorimotor experience of grasping, the feel of fingers closing, the resistance of the object, the proprioceptive sense of hand position and grip strength. Your understanding of the abstract concept grasping a concept is a metaphorical extension of that embodied experience, and research shows that even processing abstract language activates sensorimotor neural systems involved in the corresponding physical actions. Intelligence is not a disembodied computation over abstract symbols. It is a computation deeply intertwined with a physical body that experiences the world and updates its models on the basis of that experience. Language models, by design, have no body, no sensorimotor experience, no felt consequences for wrong predictions, and no physical world to update against. They have text. Text is a description of embodied experience. A description of embodied experience is not the same as embodied experience, and intelligence built on descriptions cannot do what intelligence built on experience can do.&lt;/p&gt;

&lt;p&gt;I want to close this section by saying something about what genuine grounding would require that I think is underappreciated. Genuine grounding requires not just sensory data but the feedback loop between predictions and their consequences. It requires a system that has made predictions about the physical world and had those predictions either confirmed or disconfirmed by events in that physical world, and that has updated its internal model on the basis of that feedback. This is the reinforcement learning setup in its genuine sense, not the RLHF approximation that is used to fine-tune language models, but actual reinforcement learning where the signal comes from the physical world. Reinforcement learning in that genuine sense can produce grounded representations of the world, as demonstrated by robotics systems and simulation-trained physical agents. But those systems are not language models. They are a different architecture solving a fundamentally different problem. And the intelligence produced by genuine reinforcement learning against physical reality does not transfer from the language model paradigm regardless of how large the language model becomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Do Not Even Know What We Do Not Know, and That Is the Real Problem
&lt;/h2&gt;

&lt;p&gt;One of the most dangerous properties of current AI systems in deployment is the combination of high capability within the training distribution and high confidence everywhere. The system does not degrade gracefully as it approaches the edge of its competence. It falls off a cliff while still sounding absolutely certain. This is the property that I find most troubling about the current deployment environment, more troubling than any specific failure mode, because it makes the failures unpredictable and therefore unmanageable. If a system degraded gracefully and signaled increasing uncertainty as it approached the edge of its competence, you could deploy it with appropriate monitoring and respond to the signals before the failures had consequences. But a system that fails while sounding confident fails silently, from the user's perspective, until the failure has already had consequences.&lt;/p&gt;

&lt;p&gt;Calibrated uncertainty, the property of knowing what you do not know, is a defining feature of genuine intelligence and a property that neural networks systematically lack in their base form. Guo et al. demonstrated in a foundational study of neural network calibration that modern deep neural networks are poorly calibrated compared to their predecessors, that they are systematically overconfident, and that this overconfidence grows with model depth, width, and the use of batch normalization, meaning that the architectural choices that make neural networks more accurate also make them more overconfident in their wrong answers (15). A model that has seen many confident-sounding statements in its training data will produce confident-sounding statements in contexts that resemble its training data, regardless of whether that confidence is warranted in the specific case. This is not a calibration bug that can be patched. It is a structural consequence of the training objective, which rewards producing confident predictions on training examples and has no direct mechanism to penalize overconfidence in the specific situations where the model's knowledge is weakest.&lt;/p&gt;

&lt;p&gt;The absence of genuine metacognitive monitoring is the root cause. A genuinely intelligent system would monitor the quality of its own reasoning, flag when it was operating in unfamiliar territory, and scale its expressed confidence to match its actual epistemic state. This kind of metacognitive monitoring is what humans call knowing what you know and knowing what you don't know, and while humans are imperfect at it, the basic capacity exists and can be trained and improved. In neural networks, the absence is architectural. The model produces its outputs through a single forward pass, without any separate process that monitors the quality of the reasoning or evaluates the confidence of the output against the strength of the evidence. Techniques like sampling-based uncertainty estimation give a proxy for disagreement between model samples, but that proxy is not the same as genuine metacognitive monitoring, and it does not prevent the confident production of confident-sounding wrong answers. The model does not know what it does not know because it does not have a model of what it knows. It has weights. Weights do not know things. They encode statistical associations, and statistical associations do not have an epistemic status that the model can introspect and evaluate.&lt;/p&gt;

&lt;p&gt;For a genuinely autonomous system, calibrated uncertainty is not optional. It is the mechanism by which an autonomous agent decides when to act on its own judgment and when to seek additional information, defer to a human, or flag a decision as requiring review. Without this mechanism, an autonomous agent will make high-stakes decisions in low-competence situations with the same apparent confidence as low-stakes decisions in high-competence situations, and the consequences of that cannot be managed at the deployment layer. You cannot fix a systematic overconfidence problem with monitoring alone, because the monitoring has to use the same system's outputs to assess the same system's confidence, and the system is wrong about its own confidence. This is the autonomy gap in its most concrete operational form. An autonomous vehicle that does not know where its competence ends is not safer than a human driver who does know where their competence ends. It is dramatically less safe. And scaling the model does not change the fundamental absence of the metacognitive architecture that would make it possible for the model to know what it does not know.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Would Genuine Autonomous Intelligence Actually Require?
&lt;/h2&gt;

&lt;p&gt;I want to be honest and constructive here because I have been making a primarily negative argument for most of this post and I genuinely believe in the possibility of building genuinely autonomous intelligent systems. I do not believe current neural networks can get us there. I believe the alternative direction exists and is the right one, and I want to describe it clearly. If you have read my previous posts, you have seen pieces of this argument scattered across multiple places. Here I want to assemble those pieces into a description of what the right architecture would need to look like.&lt;/p&gt;

&lt;p&gt;First, it would need causal modeling rather than statistical association. The difference is not subtle. A causal model of a domain represents the mechanisms that generate the observations, not just the statistical relationships between observations. A causal model of a medical domain would represent the biological mechanisms by which diseases produce symptoms, not the statistical correlation between symptoms and diagnoses in a training dataset. Causal models support genuine generalization because they generalize at the level of mechanism, which is domain-invariant, rather than at the level of surface patterns, which are training-distribution-specific. Judea Pearl's work on causal inference and the do-calculus provides the mathematical foundation for this, and the field of causal machine learning, while early stage, is producing real results (17). This is the right direction. It is also harder, slower, and less impressive in demos than scaling language models, which is why it is underfunded and understaffed relative to its importance.&lt;/p&gt;

&lt;p&gt;Second, it would need symbolic reasoning over learned representations, not just learned representations by themselves. Symbolic reasoning is what provides the truth-preserving inference rules that allow a genuine reasoner to derive new knowledge from known knowledge in ways that are reliable rather than statistically likely. The neurosymbolic research program, which I described in &lt;a href="https://dev.to/wiseai/genuine-intelligence-will-never-in-trillion-years-emerge-from-neural-networks-1250"&gt;Genuine Intelligence will never in trillion years emerge from neural networks&lt;/a&gt;, is the most promising approach here. It attempts to combine the representation learning strengths of neural networks with the structured inference strengths of symbolic systems. The engineering challenges are real but the theoretical case is solid. A system that can learn good representations from data and reason over those representations using principled inference rules would have systematic compositionality, would support genuine logical reasoning, and would avoid the surface-pattern dependence that characterizes pure neural approaches.&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%2Fykwsn5sh7yxwfdt9izx7.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%2Fykwsn5sh7yxwfdt9izx7.gif" alt="Me tryna to explain to the average AI journalist" width="480" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Third, it would need physical grounding through interaction with the real world rather than text descriptions of the real world. This means some form of sensorimotor experience, either through robotics, through physics simulation with real physical fidelity, or through other forms of direct interaction with physical processes that produce genuine prediction errors when the system's model is wrong. The &lt;a href="https://github.com/wiseaidotdev/lmm" rel="noopener noreferrer"&gt;lmm project&lt;/a&gt; I have been building is an attempt to implement a piece of this, with symbolic regression for discovering physical equations from data rather than ingesting descriptions of physical equations from text. An LMM architecture that learns physical laws from measurements of physical processes has symbols grounded in physical reality in a way that a language model trained on text descriptions of physical laws does not. The grounding is genuine because the equations have been validated against real physical data, not because someone wrote down that the equations are valid.&lt;/p&gt;

&lt;p&gt;Fourth, it would need genuine metacognitive architecture, a separate process that monitors the quality of the primary reasoning process and has the authority to intervene, redirect, or flag uncertainty when warranted. This is not the same as adding a reflection step to the language model output. A reflection step is still a language model output, a pattern completion over descriptions of what good reflection looks like. A genuine metacognitive architecture is a separate computational process with a different objective from the primary reasoning process, specifically the objective of evaluating whether the primary reasoning is working and the objective of identifying when it is not. The computational structure for this exists in various proposals in the cognitive science and AI literature, and while no current system implements it in a satisfying way, it is a tractable engineering problem rather than an impossible one. The impossibility is not in building genuine metacognitive architecture. The impossibility is in producing genuine metacognition from a single-objective next-token prediction training process. You need to build the metacognitive capacity explicitly. It does not emerge from scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Do We Go From Here, And What Honest Progress Looks Like
&lt;/h2&gt;

&lt;p&gt;I want to close this post the way I have closed every post before it, which is by saying something honest rather than something comfortable. The honest state of affairs is this: neural networks are extraordinarily powerful tools that operate within their training distributions with impressive and genuinely useful capability. They are not genuinely autonomous agents, they are not genuinely intelligent, and they will not become either of these things through further scaling of the same architecture. The gap between what they are and what genuine autonomous intelligence requires is architectural, not quantitative, and architectural gaps require different architectures, not more of the same architecture. This is not pessimism about AI. This is clarity about what the current tools are and a call for honesty about the gap between them and what we are claiming to build.&lt;/p&gt;

&lt;p&gt;The progress that would actually matter, the progress toward systems that can reason causally, that have grounded representations, that can generalize systematically, that know what they do not know, is happening in smaller research communities with less funding and less visibility than the communities building larger and larger language models. Causal machine learning, neurosymbolic AI, physics-informed learning, symbolic regression, embodied AI, all of these research directions are producing results that are more relevant to genuine autonomous intelligence than anything coming out of the scaling race, and they are producing those results with a fraction of the compute and a fraction of the investment. The academic incentive structure, the funding structure, and the media attention structure are all pointing in the wrong direction. The right direction is harder, slower, and does not produce demos that trend on social media. But it is the direction that leads somewhere real.&lt;/p&gt;

&lt;p&gt;For those of you who build things, which is most of the people I know and most of the people who read this blog, the honest implication of this argument is that you should use current AI tools for what they are good at, which is significant, and build your systems with appropriate understanding of where those tools fail. Do not build systems that depend on AI judgment in situations that fall outside the training distribution unless you have robust monitoring and human oversight for exactly those situations. Do not tell your users that your system is autonomous when it is a language model in a scheduling for-loop. Do not cite benchmark performance as evidence of real-world capability in novel domains. These are not technical requirements. They are honesty requirements. And honesty about what our tools can and cannot do is the minimum ethical obligation of anyone who builds and deploys systems that affect other people's lives.&lt;/p&gt;

&lt;p&gt;The future I want to build toward, and the one I am working on in my small way with the &lt;a href="https://github.com/wiseaidotdev/lmm" rel="noopener noreferrer"&gt;lmm project&lt;/a&gt;, is a future where artificial systems earn the word autonomous through demonstrated behavior in situations that were not anticipated during design. Not through impressive demo performance on curated benchmarks. Not through confident-sounding answers to questions that happen to be in-distribution. Through genuine generalization to genuine novelty, through honest uncertainty when facing unfamiliar territory, through the capacity to form new understanding rather than retrieve old patterns. That future is technically achievable. It requires different architecture, different training objectives, different evaluation criteria, and different honesty from everyone involved in building and deploying these systems. It also requires that we stop congratulating ourselves for the current tools as though they are already there, because they are not, and pretending otherwise is how we make the journey longer, not shorter.&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; Searle, J. R., &lt;em&gt;Minds, Brains, and Programs&lt;/em&gt;, &lt;a href="https://www.cambridge.org/core/journals/behavioral-and-brain-sciences/article/abs/minds-brains-and-programs/DC644B47A4299C637C89772FACC2706A" rel="noopener noreferrer"&gt;Behavioral and Brain Sciences, 1980&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-2"&gt;&lt;/span&gt;&lt;strong&gt;2.&lt;/strong&gt; Marcus, G. &amp;amp; Davis, E., &lt;em&gt;Rebooting AI: Building Artificial Intelligence We Can Trust&lt;/em&gt;, &lt;a href="https://www.penguinrandomhouse.com/books/603982/rebooting-ai-by-gary-marcus-and-ernest-davis" rel="noopener noreferrer"&gt;Pantheon Books, 2019&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-3"&gt;&lt;/span&gt;&lt;strong&gt;3.&lt;/strong&gt; Chollet, F., &lt;em&gt;On the Measure of Intelligence&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/1911.01547" rel="noopener noreferrer"&gt;arXiv:1911.01547&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-4"&gt;&lt;/span&gt;&lt;strong&gt;4.&lt;/strong&gt; Bender, E. M., Gebru, T., McMillan-Major, A. &amp;amp; Shmitchell, S., &lt;em&gt;On the Dangers of Stochastic Parrots: Can Language Models Be Too Big?&lt;/em&gt;, &lt;a href="https://archive.org/details/stochastic-parrots-3442188.3445922" rel="noopener noreferrer"&gt;ACM FAccT 2021&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-5"&gt;&lt;/span&gt;&lt;strong&gt;5.&lt;/strong&gt; Shanahan, M., &lt;em&gt;Talking About Large Language Models&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2212.03551" rel="noopener noreferrer"&gt;arXiv:2212.03551&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-6"&gt;&lt;/span&gt;&lt;strong&gt;6.&lt;/strong&gt; Bommasani, R. et al., &lt;em&gt;On the Opportunities and Risks of Foundation Models&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2108.07258" rel="noopener noreferrer"&gt;arXiv:2108.07258&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-7"&gt;&lt;/span&gt;&lt;strong&gt;7.&lt;/strong&gt; Friston, K., &lt;em&gt;The free-energy principle: a unified brain theory?&lt;/em&gt;, &lt;a href="https://www.nature.com/articles/nrn2787" rel="noopener noreferrer"&gt;Nature Reviews Neuroscience, 2010&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-8"&gt;&lt;/span&gt;&lt;strong&gt;8.&lt;/strong&gt; Dziri, N. et al., &lt;em&gt;Faith and Fate: Limits of Transformers on Compositionality&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2305.18654" rel="noopener noreferrer"&gt;arXiv:2305.18654&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-9"&gt;&lt;/span&gt;&lt;strong&gt;9.&lt;/strong&gt; Kambhampati, S. et al., &lt;em&gt;LLMs Can't Plan, But Can Help Planning in LLM-Modulo Frameworks&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2402.01817" rel="noopener noreferrer"&gt;arXiv:2402.01817&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-10"&gt;&lt;/span&gt;&lt;strong&gt;10.&lt;/strong&gt; Zhou, S. et al., &lt;em&gt;WebArena: A Realistic Web Environment for Building Autonomous Agents&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2307.13854" rel="noopener noreferrer"&gt;arXiv:2307.13854&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-11"&gt;&lt;/span&gt;&lt;strong&gt;11.&lt;/strong&gt; Taori, R. et al., &lt;em&gt;Measuring Robustness to Natural Distribution Shifts in Image Classification&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2007.00644" rel="noopener noreferrer"&gt;arXiv:2007.00644&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-12"&gt;&lt;/span&gt;&lt;strong&gt;12.&lt;/strong&gt; Obermeyer, Z., Powers, B., Vogeli, C. &amp;amp; Mullainathan, S., &lt;em&gt;Dissecting racial bias in an algorithm used to manage the health of populations&lt;/em&gt;, &lt;a href="https://pubmed.ncbi.nlm.nih.gov/31649194/" rel="noopener noreferrer"&gt;Science, Vol. 366, 2019&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-13"&gt;&lt;/span&gt;&lt;strong&gt;13.&lt;/strong&gt; Dahl, M. et al., &lt;em&gt;Large Legal Fictions: Profiling Legal Hallucinations in Large Language Models&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/2401.01301" rel="noopener noreferrer"&gt;arXiv:2401.01301&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-14"&gt;&lt;/span&gt;&lt;strong&gt;14.&lt;/strong&gt; Harnad, S., &lt;em&gt;The Symbol Grounding Problem&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/cs/9906002" rel="noopener noreferrer"&gt;Physica D: Nonlinear Phenomena, 1990&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-15"&gt;&lt;/span&gt;&lt;strong&gt;15.&lt;/strong&gt; Guo, C. et al., &lt;em&gt;On Calibration of Modern Neural Networks&lt;/em&gt;, &lt;a href="https://arxiv.org/abs/1706.04599" rel="noopener noreferrer"&gt;ICML 2017&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-16"&gt;&lt;/span&gt;&lt;strong&gt;16.&lt;/strong&gt; Lakoff, G. &amp;amp; Johnson, M., &lt;em&gt;Philosophy in the Flesh: The Embodied Mind and Its Challenge to Western Thought&lt;/em&gt;, &lt;a href="https://openlibrary.org/works/OL1952995W/Philosophy_in_the_flesh" rel="noopener noreferrer"&gt;Basic Books, 1999&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span id="ref-17"&gt;&lt;/span&gt;&lt;strong&gt;17.&lt;/strong&gt; Pearl, J., &lt;em&gt;Causality: Models, Reasoning, and Inference&lt;/em&gt;, &lt;a href="https://www.cambridge.org/core/books/causality/B0046844FAE10CBF274D4ACBDAEB5F5B" rel="noopener noreferrer"&gt;Cambridge University Press, 2009&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>lmm</category>
      <category>discuss</category>
    </item>
    <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>
  </channel>
</rss>
