<?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: Petar Liovic</title>
    <description>The latest articles on DEV Community by Petar Liovic (@petar_liovic_9fb912bdc228).</description>
    <link>https://dev.to/petar_liovic_9fb912bdc228</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3680646%2Fc9b1ffcd-c74c-45ba-ac7b-e08d2f281261.jpg</url>
      <title>DEV Community: Petar Liovic</title>
      <link>https://dev.to/petar_liovic_9fb912bdc228</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/petar_liovic_9fb912bdc228"/>
    <language>en</language>
    <item>
      <title>What if React State Was a Signal? Applying Linear Algebra to Frontend Architecture</title>
      <dc:creator>Petar Liovic</dc:creator>
      <pubDate>Mon, 16 Feb 2026 21:16:59 +0000</pubDate>
      <link>https://dev.to/petar_liovic_9fb912bdc228/what-if-react-state-was-a-signal-applying-linear-algebra-to-frontend-architecture-5671</link>
      <guid>https://dev.to/petar_liovic_9fb912bdc228/what-if-react-state-was-a-signal-applying-linear-algebra-to-frontend-architecture-5671</guid>
      <description>&lt;p&gt;React DevTools tells you &lt;em&gt;what&lt;/em&gt; rendered. Linters tell you &lt;em&gt;what&lt;/em&gt; looks wrong in your code. But neither tells you &lt;em&gt;why&lt;/em&gt; your state architecture is broken.&lt;/p&gt;

&lt;p&gt;I spent six months thinking about this problem, and I ended up in a strange place: treating React state updates as discrete-time signals and using linear algebra heuristics to find architectural debt at runtime.&lt;/p&gt;

&lt;p&gt;This article explains the technique. There's an open-source tool at the end, but the idea is what matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;Every React developer has written something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isSuccess&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setSuccess&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three booleans. They always toggle together. You've created an implicit state machine with impossible states (&lt;code&gt;isLoading: true&lt;/code&gt; AND &lt;code&gt;isSuccess: true&lt;/code&gt;). A linter won't catch this. A profiler won't catch this. Code review &lt;em&gt;might&lt;/em&gt; catch it, if someone's paying attention.&lt;/p&gt;

&lt;p&gt;Or this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AuthContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;localUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLocalUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setLocalUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// manual sync&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You've copied a global truth into local state. Now you have two sources of truth. One day they'll drift, and you'll spend three hours debugging it.&lt;/p&gt;

&lt;p&gt;These patterns are invisible to static analysis. They only reveal themselves through &lt;strong&gt;behavior&lt;/strong&gt; at runtime. So the question is: can we detect behavior mathematically?&lt;/p&gt;




&lt;h2&gt;
  
  
  Stop Looking at Values. Start Looking at Timing.
&lt;/h2&gt;

&lt;p&gt;Here's the key insight: &lt;strong&gt;you don't need to know what a state variable holds. You only need to know when it changes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're watching your app run. Every time a component re-renders, you write down which state variables changed during that frame. After 50 frames, you have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Frame:     1  2  3  4  5  6  7  8  9  10 ...
isLoading: 0  1  0  0  1  0  0  1  0  0
isSuccess: 0  1  0  0  1  0  0  1  0  0
userName:  0  0  0  0  0  0  1  0  0  0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look at &lt;code&gt;isLoading&lt;/code&gt; and &lt;code&gt;isSuccess&lt;/code&gt;. They update in the exact same frames. Every time. That pattern alone tells you they're redundant, without ever looking at their values.&lt;/p&gt;

&lt;p&gt;Now look at &lt;code&gt;userName&lt;/code&gt;. Completely independent rhythm. It belongs in the architecture. The other two don't.&lt;/p&gt;

&lt;p&gt;This is the core idea: &lt;strong&gt;each state variable is a binary vector in {0, 1}⁵⁰&lt;/strong&gt;, where each dimension is a browser frame. We can use math on these vectors to find relationships.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cosine Similarity: Measuring How "Together" Two Variables Move
&lt;/h2&gt;

&lt;p&gt;The dot product of two binary vectors counts the frames where both variables updated:&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%2F1eoyygqr0pjb86hw2zf2.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%2F1eoyygqr0pjb86hw2zf2.png" alt="Dot" width="478" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But raw counts are misleading. A variable that updates 40 times out of 50 frames will overlap with almost anything. We need to normalize.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cosine Similarity&lt;/strong&gt; solves this:&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%2Fvv9ge1dojszve7rqwypm.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%2Fvv9ge1dojszve7rqwypm.png" alt="Cosine Similarity" width="488" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives us a score between 0 and 1:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1.0&lt;/strong&gt; means the variables update in perfect sync.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0.0&lt;/strong&gt; means they never update in the same frame.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why 0.88?
&lt;/h3&gt;

&lt;p&gt;Through testing on production codebases (including Excalidraw), I found that &lt;strong&gt;0.88&lt;/strong&gt; is the threshold that best filters browser scheduling noise while still catching real architectural problems. Geometrically, that's an angle of about 28° in a 50-dimensional space. Below that, you get false positives from the browser's non-deterministic task scheduling. Above that, you miss real issues.&lt;/p&gt;

&lt;p&gt;This is a heuristic, not a formal proof. But it works in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  But Wait: Correlation Isn't Causation
&lt;/h2&gt;

&lt;p&gt;Two variables updating in the same frame doesn't mean one caused the other. Maybe they're both responding to the same click event. That's not a bug. That's normal.&lt;/p&gt;

&lt;p&gt;To figure out &lt;em&gt;direction&lt;/em&gt;, we check the similarity at a time offset.&lt;/p&gt;

&lt;p&gt;Instead of comparing frame-to-frame (offset 0), we shift one signal by one frame and compare again:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Offset 0 (sync):&lt;/strong&gt; A and B update in the same frame. Possibly redundant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offset +1:&lt;/strong&gt; A updates, then B updates one frame later. A might be causing B.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offset -1:&lt;/strong&gt; B updates, then A updates one frame later. B might be causing A.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Normalize the circular offset once, outside the loop&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;headB&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;headA&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;iB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;baseOffset&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;iB&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;iB&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;L&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ... dot product&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the highest similarity is at offset +1, that means A consistently updates one frame before B. That's a &lt;strong&gt;causal sync leak&lt;/strong&gt;: A changes, triggers an effect, and that effect sets B. You're forcing a double render.&lt;/p&gt;

&lt;p&gt;If the highest similarity is at offset 0, they're just redundant. Two variables storing the same information.&lt;/p&gt;

&lt;p&gt;This distinction matters because the fix is different. Redundant state means "delete one." Causal leaks mean "derive instead of sync."&lt;/p&gt;




&lt;h2&gt;
  
  
  The Subspace Problem: Local vs. Global
&lt;/h2&gt;

&lt;p&gt;There's another pattern that pure correlation misses: &lt;strong&gt;Context Mirroring&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you copy a context value into local state, the local variable will be perfectly correlated with the context. But they have different roles. The context is the source of truth. The local state is a shadow.&lt;/p&gt;

&lt;p&gt;To handle this, we assign every signal a role:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local Basis (U):&lt;/strong&gt; &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useReducer&lt;/code&gt;. These should be independent.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global Subspace (W):&lt;/strong&gt; &lt;code&gt;createContext&lt;/code&gt;. These are the anchors.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The ideal architecture is a &lt;strong&gt;Direct Sum&lt;/strong&gt;: V ≈ U ⊕ W, meaning local and global state don't overlap. If a local variable is found inside the global subspace (high similarity with a context value), it's flagged as &lt;strong&gt;Context Mirroring&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This catches a class of bugs that pure similarity analysis misses: the local state isn't "redundant" with another local state. It's redundant with a &lt;em&gt;context&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Finding the Root Cause: Who Do I Fix First?
&lt;/h2&gt;

&lt;p&gt;In a complex app, this analysis can produce dozens of findings. Three boolean explosions, two context mirrors, five sync leaks. Where do you start?&lt;/p&gt;

&lt;p&gt;This is where it gets interesting. We can model all these relationships as a &lt;strong&gt;directed graph&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Nodes:&lt;/strong&gt; State variables, effects, and events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edges:&lt;/strong&gt; "A triggered B" (from the lead-lag analysis).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But here's the problem: when two variables update from the same click handler, neither caused the other. To handle this, we create a &lt;strong&gt;virtual event node&lt;/strong&gt; for every external trigger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Event_click → {setUser, setTheme, setTimestamp}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can tell the difference between a dependency chain (&lt;code&gt;A → effect → B&lt;/code&gt;) and siblings responding to the same trigger (&lt;code&gt;Event → A, Event → B&lt;/code&gt;). Without this, every pair of simultaneous updates looks like a causal leak.&lt;/p&gt;

&lt;h3&gt;
  
  
  Eigenvector Centrality (PageRank for React Hooks)
&lt;/h3&gt;

&lt;p&gt;Once we have the graph, we need to rank nodes by importance. A simple "count the edges" approach doesn't work because not all downstream nodes are equally important.&lt;/p&gt;

&lt;p&gt;Instead, we calculate &lt;strong&gt;Eigenvector Centrality&lt;/strong&gt;. The idea is the same as PageRank: a node is important if it triggers other &lt;em&gt;important&lt;/em&gt; nodes.&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%2Fg9uyhfafdjouf5p65w6z.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%2Fg9uyhfafdjouf5p65w6z.png" alt="Eigenvector Centrality" width="800" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We solve this iteratively (Power Iteration, typically converges in under 20 iterations). The node with the highest score is the &lt;strong&gt;Prime Mover&lt;/strong&gt;: the single root cause driving the most downstream activity.&lt;/p&gt;

&lt;p&gt;In practice, this means: instead of fixing 12 individual issues, you fix the one event handler or effect that's causing all of them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Does It Actually Work?
&lt;/h2&gt;

&lt;p&gt;I tested this on two real codebases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Excalidraw&lt;/strong&gt; (114k stars): The engine identified a sequential sync leak in theme management. A context update was triggering a local state sync via useEffect, causing a double render on every theme change. The lead-lag analysis at τ = +1 caught it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;shadcn-admin&lt;/strong&gt;: Found a Global Event Fragmentation pattern where a single user action was updating three separate context providers. The spectral ranking correctly identified the event handler as the Prime Mover, not any of the individual state variables.&lt;/p&gt;

&lt;p&gt;Both findings led to PRs that got merged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;The whole thing runs in the browser without blocking the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signal recording: O(1) per update (ring buffer overwrite)&lt;/li&gt;
&lt;li&gt;Correlation analysis: O(D × N) where D = dirty variables (typically 2-3)&lt;/li&gt;
&lt;li&gt;Spectral ranking: ~0.3ms for a typical app (18 nodes), ~27ms for 30,000 nodes&lt;/li&gt;
&lt;li&gt;Memory: 0 bytes heap growth over a 20-minute endurance test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The signal recording uses &lt;code&gt;requestAnimationFrame&lt;/code&gt; for sampling and &lt;code&gt;requestIdleCallback&lt;/code&gt; for analysis. The math only runs when the browser is idle.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Technique, Summarized
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Represent each state variable as a binary vector: did it update this frame (1) or not (0)?&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Cosine Similarity&lt;/strong&gt; to find variables that update together (redundancy).&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Lead-Lag Correlation&lt;/strong&gt; (offset ±1) to find causal chains (double renders).&lt;/li&gt;
&lt;li&gt;Assign &lt;strong&gt;roles&lt;/strong&gt; (local vs. context) to detect context mirroring.&lt;/li&gt;
&lt;li&gt;Build a &lt;strong&gt;directed graph&lt;/strong&gt; of causal relationships.&lt;/li&gt;
&lt;li&gt;Run &lt;strong&gt;Eigenvector Centrality&lt;/strong&gt; to find the root cause.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this looks at actual state values. None of this reads your source code. It's purely behavioral, purely based on timing.&lt;/p&gt;




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

&lt;p&gt;The technique is implemented as an open-source library called &lt;a href="https://github.com/liovic/react-state-basis" rel="noopener noreferrer"&gt;react-state-basis&lt;/a&gt;. It wraps your React hooks at build time via a Babel plugin, runs the analysis in development, and compiles down to zero-op passthrough hooks in production.&lt;/p&gt;

&lt;p&gt;If the math interests you, the &lt;a href="https://github.com/liovic/react-state-basis/wiki" rel="noopener noreferrer"&gt;wiki&lt;/a&gt; goes deeper into the signal processing model, the spectral ranking algorithm, and the performance benchmarks.&lt;/p&gt;

&lt;p&gt;If you try it on your codebase and find something interesting, I'd genuinely love to hear about it.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>performance</category>
    </item>
    <item>
      <title>Mathematical Audit of Excalidraw: Finding "Logic Echoes" via Linear Algebra</title>
      <dc:creator>Petar Liovic</dc:creator>
      <pubDate>Mon, 12 Jan 2026 12:21:42 +0000</pubDate>
      <link>https://dev.to/petar_liovic_9fb912bdc228/mathematical-audit-of-excalidraw-finding-logic-echoes-via-linear-algebra-26pj</link>
      <guid>https://dev.to/petar_liovic_9fb912bdc228/mathematical-audit-of-excalidraw-finding-logic-echoes-via-linear-algebra-26pj</guid>
      <description>&lt;h3&gt;
  
  
  The Signal is Getting Stronger
&lt;/h3&gt;

&lt;p&gt;When I released the first version of &lt;strong&gt;&lt;a href="https://github.com/liovic/react-state-basis" rel="noopener noreferrer"&gt;react-state-basis&lt;/a&gt;&lt;/strong&gt;, the goal was theoretical: could we model React hooks as temporal signals to detect architectural debt? &lt;/p&gt;

&lt;p&gt;Since then, the project has hit #1 on &lt;code&gt;r/reactjs&lt;/code&gt; and gained validation from senior engineers at companies like Calendly and Snowpact. But for &lt;strong&gt;v0.3.1&lt;/strong&gt;, I wanted to move from "Theory" to "Forensics." I wanted to run the auditor against one of the most high-performance engines in the React ecosystem: &lt;strong&gt;Excalidraw&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The "Invisibility" Milestone (v0.3.1)
&lt;/h3&gt;

&lt;p&gt;The biggest barrier to architectural telemetry is the "Import Tax." No one wants to change their source code to run an audit. &lt;/p&gt;

&lt;p&gt;As of &lt;strong&gt;v0.3.1&lt;/strong&gt;, Basis is now a &lt;strong&gt;"Ghost" in the machine&lt;/strong&gt;. Using a custom &lt;strong&gt;Babel AST transformer&lt;/strong&gt; and a &lt;strong&gt;Vite Proxy&lt;/strong&gt;, it auto-instruments standard React imports at build-time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Semantic Extraction:&lt;/strong&gt; It reads your source code to label hooks automatically (e.g., &lt;code&gt;count&lt;/code&gt;, &lt;code&gt;user&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Code Changes:&lt;/strong&gt; You keep your &lt;code&gt;import { useState } from 'react'&lt;/code&gt; exactly as is. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isomorphism:&lt;/strong&gt; The proxy maintains 100% type congruence, ensuring the IDE and compiler see a "perfect body double" of React.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Case Study: Auditing Excalidraw
&lt;/h3&gt;

&lt;p&gt;Excalidraw is a 114,000-star project and a masterpiece of performance engineering. It handles massive amounts of high-frequency state transitions. It was the perfect "Laboratory" for the R⁵⁰ vector model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Audit Results:&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Dimension Collapse in the Theme Engine
&lt;/h4&gt;

&lt;p&gt;The Basis HUD immediately flagged a &lt;strong&gt;perfect collinearity (1.0 similarity)&lt;/strong&gt; between &lt;code&gt;appTheme&lt;/code&gt; and &lt;code&gt;editorTheme&lt;/code&gt; in the core theme-handle hook. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Math:&lt;/strong&gt; These two vectors were pulsing in identical coordinates in the 50-dimensional space.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Debt:&lt;/strong&gt; One variable was a redundant mirror of the other, kept in sync via an imperative effect.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Sequential Sync Leaks (Causal Loops)
&lt;/h4&gt;

&lt;p&gt;The telemetry matrix detected multiple &lt;strong&gt;"Blue Box" violations&lt;/strong&gt;. These represent directed edges in the component's causal topology where an effect "pushes" data back into state after the render pass. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Cost:&lt;/strong&gt; In a high-performance canvas, these sequential updates force unnecessary double-reconciliation cycles, adding avoidable overhead to every theme toggle and window focus event.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Closing the Loop: The Refactor
&lt;/h3&gt;

&lt;p&gt;An auditor's job isn't just to find problems; it's to provide the &lt;strong&gt;Basis for a Solution&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;I submitted a &lt;strong&gt;&lt;a href="https://github.com/excalidraw/excalidraw/pull/10637" rel="noopener noreferrer"&gt;Pull Request to Excalidraw&lt;/a&gt;&lt;/strong&gt; (which was recently noticed and reposted by &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/vjeux"&gt;@vjeux&lt;/a&gt;&lt;/strong&gt; on x.com platform, one of the most important people in the Frontend industry) to refactor this logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;The Fix:&lt;/strong&gt; We removed the redundant state and moved to a &lt;strong&gt;Pure Projection&lt;/strong&gt; using &lt;code&gt;useSyncExternalStore&lt;/code&gt; and &lt;code&gt;useMemo&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Win:&lt;/strong&gt; Theme transitions now resolve in a single &lt;strong&gt;Atomic Render Pass&lt;/strong&gt;, restoring the linear independence of the component's basis.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What’s Next: v0.4.0 and Linear Maps
&lt;/h3&gt;

&lt;p&gt;We are now moving from &lt;strong&gt;Vector Spaces&lt;/strong&gt; to &lt;strong&gt;Linear Operator Theory&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;To handle browser-thread jitter (1ms delays), we are investigating &lt;strong&gt;Signal Conditioning&lt;/strong&gt; via linear maps. By applying a temporal convolution (smoothing) and a difference operator (velocity) to our R⁵⁰ basis, we can move from "Bit-Matching" to &lt;strong&gt;Scientific Signal Processing.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Formalize Your Basis
&lt;/h3&gt;

&lt;p&gt;Basis is open-source and ready for zero-config integration. If you want to see the "heartbeat" of your own architecture and find where your logic is redundant, give it a run.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/liovic/react-state-basis" rel="noopener noreferrer"&gt;liovic/react-state-basis&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Technical Wiki:&lt;/strong&gt; &lt;a href="https://github.com/liovic/react-state-basis/wiki" rel="noopener noreferrer"&gt;8 Chapters on Vector Spaces and Causal Topology&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>computerscience</category>
      <category>react</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Auditing React State &amp; Hooks with Math (shadcn-admin Case Study)</title>
      <dc:creator>Petar Liovic</dc:creator>
      <pubDate>Mon, 05 Jan 2026 21:51:49 +0000</pubDate>
      <link>https://dev.to/petar_liovic_9fb912bdc228/auditing-react-state-hooks-with-math-shadcn-admin-case-study-f1f</link>
      <guid>https://dev.to/petar_liovic_9fb912bdc228/auditing-react-state-hooks-with-math-shadcn-admin-case-study-f1f</guid>
      <description>&lt;h2&gt;
  
  
  The "Aha!" Moment
&lt;/h2&gt;

&lt;p&gt;Most React developers view state as a collection of variables. We look at a snapshot in time and ask, "What is the value of &lt;code&gt;isLoading&lt;/code&gt; right now?"&lt;/p&gt;

&lt;p&gt;But state isn't a static value. It's a &lt;strong&gt;signal&lt;/strong&gt; that moves through time. &lt;/p&gt;

&lt;p&gt;I spent my holiday break building &lt;strong&gt;react-state-basis&lt;/strong&gt;, an architectural auditor that treats every React hook as a vector in a 50-dimensional space. After my &lt;a href="https://dev.to/petar_liovic_9fb912bdc228/i-used-linear-algebra-to-audit-my-react-state-and-built-a-tool-for-it-280b"&gt;last post&lt;/a&gt; about the theory, I realized one thing: &lt;strong&gt;Engineers don't want more console logs. They want an Oscilloscope.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, I built the &lt;strong&gt;Temporal Matrix HUD&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Matrix: Visualizing Dimension Collapse
&lt;/h2&gt;

&lt;p&gt;When multiple state variables update in perfect sync, they aren't adding new information - they are redundant dimensions. In Linear Algebra, we call this &lt;strong&gt;Linear Dependence&lt;/strong&gt;. In React, we call it &lt;strong&gt;Architectural Debt&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I implemented a Zero-Overhead HUD (using Canvas API and &lt;code&gt;requestAnimationFrame&lt;/code&gt;) that visualizes your state transitions as a real-time heatmap.&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%2Fsym69vmf31ngjmfjap7x.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%2Fsym69vmf31ngjmfjap7x.png" alt="rsb" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Vectorization:&lt;/strong&gt; Every state variable is mapped to a row.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Temporal Window:&lt;/strong&gt; The HUD shows a sliding window of the last 50 "ticks" (20ms windows).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redundancy Detection:&lt;/strong&gt; Every 5 ticks, the engine calculates the &lt;strong&gt;Cosine Similarity&lt;/strong&gt; between all active vectors. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Visual Alert:&lt;/strong&gt; If similarity exceeds &lt;strong&gt;0.88&lt;/strong&gt;, the rows in the HUD turn &lt;strong&gt;Red&lt;/strong&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;If it pulses together, it belongs together.&lt;/strong&gt; If your matrix is full of red blocks, you're storing the same data in multiple places. Move it to &lt;code&gt;useMemo&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Case Study: Auditing &lt;code&gt;shadcn-admin&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To test the engine, I audited the popular &lt;a href="https://github.com/satnaing/shadcn-admin" rel="noopener noreferrer"&gt;shadcn-admin&lt;/a&gt; template - a gold standard for clean shadcn/ui implementations.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Efficiency Score: 100%.&lt;/strong&gt; The mathematical rank of the system was perfect. Every state variable was a unique source of truth.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "Causal" Catch:&lt;/strong&gt; Even in perfect code, the &lt;strong&gt;Causality Detective&lt;/strong&gt; flagged a sequential sync leak in the &lt;code&gt;use-mobile.tsx&lt;/code&gt; hook. It detected a "Double Render Cycle" where state was being manually synchronized within an effect.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This is the power of Basis: it finds execution-level bottlenecks that are invisible to static analysis and standard DevTools.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features in v0.2.4
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React 19 Ready:&lt;/strong&gt; Full support for &lt;code&gt;use()&lt;/code&gt;, &lt;code&gt;useOptimistic()&lt;/code&gt;, and &lt;code&gt;useActionState()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Causality Detective:&lt;/strong&gt; Tracks the chain of updates from &lt;code&gt;useEffect&lt;/code&gt; to state setters to find unnecessary renders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breaker:&lt;/strong&gt; Forcefully halts infinite loops before they lock up your browser thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ghost Mode:&lt;/strong&gt; In production, the engine resolves to "Zero-Op" exports. &lt;strong&gt;Zero bundle bloat. Zero performance penalty.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Math?
&lt;/h2&gt;

&lt;p&gt;We’ve spent a decade "guessing" why our React apps feel sluggish. By treating state transitions as vectors, we move from "voodoo debugging" to &lt;strong&gt;formal verification&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you can measure the &lt;strong&gt;Rank&lt;/strong&gt; of your state-space, you can prove that your architecture is optimal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check it out on GitHub:
&lt;/h3&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/liovic/react-state-basis" rel="noopener noreferrer"&gt;https://github.com/liovic/react-state-basis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm a solo dev and would love to hear your thoughts.&lt;/p&gt;

&lt;p&gt;Let's discuss in the comments.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>performance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I built a runtime profiler that catches React state anti-patterns</title>
      <dc:creator>Petar Liovic</dc:creator>
      <pubDate>Sat, 27 Dec 2025 01:16:30 +0000</pubDate>
      <link>https://dev.to/petar_liovic_9fb912bdc228/i-used-linear-algebra-to-audit-my-react-state-and-built-a-tool-for-it-280b</link>
      <guid>https://dev.to/petar_liovic_9fb912bdc228/i-used-linear-algebra-to-audit-my-react-state-and-built-a-tool-for-it-280b</guid>
      <description>&lt;h2&gt;
  
  
  The Problem: State Gets Messy
&lt;/h2&gt;

&lt;p&gt;In large React apps, we often end up with state that's harder to maintain than it needs to be. You've probably written code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoggedIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoggedIn&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onLogin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;setUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="nf"&gt;setIsLoggedIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Do we need both?&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;isLoggedIn&lt;/code&gt; isn't really independent—it's just &lt;code&gt;!!user&lt;/code&gt;. But keeping them in sync manually creates extra work and potential bugs.&lt;/p&gt;

&lt;p&gt;Or this pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;celsius&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCelsius&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fahrenheit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFahrenheit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setFahrenheit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;celsius&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Double render!&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;celsius&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This causes two renders every time: one for &lt;code&gt;celsius&lt;/code&gt;, then another for &lt;code&gt;fahrenheit&lt;/code&gt;. A &lt;code&gt;useMemo&lt;/code&gt; would be better.&lt;/p&gt;

&lt;p&gt;These aren't syntax errors. They work. But they create architectural debt that compounds over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: How Do You Find These?
&lt;/h2&gt;

&lt;p&gt;Standard tools like React DevTools show you &lt;em&gt;what&lt;/em&gt; your state is right now. ESLint catches some hook mistakes. But nothing really tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"These two states always update together—they're probably redundant"&lt;/li&gt;
&lt;li&gt;"This useEffect is creating a double-render cycle"&lt;/li&gt;
&lt;li&gt;"You have an infinite loop about to freeze your browser"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I built something that does.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tool: react-state-basis
&lt;/h2&gt;

&lt;p&gt;It's a development-time profiler that watches &lt;em&gt;when&lt;/em&gt; state updates happen (not the values themselves) and detects patterns that suggest architectural problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it catches:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Redundant State&lt;/strong&gt;&lt;br&gt;
When two states always update together, it suggests refactoring to a single source of truth or &lt;code&gt;useMemo&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Double-Render Cycles&lt;/strong&gt;&lt;br&gt;
When a &lt;code&gt;useEffect&lt;/code&gt; triggers another state update, causing an extra render.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Infinite Loops&lt;/strong&gt;&lt;br&gt;
High-frequency oscillations that would normally freeze your browser—caught and stopped before they lock up your tab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Hidden Coupling&lt;/strong&gt;&lt;br&gt;
States that should be independent but are actually synchronized (even across different contexts).&lt;/p&gt;

&lt;h2&gt;
  
  
  How it looks
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Detecting Redundant Boolean Flags
&lt;/h3&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%2F6jit5v8eg31qwkkjzj5i.gif" 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%2F6jit5v8eg31qwkkjzj5i.gif" alt="Booleans Example" width="600" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Using multiple boolean flags (&lt;code&gt;isLoading&lt;/code&gt;, &lt;code&gt;isSuccess&lt;/code&gt;, &lt;code&gt;hasData&lt;/code&gt;) often leads to "impossible states."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Basis catches:&lt;/strong&gt; Even though these are separate variables, they update in perfect sync. It flags them as redundant and suggests consolidating into a single state machine or status enum.&lt;/p&gt;




&lt;h3&gt;
  
  
  Circuit Breaker for Infinite Loops
&lt;/h3&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%2Fgw8bmqw6qrari87upxyi.gif" 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%2Fgw8bmqw6qrari87upxyi.gif" alt="Circuit Breaker" width="720" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; A recursive &lt;code&gt;useEffect&lt;/code&gt; causing an infinite loop—normally this freezes your browser.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Basis does:&lt;/strong&gt; Detects high-frequency oscillations (25+ updates in 500ms) and automatically halts the update chain before it locks up. Gives you a diagnostic report showing where the loop is.&lt;/p&gt;




&lt;h3&gt;
  
  
  Catching Manual State Synchronization
&lt;/h3&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%2Fyz796rei5gddeeg9s4ac.gif" 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%2Fyz796rei5gddeeg9s4ac.gif" alt="Manually Syncing" width="720" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem:&lt;/strong&gt; Manually syncing &lt;code&gt;fahrenheit&lt;/code&gt; via &lt;code&gt;useEffect&lt;/code&gt; creates a double-render cycle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Basis suggests:&lt;/strong&gt; It identifies the sequential dependency and recommends refactoring to &lt;code&gt;useMemo&lt;/code&gt; for a cleaner, single-render solution.&lt;/p&gt;




&lt;h3&gt;
  
  
  Finding Hidden Cross-Context Dependencies
&lt;/h3&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%2Fa1sduhkycw3pkk20bacm.gif" 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%2Fa1sduhkycw3pkk20bacm.gif" alt="Cross Context" width="720" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Scenario:&lt;/strong&gt; You have separate contexts (&lt;code&gt;AuthContext&lt;/code&gt;, &lt;code&gt;ThemeContext&lt;/code&gt;), but they're manually synchronized in your logic (e.g., switching to dark theme when a user logs in).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Basis reveals:&lt;/strong&gt; By analyzing update timing across your entire app, it identifies that &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;theme&lt;/code&gt; are moving in perfect sync—exposing hidden coupling between supposedly independent parts of your architecture.&lt;/p&gt;




&lt;h3&gt;
  
  
  System Health Check
&lt;/h3&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%2F13ykitsp2ewe6qyp0d0v.gif" 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%2F13ykitsp2ewe6qyp0d0v.gif" alt="Health Check" width="720" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architectural Overview:&lt;/strong&gt; Basis performs a global audit showing how much of your state is actually independent vs. redundant.&lt;/p&gt;

&lt;p&gt;An efficiency of &lt;strong&gt;40%&lt;/strong&gt; means 60% of your state variables are synchronized with others—they could probably be derived or consolidated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Goal:&lt;/strong&gt; Get closer to 100% efficiency, where every state variable serves as a true independent source of truth.&lt;/p&gt;




&lt;h2&gt;
  
  
  How It Works (High Level)
&lt;/h2&gt;

&lt;p&gt;The tool runs only in development and tracks the &lt;em&gt;timing&lt;/em&gt; of state updates across a sliding window. By looking at when updates happen (not what the values are), it can detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;States that always change together&lt;/li&gt;
&lt;li&gt;Sequential update chains&lt;/li&gt;
&lt;li&gt;Oscillating patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's inspired by signal processing and correlation analysis—think of it like a profiler for your state architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero Production Overhead
&lt;/h2&gt;

&lt;p&gt;The detection engine completely disappears in production builds. Your production bundle stays clean—this only runs during development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out
&lt;/h2&gt;

&lt;p&gt;I just released this as open source. Looking for feedback from engineers who've dealt with messy state architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/liovic/react-state-basis" rel="noopener noreferrer"&gt;https://github.com/liovic/react-state-basis&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;NPM:&lt;/strong&gt; &lt;code&gt;npm i react-state-basis&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Setup is straightforward—uses a Babel plugin to automatically instrument your hooks. No need to change your component code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;After working on large React codebases for years, I kept seeing the same patterns cause problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boolean flags that should be enums&lt;/li&gt;
&lt;li&gt;Manual synchronization that should be derivation&lt;/li&gt;
&lt;li&gt;Hidden dependencies across contexts&lt;/li&gt;
&lt;li&gt;Infinite loops that only appear in production&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of these aren't caught by linters or type checkers. They're architectural issues that emerge over time. I wanted a tool that could spot them automatically.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you've struggled with state management complexity, I'd love to hear your thoughts.&lt;/strong&gt; What patterns do you wish tools could catch automatically?&lt;/p&gt;

&lt;p&gt;Star the repo if this looks useful, or open an issue with feedback. Always looking to improve it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Keep your state minimal and your architecture clean.&lt;/em&gt; ✨&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>linearalgebra</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
