<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>BeWellUp - Blog</title>
    <subtitle>BeWellUp: news, updates, and information about BWU Designer.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://bewellup.com/blog/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://bewellup.com/blog/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-07-18T00:00:00+00:00</updated>
    <id>https://bewellup.com/blog/atom.xml</id>
    <entry xml:lang="en">
        <title>Introducing bwu_redux_devtools: A Redux DevTools GUI for Rust</title>
        <published>2026-07-18T00:00:00+00:00</published>
        <updated>2026-07-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bewellup.com/blog/introducing-bwu-redux-devtools/"/>
        <id>https://bewellup.com/blog/introducing-bwu-redux-devtools/</id>
        
        <content type="html" xml:base="https://bewellup.com/blog/introducing-bwu-redux-devtools/">&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;bwu-redux-devtools-diff-coloring.gif&quot; alt=&quot;Tree view color-coding added, removed, and changed state between actions&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Following &lt;a href=&quot;&#x2F;blog&#x2F;introducing-bwu-redux&#x2F;&quot;&gt;bwu_redux&lt;&#x2F;a&gt; out the door, we&#x27;ve now open sourced
&lt;strong&gt;bwu_redux_devtools&lt;&#x2F;strong&gt; — the Redux DevTools GUI and gRPC server we built to inspect
&lt;code&gt;bwu_redux&lt;&#x2F;code&gt; stores, published on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux_devtools&quot;&gt;GitHub&lt;&#x2F;a&gt; under a dual MIT&#x2F;Apache-2.0
license.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-it-does&quot;&gt;What it does&lt;&#x2F;h2&gt;
&lt;p&gt;Connected apps stream every dispatched action and the resulting state to the DevTools
server. The GUI shows the action history per app and lets you inspect any recorded
state as a collapsible tree, JSON, or RON. The tree view — shown above — color-codes
what changed since the previous action (added, removed, changed), with a toggle to hide
everything that didn&#x27;t change, so a large state doesn&#x27;t bury the one field you actually
care about.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s built with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dioxuslabs.com&#x2F;&quot;&gt;Dioxus&lt;&#x2F;a&gt;, the same GUI framework as BWU
Designer, and runs as both a desktop app and a web GUI.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;not-on-crates-io-yet&quot;&gt;Not on crates.io yet&lt;&#x2F;h2&gt;
&lt;p&gt;Unlike &lt;code&gt;bwu_redux&lt;&#x2F;code&gt; itself, this crate isn&#x27;t published to crates.io: it depends on the
official Dioxus components, whose &lt;code&gt;dioxus-primitives&lt;&#x2F;code&gt; crate is currently only available
as a git dependency, not a published release. Once that lands upstream, we&#x27;ll publish
here too. Until then, install straight from GitHub:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Desktop GUI (embeds the DevTools gRPC server)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux_devtools&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --bin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; bwu_redux_devtools&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6A737D;&quot;&gt;# Headless gRPC server only (e.g. to serve the web GUI)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;cargo&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; install&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --git&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux_devtools&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --bin&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; bwu_redux_devtools_server&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt; --features&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; standalone-server&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;connecting-an-app&quot;&gt;Connecting an app&lt;&#x2F;h2&gt;
&lt;p&gt;Enable devtools on the store config in the app you want to inspect — this needs the
&lt;code&gt;redux_devtools&lt;&#x2F;code&gt; feature of &lt;code&gt;bwu_redux&lt;&#x2F;code&gt;, which is on by default:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;let&lt;&#x2F;span&gt;&lt;span&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; StoreConfig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(initial_state, reducer)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;with_devtools&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #005CC5;&quot;&gt;true&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;with_app_name&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;my-app&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Start the DevTools GUI, then your app; it appears in the sidebar and its action history
fills in live.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-mcp-interface-for-free&quot;&gt;An MCP interface, for free&lt;&#x2F;h2&gt;
&lt;p&gt;With the &lt;code&gt;mcp&lt;&#x2F;code&gt; feature enabled, the same server also serves an
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;modelcontextprotocol.io&#x2F;&quot;&gt;MCP&lt;&#x2F;a&gt; endpoint alongside its usual gRPC one — no
separate binary or process. That means an AI agent — Claude Code, for instance — can
inspect a connected app&#x27;s live Redux state directly: list connected apps, pull an app&#x27;s
action&#x2F;state history, read its current state, or pause forwarding for noisy actions.
For us, that turned out to be a genuinely useful way to let an agent debug state issues
in BWU Designer without us relaying screenshots back and forth.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;try-it&quot;&gt;Try it&lt;&#x2F;h2&gt;
&lt;p&gt;Issues and pull requests are welcome on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux_devtools&quot;&gt;GitHub&lt;&#x2F;a&gt;. If you&#x27;re already using
&lt;code&gt;bwu_redux&lt;&#x2F;code&gt;, this is the other half of the picture — go give it a try.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introducing bwu_redux: Redux-Style State Management for Rust, Now Open Source</title>
        <published>2026-07-17T00:00:00+00:00</published>
        <updated>2026-07-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bewellup.com/blog/introducing-bwu-redux/"/>
        <id>https://bewellup.com/blog/introducing-bwu-redux/</id>
        
        <content type="html" xml:base="https://bewellup.com/blog/introducing-bwu-redux/">&lt;img src=&quot;&#x2F;images&#x2F;rustacean-flat-gesture.svg&quot; alt=&quot;Ferris the Rust mascot crab, waving a claw&quot; class=&quot;w-40 mx-auto not-prose&quot;&gt;
&lt;p&gt;In our &lt;a href=&quot;&#x2F;blog&#x2F;redux-and-rust-for-frontend-development&#x2F;&quot;&gt;last post&lt;&#x2F;a&gt; we made the case for
pairing Redux-style state management with Rust. Today that&#x27;s no longer just an
argument — it&#x27;s a crate you can add to your project. &lt;strong&gt;bwu_redux&lt;&#x2F;strong&gt; is now open source,
published on &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;bwu_redux&quot;&gt;crates.io&lt;&#x2F;a&gt; and
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux&quot;&gt;GitHub&lt;&#x2F;a&gt; under a dual MIT&#x2F;Apache-2.0 license.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s the same state management library behind BWU Designer&#x27;s frontend, extracted so
anyone can use it independently of our app.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-it-does&quot;&gt;What it does&lt;&#x2F;h2&gt;
&lt;p&gt;bwu_redux is an async, Redux-style store for Rust: a single immutable state, actions
dispatched through a middleware chain, and a pure reducer that produces the next state.
State changes are broadcast to subscribers as async streams, driven by selectors that
extract just the slice of state a subscriber actually cares about — so a subscriber is
only woken up when the value it selected actually changes, not on every dispatch.&lt;&#x2F;p&gt;
&lt;p&gt;A few things worth calling out specifically:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Undo for free.&lt;&#x2F;strong&gt; With the &lt;code&gt;history&lt;&#x2F;code&gt; feature enabled (on by default), the store
keeps the last N states automatically. Undo isn&#x27;t a separate system bolted on top —
it falls out of the same append-only state log that makes the store predictable in
the first place.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Time-travel debugging.&lt;&#x2F;strong&gt; The &lt;code&gt;redux_devtools&lt;&#x2F;code&gt; feature streams every state change to
a DevTools gRPC server for live inspection, using the same wire format whether your
app is running natively or in the browser.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;One codebase, two runtimes.&lt;&#x2F;strong&gt; The exact same store, actions, and reducer logic run
unmodified on native targets and in WASM via &lt;code&gt;wasm-bindgen&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;gloo&lt;&#x2F;code&gt; — including the
DevTools connection, which just switches to gRPC-web in the browser.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting started&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; std&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;sync&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;Arc&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;use&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; bwu_redux&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;StoreConfig&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; StoreWrapper&lt;&#x2F;span&gt;&lt;span&gt;};&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[tokio&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;main]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;async fn&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; main&lt;&#x2F;span&gt;&lt;span&gt;() {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; config&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; StoreConfig&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;initial&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;state&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; String&lt;&#x2F;span&gt;&lt;span&gt;, action&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;: &amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;        if&lt;&#x2F;span&gt;&lt;span&gt; action&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;is_empty&lt;&#x2F;span&gt;&lt;span&gt;() { state }&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; else&lt;&#x2F;span&gt;&lt;span&gt; { action&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span&gt;() }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    });&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; store&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt; Arc&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;StoreWrapper&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;(config));&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    store&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;run&lt;&#x2F;span&gt;&lt;span&gt;();&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    store&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dispatch&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;from&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;))&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;store is running&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    store&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;close&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;String&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.await.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt;&amp;quot;close failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;    assert_eq!&lt;&#x2F;span&gt;&lt;span&gt;(store&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;select&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; s&lt;&#x2F;span&gt;&lt;span style=&quot;color: #D73A49;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;clone&lt;&#x2F;span&gt;&lt;span&gt;()),&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;hello&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;State and action types just need &lt;code&gt;Clone + Debug + PartialEq + Send + Sync&lt;&#x2F;code&gt; — add
&lt;code&gt;serde::Serialize&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;Deserialize&lt;&#x2F;code&gt; if you want the &lt;code&gt;redux_devtools&lt;&#x2F;code&gt; feature. The
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux&quot;&gt;README&lt;&#x2F;a&gt; has a more complete example with
tracing set up, and the full feature-flag reference.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;try-it-and-tell-us-what-breaks&quot;&gt;Try it, and tell us what breaks&lt;&#x2F;h2&gt;
&lt;p&gt;This is a &lt;code&gt;0.1.0&lt;&#x2F;code&gt; release: the core store, middleware, undo history, and DevTools
integration are all in daily use inside BWU Designer, but the crate is young and the
API may still shift. If you try it and hit a rough edge — or just want to see how the
DevTools protocol works — issues and pull requests are welcome on
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;BeWellUp&#x2F;bwu_redux&quot;&gt;GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #24292E; background-color: #FFFFFF;&quot;&gt;&lt;code data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: #6F42C1;&quot;&gt;dependencies&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bwu_redux =&lt;&#x2F;span&gt;&lt;span style=&quot;color: #032F62;&quot;&gt; &amp;quot;0.1&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Case for Redux and Rust in Frontend Development</title>
        <published>2026-07-17T00:00:00+00:00</published>
        <updated>2026-07-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bewellup.com/blog/redux-and-rust-for-frontend-development/"/>
        <id>https://bewellup.com/blog/redux-and-rust-for-frontend-development/</id>
        
        <content type="html" xml:base="https://bewellup.com/blog/redux-and-rust-for-frontend-development/">&lt;p&gt;&lt;img src=&quot;&#x2F;images&#x2F;redux-and-rust-cover.jpg&quot; alt=&quot;View across a mountain ridge in the Alps&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Frontend state has a way of sprawling. Data gets fetched in one place, mutated in
another, and read somewhere else entirely. Six months into a project, the hardest bugs
are rarely about &lt;em&gt;what&lt;&#x2F;em&gt; the state contains — they&#x27;re about &lt;em&gt;when&lt;&#x2F;em&gt; and &lt;em&gt;how&lt;&#x2F;em&gt; it got that
way. Something changed state out from under a component that assumed it owned it, or
two pieces of code raced to update the same value in slightly different orders. None of
that shows up in a type signature. It only shows up at 2am.&lt;&#x2F;p&gt;
&lt;p&gt;The Redux pattern was a direct answer to that problem, and it holds up well over a
decade later.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-the-pattern-buys-you&quot;&gt;What the pattern buys you&lt;&#x2F;h2&gt;
&lt;p&gt;Redux&#x27;s core idea is almost boringly simple: there is exactly one source of truth for
your application&#x27;s state, and the only way to change it is by dispatching a typed
action through a pure reducer function. No component reaches in and mutates state
directly; no side effect quietly rewrites something a different part of the UI is
relying on. Every state transition is &lt;code&gt;(old_state, action) -&amp;gt; new_state&lt;&#x2F;code&gt;, full stop.&lt;&#x2F;p&gt;
&lt;p&gt;That discipline sounds restrictive, but it pays for itself almost immediately. Because
reducers are pure functions, every state transition is inspectable, replayable, and
testable in isolation — no mocking a DOM, no simulating a component lifecycle. And once
your state changes are just a log of &lt;code&gt;(action, resulting_state)&lt;&#x2F;code&gt; pairs, time-travel
debugging and undo&#x2F;redo stop being hard features to build. They&#x27;re closer to a
side effect of the architecture than a project in their own right.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;framework-independence&quot;&gt;Framework independence&lt;&#x2F;h2&gt;
&lt;p&gt;This is the part that gets undersold. Because business logic — actions, reducers,
selectors — has no dependency on the rendering layer at all, the GUI framework becomes
a thin, swappable consumer of state rather than the thing everything else is built
around. Your reducers don&#x27;t know or care whether they&#x27;re being rendered by React, a
native toolkit, or nothing at all. That means you can replace the rendering framework
later, run a second UI alongside the first — a CLI, a mobile shell, a server-side
render — or upgrade the framework version without touching a single reducer, because
there was never a dependency to begin with.&lt;&#x2F;p&gt;
&lt;p&gt;That&#x27;s a structural property of Redux itself, independent of language. But it turns out
Rust is a particularly good place to build on top of it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-rust-sharpens-the-pattern-further&quot;&gt;Why Rust sharpens the pattern further&lt;&#x2F;h2&gt;
&lt;p&gt;A few things compound nicely:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Actions as enums.&lt;&#x2F;strong&gt; When every action is a variant of an enum, reducers match
exhaustively over them. Add a new action and forget to handle it somewhere, and the
compiler stops you — not a silent no-op discovered by a user three releases later.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Ownership rules eliminate a whole bug class.&lt;&#x2F;strong&gt; The classic Redux footgun in
dynamically-typed languages is something reaching in and mutating shared state
outside the reducer path. Rust&#x27;s borrow checker makes that structurally impossible,
rather than a matter of team discipline and code review.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Types catch invalid states at compile time.&lt;&#x2F;strong&gt; Instead of a runtime warning about an
unexpected prop shape, an invalid state transition simply doesn&#x27;t compile. The
feedback loop moves from &quot;someone notices in production&quot; to &quot;the build fails.&quot;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;the-usual-objection&quot;&gt;The usual objection&lt;&#x2F;h2&gt;
&lt;p&gt;The standard complaint about Redux is boilerplate — action creators, type constants,
switch statements sprawling across files. That complaint is largely an artifact of
building Redux in a language without a real type system to lean on. Enums, derive
macros, and pattern matching collapse most of that ceremony automatically, and the
compiler is doing validation work that a dynamically-typed Redux setup has to do by
hand, action by action.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-this-actually-earns-its-keep&quot;&gt;Where this actually earns its keep&lt;&#x2F;h2&gt;
&lt;p&gt;This combination isn&#x27;t the right tool for a static marketing page. It earns its
complexity in applications with genuinely long-lived, intricate state — undo history,
multiple views that need to stay in sync, sessions that persist across a lot of user
interaction. That&#x27;s also where the framework-independence point from earlier stops
being theoretical: the same reducer and action logic can target multiple &lt;em&gt;runtimes&lt;&#x2F;em&gt;,
not just multiple UI frameworks, since none of it depends on a JS runtime, a DOM, or
any particular platform to execute. Framework-independence and runtime-independence
turn out to be two sides of the same coin — logic that genuinely doesn&#x27;t know anything
about the view layer runs anywhere a view layer might eventually need to exist.&lt;&#x2F;p&gt;
&lt;p&gt;We&#x27;ve been finding this combination genuinely useful, and expect to keep writing about
what we learn as we go.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello, world!</title>
        <published>2026-07-14T00:00:00+00:00</published>
        <updated>2026-07-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://bewellup.com/blog/hello-world/"/>
        <id>https://bewellup.com/blog/hello-world/</id>
        
        <content type="html" xml:base="https://bewellup.com/blog/hello-world/">&lt;p&gt;This is the first post on the BeWellUp blog. More updates about &lt;strong&gt;BWU Designer&lt;&#x2F;strong&gt; will
follow here as the product takes shape.&lt;&#x2F;p&gt;

&lt;div class=&quot;card bg-base-100 shadow-sm my-8&quot; id=&quot;newsletter&quot;&gt;
  &lt;div class=&quot;card-body&quot;&gt;
    &lt;h2 class=&quot;card-title&quot;&gt;Subscribe to our newsletter&lt;&#x2F;h2&gt;
    &lt;p&gt;Get updates about BWU Designer in your inbox.&lt;&#x2F;p&gt;
    
    &lt;form
      class=&quot;flex gap-2&quot;
      action=&quot;https:&#x2F;&#x2F;buttondown.com&#x2F;api&#x2F;emails&#x2F;embed-subscribe&#x2F;bewellup&quot;
      method=&quot;post&quot;
      target=&quot;popupwindow&quot;
      onsubmit=&quot;window.open(&#x27;https:&#x2F;&#x2F;buttondown.com&#x2F;bewellup&#x27;, &#x27;popupwindow&#x27;)&quot;
    &gt;
      &lt;input
        type=&quot;email&quot;
        name=&quot;email&quot;
        required
        placeholder=&quot;Your email address&quot;
        class=&quot;input input-bordered flex-1&quot;
      &gt;
      &lt;input type=&quot;hidden&quot; value=&quot;1&quot; name=&quot;embed&quot;&gt;
      &lt;button type=&quot;submit&quot; class=&quot;btn btn-primary&quot;&gt;Subscribe&lt;&#x2F;button&gt;
    &lt;&#x2F;form&gt;
    
  &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;

</content>
        
    </entry>
</feed>
