<?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>Forem: Taron Vardanyan</title>
    <description>The latest articles on Forem by Taron Vardanyan (@taronvardanyan).</description>
    <link>https://forem.com/taronvardanyan</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%2F1085533%2F81642591-6ca2-47e1-95ac-de0c14ba43be.png</url>
      <title>Forem: Taron Vardanyan</title>
      <link>https://forem.com/taronvardanyan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/taronvardanyan"/>
    <language>en</language>
    <item>
      <title>Risks When Business Logic Is Forgotten</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Sat, 07 Feb 2026 13:15:58 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/risks-when-business-logic-is-forgotten-30o8</link>
      <guid>https://forem.com/taronvardanyan/risks-when-business-logic-is-forgotten-30o8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Sometimes, the system remembers more than the people managing it.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In legacy or large projects, team changes happen frequently. New product managers arrive, stakeholders may forget key details, and important business logic risks being overlooked.&lt;/p&gt;

&lt;p&gt;This can lead to feature duplication, conflicts, or unintended behavior if the technical team doesn’t step in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Risks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Existing business rules get ignored or reimplemented&lt;/li&gt;
&lt;li&gt;Features may conflict with hidden dependencies&lt;/li&gt;
&lt;li&gt;Product behavior can become inconsistent or unpredictable&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How Technical Teams Can Mitigate
&lt;/h2&gt;

&lt;p&gt;Here are key approaches and considerations:&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Document &amp;amp; Communicate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Keep &lt;strong&gt;technical documentation and system diagrams&lt;/strong&gt; updated&lt;/li&gt;
&lt;li&gt;Document &lt;strong&gt;existing features and dependencies&lt;/strong&gt; clearly&lt;/li&gt;
&lt;li&gt;Provide explanations when rejecting or modifying requests&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2️⃣ Analyze Existing Features First
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Before implementing a new request, &lt;strong&gt;check if the functionality already exists&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Identify potential conflicts or redundancies&lt;/li&gt;
&lt;li&gt;Suggest leveraging existing systems rather than building from scratch&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3️⃣ Provide Trade-off Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Explain implications: performance, maintenance, and user experience&lt;/li&gt;
&lt;li&gt;Highlight risks: breaking legacy flows, introducing regressions&lt;/li&gt;
&lt;li&gt;Give estimates of cost vs benefit&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4️⃣ Use Controlled Rollouts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;For features that might overlap with existing logic, &lt;strong&gt;implement in stages&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Monitor for unexpected interactions&lt;/li&gt;
&lt;li&gt;Provide stakeholders with real feedback before fully committing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5️⃣ Share Historical Context
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Encourage onboarding sessions for new team members about &lt;strong&gt;historical decisions, product rationale, and technical constraints&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;This reduces future redundant requests and misaligned expectations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6️⃣ Roadmap Awareness
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Maintain a clear &lt;strong&gt;roadmap&lt;/strong&gt; outlining &lt;strong&gt;product direction, upcoming features, and priorities&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Helps the team understand which features are planned and critical&lt;/li&gt;
&lt;li&gt;Reduces redundant requests and confusion, aligning technical decisions with business goals&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7️⃣ Respect Stakeholder Philosophy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Developers and technical teams care deeply about the &lt;strong&gt;product vision and the mindset of stakeholders&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If stakeholders or executives focus only on adding features or profit without understanding the product, the team may face frustration&lt;/li&gt;
&lt;li&gt;The value developers bring is in &lt;strong&gt;creating thoughtful, meaningful features&lt;/strong&gt;, not just executing requests&lt;/li&gt;
&lt;li&gt;Features implemented exactly according to a user story should &lt;strong&gt;not be blamed&lt;/strong&gt; if the outcome does not satisfy stakeholders who are not fully involved in creation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;When knowledge about business logic is lost or overlooked, the technical team becomes the guardian of continuity. A clear roadmap, proper documentation, and stakeholder engagement ensure the product evolves safely and efficiently even as teams change. Developers rely on stakeholder involvement to maintain meaningful outcomes and avoid misaligned expectations.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How do you handle business logic risks and stakeholder alignment in changing teams?&lt;/em&gt; 💬&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>management</category>
      <category>product</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Legacy Code: Refactor or Rewrite? Deciding From Business &amp; Engineering Perspectives</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Sat, 07 Feb 2026 11:44:52 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/legacy-code-refactor-or-rewrite-deciding-from-business-engineering-perspectives-518k</link>
      <guid>https://forem.com/taronvardanyan/legacy-code-refactor-or-rewrite-deciding-from-business-engineering-perspectives-518k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Every production system has a story. Every decision has a cost.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Legacy code isn’t just “messy code.” It’s &lt;strong&gt;revenue, customers, and trust&lt;/strong&gt;. It works — maybe not elegantly, maybe not consistently — but it works. And now, the question hits:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Should we refactor it… or rewrite it completely?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s explore the decision from both &lt;strong&gt;business&lt;/strong&gt; and &lt;strong&gt;development management&lt;/strong&gt; angles.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ When Refactoring Makes Sense
&lt;/h2&gt;

&lt;p&gt;Refactoring is like &lt;strong&gt;cleaning and reorganizing a house while still living in it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It’s ideal when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The product is actively used and generating revenue&lt;/li&gt;
&lt;li&gt;The system works correctly most of the time&lt;/li&gt;
&lt;li&gt;Business logic is critical and well-understood only by existing teams&lt;/li&gt;
&lt;li&gt;You want incremental improvement with minimal risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;From a business perspective:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lower immediate cost compared to a full rewrite&lt;/li&gt;
&lt;li&gt;Reduces risk of breaking something important&lt;/li&gt;
&lt;li&gt;Preserves historical knowledge embedded in the code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;From a development perspective:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows gradual improvement of code quality&lt;/li&gt;
&lt;li&gt;Makes onboarding new engineers easier&lt;/li&gt;
&lt;li&gt;Keeps architectural improvements aligned with real usage patterns&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2️⃣ When Rewriting Becomes the Better Option
&lt;/h2&gt;

&lt;p&gt;A rewrite is like &lt;strong&gt;building a new house from scratch&lt;/strong&gt;. It’s costly, risky, but sometimes inevitable.&lt;/p&gt;

&lt;p&gt;It becomes sensible when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The current architecture cannot support future business goals&lt;/li&gt;
&lt;li&gt;Technical debt is so high that feature development is slowed dramatically&lt;/li&gt;
&lt;li&gt;Multiple inconsistent patterns exist that are impossible to unify safely&lt;/li&gt;
&lt;li&gt;Legacy dependencies are obsolete or impossible to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;From a business perspective:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Higher short-term cost, but potentially lower long-term maintenance&lt;/li&gt;
&lt;li&gt;Allows new features to be implemented faster in the future&lt;/li&gt;
&lt;li&gt;Provides a clean slate for integrating AI tools, modern frameworks, or cloud infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;From a development perspective:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoids patching fragile, inconsistent code repeatedly&lt;/li&gt;
&lt;li&gt;Enables modern best practices and standards&lt;/li&gt;
&lt;li&gt;Improves team morale — no one enjoys patching a brittle system forever&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3️⃣ The Middle Ground: Strategic Refactor + Targeted Rewrite
&lt;/h2&gt;

&lt;p&gt;Often the best path isn’t purely one or the other.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Critical paths&lt;/strong&gt; can be rewritten gradually&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stable parts&lt;/strong&gt; are refactored incrementally&lt;/li&gt;
&lt;li&gt;Business logic is preserved while architecture is modernized&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach balances &lt;strong&gt;risk, cost, and speed&lt;/strong&gt;, keeping the system live and the business running.&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Legacy code is not a problem — it’s a historical artifact of business and technology decisions&lt;/li&gt;
&lt;li&gt;Refactoring is cheaper, safer, and ideal for incremental improvements&lt;/li&gt;
&lt;li&gt;Rewriting is justified when technical debt blocks business growth or agility&lt;/li&gt;
&lt;li&gt;AI and modern tools can &lt;strong&gt;amplify both approaches&lt;/strong&gt;, but cannot replace the human understanding of business logic and system design&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Final Thought:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every system has its own “story.” Understanding &lt;strong&gt;why it exists, how it evolved, and where it must go next&lt;/strong&gt; is the most important skill in software engineering. Refactoring and rewriting are just the tools — knowing &lt;strong&gt;when and how to use them&lt;/strong&gt; is what separates good engineers from great ones.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Curious how others decide between refactor and rewrite in their legacy systems? Let’s discuss.&lt;/em&gt; 💬&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>codequality</category>
      <category>management</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Front-End Engineering in 2026: Evolution, Saturation, and the Untapped Paths</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Sun, 01 Feb 2026 16:15:50 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/front-end-engineering-in-2026-evolution-saturation-and-the-untapped-paths-3646</link>
      <guid>https://forem.com/taronvardanyan/front-end-engineering-in-2026-evolution-saturation-and-the-untapped-paths-3646</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Being “just” a front-end developer is no longer a long-term strategy.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Front-end engineering has gone through multiple eras: from jQuery-powered websites, to SPA dominance, to framework specialization. In 2026, we’re entering a new phase — one defined by &lt;strong&gt;AI assistance, market saturation, and specialization pressure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This post is not about panic. It’s about realism, positioning, and choosing the right evolutionary path.&lt;/p&gt;




&lt;h2&gt;
  
  
  The End of the One-Framework Career
&lt;/h2&gt;

&lt;p&gt;For a long time, being &lt;em&gt;really good&lt;/em&gt; at a single framework (React, Angular, Vue) was enough. That era is ending.&lt;/p&gt;

&lt;p&gt;Today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI agents can scaffold, refactor, and debug across &lt;strong&gt;multiple frameworks&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Switching between React, Vue, or Svelte is no longer a multi-month learning curve&lt;/li&gt;
&lt;li&gt;Framework knowledge alone is becoming &lt;strong&gt;commoditized&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI doesn’t replace engineers — but it &lt;em&gt;compresses skill gaps&lt;/em&gt;. A mid-level engineer with strong fundamentals and AI assistance can move faster than a specialist locked into one ecosystem.&lt;/p&gt;

&lt;p&gt;That’s powerful.&lt;/p&gt;

&lt;p&gt;But it creates a &lt;strong&gt;new problem&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Market Reality: Too Many Front-End Engineers
&lt;/h2&gt;

&lt;p&gt;If many engineers can now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build similar UIs&lt;/li&gt;
&lt;li&gt;Ship features faster&lt;/li&gt;
&lt;li&gt;Work across frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the obvious question arises:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Why should companies hire all of them?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The truth is uncomfortable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Front-end developers are &lt;strong&gt;numerous&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Open positions are &lt;strong&gt;limited&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Competition is &lt;strong&gt;brutal&lt;/strong&gt;, especially for generic roles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being “a front-end engineer” is no longer a differentiator.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Usual Advice — And Why It’s Breaking
&lt;/h2&gt;

&lt;p&gt;The classic recommendation is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Become a full-stack engineer.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;On paper, it makes sense. In practice, it’s splitting into two difficult paths.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path 1: Full-Stack with Node.js
&lt;/h3&gt;

&lt;p&gt;Yes, JavaScript knowledge transfers nicely to Node.js.&lt;/p&gt;

&lt;p&gt;But reality check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most &lt;strong&gt;existing&lt;/strong&gt; products are legacy systems&lt;/li&gt;
&lt;li&gt;Backends are written in &lt;strong&gt;C#, Java, PHP, Ruby, Python&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Node.js is still a &lt;strong&gt;newcomer&lt;/strong&gt; in enterprise and long-lived systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The chance that you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Join a greenfield project&lt;/li&gt;
&lt;li&gt;Choose Node.js freely&lt;/li&gt;
&lt;li&gt;Grow as a JS full-stack engineer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…is &lt;strong&gt;much smaller than people think&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And the market is already full of experienced full-stack engineers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path 2: Learn a Second Backend Language
&lt;/h3&gt;

&lt;p&gt;This path is even harder.&lt;/p&gt;

&lt;p&gt;You must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn a new language from scratch&lt;/li&gt;
&lt;li&gt;Compete with backend-first engineers&lt;/li&gt;
&lt;li&gt;Accept junior-level backend responsibility&lt;/li&gt;
&lt;li&gt;Often &lt;em&gt;not&lt;/em&gt; touch real production systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This path is slow, risky, and heavily competitive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Backend Awareness Still Matters (A Lot)
&lt;/h2&gt;

&lt;p&gt;Let’s be clear: front-end engineers &lt;strong&gt;must&lt;/strong&gt; understand backend concepts.&lt;/p&gt;

&lt;p&gt;But not just REST.&lt;/p&gt;

&lt;p&gt;In 2026, strong front-end engineers should be comfortable with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL&lt;/strong&gt; and schema-driven thinking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apollo Client&lt;/strong&gt; and cache strategies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RPC / tRPC&lt;/strong&gt; patterns&lt;/li&gt;
&lt;li&gt;Data ownership, contracts, and boundaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not about writing backend services — it’s about &lt;strong&gt;understanding how data flows&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That knowledge is now baseline.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Overlooked Evolution Path: Advanced Front-End Domains
&lt;/h2&gt;

&lt;p&gt;There is another path. A bigger one. And it’s wildly underestimated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Complex, High-Skill Front-End Applications
&lt;/h3&gt;

&lt;p&gt;Not all front-end work is CRUD dashboards.&lt;/p&gt;

&lt;p&gt;There are domains where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI helps less&lt;/li&gt;
&lt;li&gt;Abstraction is thinner&lt;/li&gt;
&lt;li&gt;Skill gaps are massive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Construction &amp;amp; engineering visualization apps&lt;/li&gt;
&lt;li&gt;Data-heavy analytical platforms&lt;/li&gt;
&lt;li&gt;Real-time systems&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2D and 3D animation-driven applications&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And most importantly…&lt;/p&gt;




&lt;h2&gt;
  
  
  Game Development: The Front-End Gold Mine
&lt;/h2&gt;

&lt;p&gt;Game development is one of the &lt;strong&gt;richest and least saturated&lt;/strong&gt; front-end domains.&lt;/p&gt;

&lt;p&gt;Especially in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web-based games&lt;/li&gt;
&lt;li&gt;Gambling &amp;amp; casino platforms&lt;/li&gt;
&lt;li&gt;Interactive entertainment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why this matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still heavily based on &lt;strong&gt;JavaScript&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Requires deep rendering, timing, and state knowledge&lt;/li&gt;
&lt;li&gt;Very few strong front-end engineers specialize here&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technologies worth learning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PixiJS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Three.js&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;WebGL concepts&lt;/li&gt;
&lt;li&gt;Animation lifecycles&lt;/li&gt;
&lt;li&gt;Performance optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compared to learning a new backend language, this path is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster&lt;/li&gt;
&lt;li&gt;More aligned with front-end thinking&lt;/li&gt;
&lt;li&gt;Far less competitive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And demand?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constant. Global. Well-paid.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Competitive Advantage Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;In animation-heavy and game-oriented front-end work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is &lt;strong&gt;no crowd&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Specialists are always in demand&lt;/li&gt;
&lt;li&gt;Projects are long-running&lt;/li&gt;
&lt;li&gt;Budgets are high&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t restart as a junior.&lt;br&gt;
You &lt;strong&gt;evolve as an engineer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You already know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;li&gt;Rendering lifecycles&lt;/li&gt;
&lt;li&gt;State management&lt;/li&gt;
&lt;li&gt;Performance constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’re just applying them in a deeper, more technical domain.&lt;/p&gt;




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

&lt;p&gt;If you are a front-end engineer in 2026:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You are already an engineer — that part is done&lt;/li&gt;
&lt;li&gt;Generic roles will keep shrinking&lt;/li&gt;
&lt;li&gt;Backend knowledge is necessary, but not always the escape route&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real opportunity lies in &lt;strong&gt;specialized front-end universes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Animation&lt;/li&gt;
&lt;li&gt;Visualization&lt;/li&gt;
&lt;li&gt;Game development&lt;/li&gt;
&lt;li&gt;High-performance UI systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is less competition.&lt;br&gt;
There is more depth.&lt;br&gt;
And there is real long-term value.&lt;/p&gt;

&lt;p&gt;Sometimes, the next step forward isn’t becoming &lt;em&gt;more general&lt;/em&gt; —&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s going &lt;strong&gt;deeper where others won’t go&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading. Curious to hear how others are navigating front-end careers in 2026.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI Won’t Replace Software Engineers — It Will Terraform How We Build</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Sat, 31 Jan 2026 10:37:57 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/ai-wont-replace-software-engineers-it-will-terraform-how-we-build-56k3</link>
      <guid>https://forem.com/taronvardanyan/ai-wont-replace-software-engineers-it-will-terraform-how-we-build-56k3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;AI will absolutely do the work of coders.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;It will not replace software engineers.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a take shaped by years of working inside &lt;strong&gt;real, running, revenue‑generating legacy systems&lt;/strong&gt; — the kind no one wants to rewrite, but everyone depends on.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Quick Time Travel Through Web Development
&lt;/h2&gt;

&lt;p&gt;From the early days of web development, we’ve accumulated &lt;strong&gt;a massive amount of legacy code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Different eras.&lt;br&gt;
Different teams.&lt;br&gt;
Different skill levels.&lt;br&gt;
Different pressures.&lt;/p&gt;

&lt;p&gt;And as a result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One file uses a clean pattern&lt;/li&gt;
&lt;li&gt;The next file uses a completely different algorithm&lt;/li&gt;
&lt;li&gt;Another file ignores architecture entirely&lt;/li&gt;
&lt;li&gt;Naming conventions drift&lt;/li&gt;
&lt;li&gt;State flows sideways&lt;/li&gt;
&lt;li&gt;Business logic leaks into UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not because people were lazy — but because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standards didn’t exist yet&lt;/li&gt;
&lt;li&gt;Deadlines were brutal&lt;/li&gt;
&lt;li&gt;Experts weren’t always available&lt;/li&gt;
&lt;li&gt;Products had to ship to survive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And here’s the important part:&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;These systems still work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They’re in production.&lt;br&gt;
They make money.&lt;br&gt;
They have users.&lt;br&gt;
They cannot simply be “rewritten from scratch.”&lt;/p&gt;

&lt;p&gt;This is the reality AI is walking into.&lt;/p&gt;




&lt;h2&gt;
  
  
  Legacy Chaos Is Not a Bug — It’s a Historical Artifact
&lt;/h2&gt;

&lt;p&gt;Many modern engineers open a legacy project and think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Who wrote this?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The real answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Time did.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Legacy projects are not just codebases — they’re &lt;strong&gt;archaeological layers&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Old frameworks mixed with new ones&lt;/li&gt;
&lt;li&gt;Patterns half‑adopted&lt;/li&gt;
&lt;li&gt;Business rules encoded in strange places&lt;/li&gt;
&lt;li&gt;UX decisions driven by domain constraints outsiders don’t see&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yet — the system behaves correctly.&lt;/p&gt;

&lt;p&gt;That correctness is not accidental.&lt;/p&gt;




&lt;h2&gt;
  
  
  This Is Where AI Enters the Picture
&lt;/h2&gt;

&lt;p&gt;AI is &lt;em&gt;perfectly positioned&lt;/em&gt; to handle one specific kind of work:&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 The Work of Coders
&lt;/h3&gt;

&lt;p&gt;AI can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactor inconsistent files&lt;/li&gt;
&lt;li&gt;Normalize styles and patterns&lt;/li&gt;
&lt;li&gt;Translate between paradigms&lt;/li&gt;
&lt;li&gt;Explain what a piece of code does in isolation&lt;/li&gt;
&lt;li&gt;Generate boilerplate safely and fast&lt;/li&gt;
&lt;li&gt;Fill in missing implementation details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI is exceptional at local reasoning.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Give it a file.&lt;br&gt;
Give it a function.&lt;br&gt;
Give it a pattern.&lt;/p&gt;

&lt;p&gt;It will help.&lt;br&gt;
A lot.&lt;/p&gt;




&lt;h2&gt;
  
  
  But Software Engineering Is Not Local Reasoning
&lt;/h2&gt;

&lt;p&gt;Here’s the hard boundary.&lt;/p&gt;

&lt;p&gt;Software engineering is about &lt;strong&gt;global understanding&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why this system exists&lt;/li&gt;
&lt;li&gt;What problem it actually solves&lt;/li&gt;
&lt;li&gt;Which parts must never break&lt;/li&gt;
&lt;li&gt;How files interact &lt;em&gt;indirectly&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;How business logic flows across layers&lt;/li&gt;
&lt;li&gt;How UX expectations shape architecture&lt;/li&gt;
&lt;li&gt;What constraints come from the domain itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This knowledge lives &lt;strong&gt;between files&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not inside them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Invisible Glue: Business Logic &amp;amp; Domain Knowledge
&lt;/h2&gt;

&lt;p&gt;Legacy systems often look chaotic &lt;em&gt;until you understand the business&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Then suddenly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;That weird conditional makes sense&lt;/li&gt;
&lt;li&gt;That duplicated logic exists for a reason&lt;/li&gt;
&lt;li&gt;That “bad” abstraction protects a fragile workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI does not &lt;em&gt;own&lt;/em&gt; this context.&lt;/p&gt;

&lt;p&gt;Software engineers do — together with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product managers&lt;/li&gt;
&lt;li&gt;UX designers&lt;/li&gt;
&lt;li&gt;Domain experts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not accidental.&lt;br&gt;
This is &lt;strong&gt;human‑centered knowledge&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI Will Terraform Software Engineering — Not Erase It
&lt;/h2&gt;

&lt;p&gt;AI is not here to delete engineers.&lt;/p&gt;

&lt;p&gt;It’s here to &lt;strong&gt;reshape the terrain&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Less time fighting syntax&lt;/li&gt;
&lt;li&gt;Less time decoding messy files&lt;/li&gt;
&lt;li&gt;Less time re‑implementing known patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More time spent on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;System design&lt;/li&gt;
&lt;li&gt;Architecture decisions&lt;/li&gt;
&lt;li&gt;Domain modeling&lt;/li&gt;
&lt;li&gt;UX trade‑offs&lt;/li&gt;
&lt;li&gt;Product thinking&lt;/li&gt;
&lt;li&gt;Long‑term evolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not replacement.&lt;/p&gt;

&lt;p&gt;This is amplification.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Shift: From Coders to Engineers
&lt;/h2&gt;

&lt;p&gt;Historically, many roles were forced to blur:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coders had to be engineers&lt;/li&gt;
&lt;li&gt;Engineers had to be historians&lt;/li&gt;
&lt;li&gt;Everyone had to fight the codebase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI absorbs the &lt;strong&gt;mechanical load&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What remains is the work that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires judgment&lt;/li&gt;
&lt;li&gt;Requires responsibility&lt;/li&gt;
&lt;li&gt;Requires understanding consequences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That work has always belonged to software engineers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;AI will &lt;strong&gt;100% do the work of coders&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But software engineering is not just writing code.&lt;/p&gt;

&lt;p&gt;It’s understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Why&lt;/em&gt; the system exists&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;How&lt;/em&gt; it survives change&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Where&lt;/em&gt; it must bend&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Where&lt;/em&gt; it must never break&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Legacy systems aren’t chaos.&lt;/p&gt;

&lt;p&gt;They’re stories.&lt;/p&gt;

&lt;p&gt;AI can help us read them faster.&lt;/p&gt;

&lt;p&gt;But humans still decide how the story continues.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Curious how others are using AI inside legacy projects without breaking production? Let’s discuss.&lt;/em&gt; 💬&lt;/p&gt;

</description>
      <category>ai</category>
      <category>career</category>
      <category>discuss</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Redux Toolkit vs React Query: Do You Really Need Both? 🤔</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Wed, 12 Nov 2025 17:49:27 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/redux-toolkit-vs-react-query-do-you-really-need-both-3m9d</link>
      <guid>https://forem.com/taronvardanyan/redux-toolkit-vs-react-query-do-you-really-need-both-3m9d</guid>
      <description>&lt;p&gt;For years, &lt;strong&gt;Redux&lt;/strong&gt; was the go-to for state management in React apps.&lt;br&gt;&lt;br&gt;
Then came &lt;strong&gt;React Query&lt;/strong&gt; (now &lt;strong&gt;TanStack Query&lt;/strong&gt;) — and it changed how we handle &lt;strong&gt;server state&lt;/strong&gt; forever.&lt;/p&gt;

&lt;p&gt;But here's the confusion many developers face:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“If I’m using React Query, do I still need Redux?”&lt;br&gt;&lt;br&gt;
“Can Redux Toolkit replace React Query?”  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s clear the fog. 🌫️&lt;/p&gt;


&lt;h2&gt;
  
  
  🧠 First — Two Different Problems
&lt;/h2&gt;

&lt;p&gt;Before comparing them, it’s crucial to understand &lt;strong&gt;what each tool actually manages&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type of State&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client State&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Data that exists only in the UI or app memory.&lt;/td&gt;
&lt;td&gt;Modal open/close, filters, active tab&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Server State&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Data fetched from APIs or databases, often cached.&lt;/td&gt;
&lt;td&gt;Users list, product data, comments&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;🧩 &lt;strong&gt;Redux Toolkit (RTK)&lt;/strong&gt; → best for &lt;strong&gt;client state&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;React Query&lt;/strong&gt; → best for &lt;strong&gt;server state&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧩 Redux Toolkit Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Redux Toolkit (RTK)&lt;/strong&gt; is the official, modern way to write Redux — without the boilerplate.&lt;/p&gt;

&lt;p&gt;It’s great for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local or global UI state&lt;/li&gt;
&lt;li&gt;Caching small API responses&lt;/li&gt;
&lt;li&gt;Complex app logic&lt;/li&gt;
&lt;li&gt;Predictable, centralized state updates&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Installation
&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; @reduxjs/toolkit react-redux
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;configureStore&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@reduxjs/toolkit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useDispatch&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&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="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&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="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterSlice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Predictable, centralized store&lt;/li&gt;
&lt;li&gt;Time-travel debugging and middleware&lt;/li&gt;
&lt;li&gt;Immutable updates via Immer&lt;/li&gt;
&lt;li&gt;Integration with async logic via &lt;code&gt;createAsyncThunk&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Scales beautifully for enterprise apps&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Boilerplate compared to local hooks&lt;/li&gt;
&lt;li&gt;Manual caching and invalidation for API data&lt;/li&gt;
&lt;li&gt;More setup for smaller apps&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🌐 React Query (TanStack Query) Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React Query&lt;/strong&gt; manages &lt;strong&gt;remote data fetching, caching, and syncing&lt;/strong&gt; — not app logic.&lt;/p&gt;

&lt;p&gt;It automates the painful parts of server-state management:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fetching&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Stale data invalidation&lt;/li&gt;
&lt;li&gt;Background updates&lt;/li&gt;
&lt;li&gt;Pagination &amp;amp; optimistic updates&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Installation
&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; @tanstack/react-query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;QueryClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;QueryClientProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tanstack/react-query&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queryClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;QueryClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Todos&lt;/span&gt;&lt;span class="p"&gt;()&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;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;queryKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;queryFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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="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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Error: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&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;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Automatic caching and refetching&lt;/li&gt;
&lt;li&gt;Handles background sync and retry logic&lt;/li&gt;
&lt;li&gt;No reducers or actions — pure hooks&lt;/li&gt;
&lt;li&gt;Amazing devtools for debugging&lt;/li&gt;
&lt;li&gt;Ideal for data-heavy apps (dashboards, SaaS)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Not designed for client UI state&lt;/li&gt;
&lt;li&gt;No central store or global reducer logic&lt;/li&gt;
&lt;li&gt;Limited control over global mutation side-effects&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ⚔️ Head-to-Head Comparison
&lt;/h2&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;Redux Toolkit&lt;/th&gt;
&lt;th&gt;React Query&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Client/Global State&lt;/td&gt;
&lt;td&gt;Server/Remote State&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Source&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Local or manual API calls&lt;/td&gt;
&lt;td&gt;Fetched via queries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Caching&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Invalidation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Setup Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Simple&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Global Store&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DevTools&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Redux DevTools&lt;/td&gt;
&lt;td&gt;React Query Devtools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best For&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;State logic, app-wide control&lt;/td&gt;
&lt;td&gt;Fetching &amp;amp; syncing backend data&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  🔀 Can You Use Both Together?
&lt;/h2&gt;

&lt;p&gt;Absolutely — and many real-world apps &lt;strong&gt;do&lt;/strong&gt;. 💪&lt;/p&gt;

&lt;p&gt;They solve &lt;strong&gt;different concerns&lt;/strong&gt;, and together they shine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;React Query&lt;/strong&gt; for all &lt;strong&gt;server communication&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Redux Toolkit&lt;/strong&gt; for &lt;strong&gt;UI and app logic&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example integration:&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="c1"&gt;// react-query handles data&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;fetchTodos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// redux handles UI&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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;filteredTodos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;todos&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach keeps your &lt;strong&gt;data layer&lt;/strong&gt; and &lt;strong&gt;UI layer&lt;/strong&gt; cleanly separated.&lt;/p&gt;




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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You Need...&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;To manage app-wide UI state&lt;/td&gt;
&lt;td&gt;Redux Toolkit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To handle API fetching and caching&lt;/td&gt;
&lt;td&gt;React Query&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To replace Redux entirely&lt;/td&gt;
&lt;td&gt;React Query + local state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;To handle everything with structure&lt;/td&gt;
&lt;td&gt;Combine both&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;&lt;strong&gt;Redux Toolkit&lt;/strong&gt; and &lt;strong&gt;React Query&lt;/strong&gt; aren’t competitors — they’re &lt;strong&gt;complements&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Think of them like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧠 Redux: Your app’s brain (logic, actions, state)&lt;br&gt;&lt;br&gt;
🌍 React Query: Your app’s bloodstream (data flow and sync)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use the right tool for the right job — and your React app will stay clean, fast, and predictable.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you liked this post, follow me for more deep dives on React architecture and state management!&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://dev.to/taronvardanyan"&gt;@taronvardanyan &lt;/a&gt;&lt;/p&gt;

</description>
      <category>redux</category>
      <category>reactquery</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Node Package Managers Compared: npm vs Yarn vs pnpm vs Bun ⚙️</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Wed, 12 Nov 2025 12:40:49 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/node-package-managers-compared-npm-vs-yarn-vs-pnpm-vs-bun-1kd1</link>
      <guid>https://forem.com/taronvardanyan/node-package-managers-compared-npm-vs-yarn-vs-pnpm-vs-bun-1kd1</guid>
      <description>&lt;p&gt;Every JavaScript developer installs packages — but not everyone realizes &lt;strong&gt;how different package managers really are&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Whether you’re building a side project or maintaining a massive monorepo, the choice between &lt;strong&gt;npm&lt;/strong&gt;, &lt;strong&gt;Yarn&lt;/strong&gt;, &lt;strong&gt;pnpm&lt;/strong&gt;, and &lt;strong&gt;Bun&lt;/strong&gt; can affect your speed, storage, and developer experience.&lt;/p&gt;

&lt;p&gt;Let’s explore what sets them apart.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 npm — The Classic Default
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;npm (Node Package Manager)&lt;/strong&gt; is the original and still most widely used tool for managing Node.js dependencies.&lt;br&gt;&lt;br&gt;
It ships with Node.js, making it the easiest to start with.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Comes preinstalled with Node.js
&lt;/li&gt;
&lt;li&gt;Huge ecosystem (1M+ packages)
&lt;/li&gt;
&lt;li&gt;Reliable &lt;code&gt;package-lock.json&lt;/code&gt; for deterministic installs
&lt;/li&gt;
&lt;li&gt;Workspaces support for monorepos
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Slower installs compared to modern alternatives
&lt;/li&gt;
&lt;li&gt;Historically prone to dependency duplication
&lt;/li&gt;
&lt;li&gt;Larger node_modules size
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Example commands
&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;lodash  
npm uninstall lodash  
npm run build  
npm ci  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Yarn — Speed and Reliability
&lt;/h2&gt;

&lt;p&gt;Created by Facebook, &lt;strong&gt;Yarn&lt;/strong&gt; was a response to npm’s early performance and consistency issues.&lt;br&gt;&lt;br&gt;
It introduced &lt;strong&gt;lock files&lt;/strong&gt;, &lt;strong&gt;parallel installs&lt;/strong&gt;, and &lt;strong&gt;offline caching&lt;/strong&gt;, setting new standards for package management.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Faster installs than npm (especially v1)
&lt;/li&gt;
&lt;li&gt;Predictable dependency trees (&lt;code&gt;yarn.lock&lt;/code&gt;)
&lt;/li&gt;
&lt;li&gt;Offline caching
&lt;/li&gt;
&lt;li&gt;Great for monorepos with Yarn Workspaces
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Multiple major versions (v1, v2, v3) can cause confusion
&lt;/li&gt;
&lt;li&gt;Plug’n’Play (PnP) may break some tools
&lt;/li&gt;
&lt;li&gt;Slightly steeper learning curve
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Example commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn add lodash  
yarn remove lodash  
yarn build  
yarn &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--immutable&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🪶 pnpm — Performance and Efficiency
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;pnpm&lt;/strong&gt; (short for &lt;em&gt;performant npm&lt;/em&gt;) takes a smart approach to dependency storage.&lt;br&gt;&lt;br&gt;
Instead of duplicating packages for every project, it uses &lt;strong&gt;a global content-addressable store&lt;/strong&gt; and &lt;strong&gt;symlinks&lt;/strong&gt;, saving tons of disk space.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Blazing fast installs
&lt;/li&gt;
&lt;li&gt;Minimal disk usage via global cache
&lt;/li&gt;
&lt;li&gt;Strict dependency isolation — avoids “phantom dependencies”
&lt;/li&gt;
&lt;li&gt;Excellent monorepo support via &lt;code&gt;pnpm workspaces&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Some CI/CD or tooling setups need extra tweaks
&lt;/li&gt;
&lt;li&gt;Learning curve if you’re coming from npm
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Example commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add lodash  
pnpm remove lodash  
pnpm run build  
pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--frozen-lockfile&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧈 Bun — The New All-in-One Runtime
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Bun&lt;/strong&gt; is more than a package manager — it’s a &lt;strong&gt;complete JavaScript runtime&lt;/strong&gt;, written in &lt;strong&gt;Zig&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
It bundles, runs, and installs dependencies at lightning speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Incredibly fast installs and scripts
&lt;/li&gt;
&lt;li&gt;Bundler + test runner + runtime in one
&lt;/li&gt;
&lt;li&gt;Fully npm-compatible
&lt;/li&gt;
&lt;li&gt;Zero setup — works out of the box
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❌ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Still evolving; some Node APIs aren’t 100% supported
&lt;/li&gt;
&lt;li&gt;Smaller ecosystem than Node/npm
&lt;/li&gt;
&lt;li&gt;Potential compatibility issues for older packages
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📦 Example commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nb"&gt;install  
&lt;/span&gt;bun add lodash  
bun remove lodash  
bun run build  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚔️ Benchmark Snapshot
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package Manager&lt;/th&gt;
&lt;th&gt;Cold Install (s)&lt;/th&gt;
&lt;th&gt;Reinstall (s)&lt;/th&gt;
&lt;th&gt;Disk Space (MB)&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;npm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;25–30&lt;/td&gt;
&lt;td&gt;10–15&lt;/td&gt;
&lt;td&gt;250+&lt;/td&gt;
&lt;td&gt;Reliable but slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Yarn&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;15–20&lt;/td&gt;
&lt;td&gt;8–10&lt;/td&gt;
&lt;td&gt;220+&lt;/td&gt;
&lt;td&gt;Balanced and mature&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;pnpm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10–15&lt;/td&gt;
&lt;td&gt;4–6&lt;/td&gt;
&lt;td&gt;100–120&lt;/td&gt;
&lt;td&gt;Ultra-efficient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Bun&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3–5&lt;/td&gt;
&lt;td&gt;2–3&lt;/td&gt;
&lt;td&gt;100–110&lt;/td&gt;
&lt;td&gt;Fastest overall&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;(Results vary based on network and hardware.)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Which One Should You Use?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;You want stability and compatibility&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;npm&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You need a balance of speed and features&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yarn&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You work with monorepos or large projects&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;pnpm&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You love cutting-edge performance&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Bun&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt; → The standard and safest default.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Yarn&lt;/strong&gt; → Familiar, stable, and faster than npm.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;pnpm&lt;/strong&gt; → Efficient and ideal for large-scale apps.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bun&lt;/strong&gt; → Future-facing speed demon.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tool has a unique philosophy — your best choice depends on &lt;strong&gt;team size, workflow, and ecosystem compatibility&lt;/strong&gt;.&lt;/p&gt;




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

&lt;p&gt;The Node.js world is evolving fast.&lt;br&gt;&lt;br&gt;
What used to be a single choice (&lt;code&gt;npm&lt;/code&gt;) is now a diverse ecosystem of package managers that prioritize &lt;strong&gt;speed&lt;/strong&gt;, &lt;strong&gt;reliability&lt;/strong&gt;, and &lt;strong&gt;efficiency&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you haven’t yet, try running your next install with &lt;strong&gt;pnpm&lt;/strong&gt; or &lt;strong&gt;Bun&lt;/strong&gt; — the difference might surprise you.&lt;/p&gt;

&lt;p&gt;Happy coding! ⚙️✨&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Follow me for more deep dives into the modern JavaScript ecosystem!&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://dev.to/taronvardanyan"&gt;@taronvardanyan &lt;/a&gt;&lt;/p&gt;

</description>
      <category>bunjs</category>
      <category>pnpm</category>
      <category>yarn</category>
      <category>npm</category>
    </item>
    <item>
      <title>Atomic State Management in React: Zustand vs Jotai vs Recoil ⚛️</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Wed, 12 Nov 2025 07:37:55 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/atomic-state-management-in-react-zustand-vs-jotai-vs-recoil-j5p</link>
      <guid>https://forem.com/taronvardanyan/atomic-state-management-in-react-zustand-vs-jotai-vs-recoil-j5p</guid>
      <description>&lt;p&gt;React’s built-in &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useContext&lt;/code&gt; work great — until they don’t.&lt;br&gt;&lt;br&gt;
When your app scales, managing shared and deeply nested state becomes messy. That’s where &lt;strong&gt;atomic state management&lt;/strong&gt; libraries come in.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore three of the most popular libraries that embrace this model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pmndrs/zustand" rel="noopener noreferrer"&gt;Zustand&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pmndrs/jotai" rel="noopener noreferrer"&gt;Jotai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://recoiljs.org/" rel="noopener noreferrer"&gt;Recoil&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive into how each works, their strengths, and which might fit your project best.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 What is Atomic State Management?
&lt;/h2&gt;

&lt;p&gt;Traditional state managers like Redux rely on &lt;strong&gt;a single global store&lt;/strong&gt; — all data flows through a central structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomic state&lt;/strong&gt; flips that idea.&lt;br&gt;&lt;br&gt;
Instead of one big store, your state is composed of &lt;strong&gt;independent atoms&lt;/strong&gt; — small, isolated units of state that can be subscribed to directly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each atom updates only the components that use it — no global re-renders, no boilerplate, no reducers.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  ⚡ Zustand: Minimal and Fast
&lt;/h2&gt;

&lt;p&gt;Zustand is a &lt;strong&gt;tiny, unopinionated state manager&lt;/strong&gt; that feels like using plain React hooks — but with superpowers.&lt;br&gt;
&lt;/p&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;zustand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zustand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kd"&gt;set&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="na"&gt;count&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="na"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&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="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;increase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increase&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Minimal API (~1KB gzipped)&lt;/li&gt;
&lt;li&gt;Direct, predictable mutations&lt;/li&gt;
&lt;li&gt;Excellent for medium-to-large apps&lt;/li&gt;
&lt;li&gt;Works outside React (e.g. vanilla JS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No built-in async or atom logic (you write it manually)&lt;/li&gt;
&lt;li&gt;Less declarative than Jotai/Recoil&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧬 Jotai: Primitives for React State
&lt;/h2&gt;

&lt;p&gt;Jotai (which literally means &lt;em&gt;“atom”&lt;/em&gt; in Japanese) provides &lt;strong&gt;atomic state primitives&lt;/strong&gt; — tiny pieces of state managed independently.&lt;br&gt;
&lt;/p&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;jotai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useAtom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jotai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countAtom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atom&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;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAtom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countAtom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Simple mental model (like Recoil, but smaller)&lt;/li&gt;
&lt;li&gt;Derivable atoms (&lt;code&gt;atom(get =&amp;gt; get(otherAtom) + 1)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;SSR-friendly&lt;/li&gt;
&lt;li&gt;Built on React’s native &lt;code&gt;useSyncExternalStore&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Requires you to think atomically — might feel verbose for simple apps&lt;/li&gt;
&lt;li&gt;Lacks centralized debugging tools (yet)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🪶 Recoil: Facebook’s Take on Atoms and Selectors
&lt;/h2&gt;

&lt;p&gt;Recoil was built by Facebook to solve React’s global state challenges.&lt;br&gt;&lt;br&gt;
It introduces &lt;strong&gt;atoms&lt;/strong&gt; and &lt;strong&gt;selectors&lt;/strong&gt; for derived data.&lt;br&gt;
&lt;/p&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;recoil
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRecoilState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRecoilValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recoil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countAtom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;default&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="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doubleCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;doubleCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countAtom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRecoilState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countAtom&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;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRecoilValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doubleCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Double: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;double&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increase&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mature, production-ready (used at Meta)&lt;/li&gt;
&lt;li&gt;Powerful selectors (derived/computed state)&lt;/li&gt;
&lt;li&gt;Great dev tools and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Larger bundle (~15KB)&lt;/li&gt;
&lt;li&gt;Requires &lt;code&gt;RecoilRoot&lt;/code&gt; provider&lt;/li&gt;
&lt;li&gt;Still React-only (no vanilla JS usage)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚖️ When to Choose What
&lt;/h2&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;Best For&lt;/th&gt;
&lt;th&gt;API Style&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Ecosystem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zustand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scalable apps needing minimal setup&lt;/td&gt;
&lt;td&gt;Mutations&lt;/td&gt;
&lt;td&gt;~1KB&lt;/td&gt;
&lt;td&gt;Strong (PMNDRS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Jotai&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Declarative atomic apps&lt;/td&gt;
&lt;td&gt;Primitives&lt;/td&gt;
&lt;td&gt;~3KB&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recoil&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large apps needing selectors and tooling&lt;/td&gt;
&lt;td&gt;Atoms + Selectors&lt;/td&gt;
&lt;td&gt;~15KB&lt;/td&gt;
&lt;td&gt;Mature&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zustand&lt;/strong&gt; → If you want simplicity and speed.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jotai&lt;/strong&gt; → If you want minimalism with atomic reactivity.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recoil&lt;/strong&gt; → If you want structure, selectors, and dev tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three are excellent — the “best” choice depends on your project’s scale and mental model preference.&lt;/p&gt;




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

&lt;p&gt;Atomic state management isn’t just a buzzword — it’s a mindset shift.&lt;br&gt;&lt;br&gt;
It helps React apps stay predictable, performant, and modular as they grow.&lt;/p&gt;

&lt;p&gt;If you haven’t tried these yet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;strong&gt;Zustand&lt;/strong&gt; to grasp the basics.&lt;/li&gt;
&lt;li&gt;Move to &lt;strong&gt;Jotai&lt;/strong&gt; or &lt;strong&gt;Recoil&lt;/strong&gt; for more reactive patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding! ⚛️✨&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you enjoyed this, follow me for more deep dives on modern React state patterns!&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://dev.to/taronvardanyan"&gt;@taronva&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>zustand</category>
      <category>jotai</category>
      <category>recoil</category>
    </item>
    <item>
      <title>Atomic State Management in React: Zustand vs Jotai vs Recoil ⚛️</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Wed, 12 Nov 2025 07:37:55 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/atomic-state-management-in-react-zustand-vs-jotai-vs-recoil-35cp</link>
      <guid>https://forem.com/taronvardanyan/atomic-state-management-in-react-zustand-vs-jotai-vs-recoil-35cp</guid>
      <description>&lt;p&gt;React’s built-in &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useContext&lt;/code&gt; work great — until they don’t.&lt;br&gt;&lt;br&gt;
When your app scales, managing shared and deeply nested state becomes messy. That’s where &lt;strong&gt;atomic state management&lt;/strong&gt; libraries come in.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore three of the most popular libraries that embrace this model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/pmndrs/zustand" rel="noopener noreferrer"&gt;Zustand&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pmndrs/jotai" rel="noopener noreferrer"&gt;Jotai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://recoiljs.org/" rel="noopener noreferrer"&gt;Recoil&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive into how each works, their strengths, and which might fit your project best.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 What is Atomic State Management?
&lt;/h2&gt;

&lt;p&gt;Traditional state managers like Redux rely on &lt;strong&gt;a single global store&lt;/strong&gt; — all data flows through a central structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Atomic state&lt;/strong&gt; flips that idea.&lt;br&gt;&lt;br&gt;
Instead of one big store, your state is composed of &lt;strong&gt;independent atoms&lt;/strong&gt; — small, isolated units of state that can be subscribed to directly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each atom updates only the components that use it — no global re-renders, no boilerplate, no reducers.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  ⚡ Zustand: Minimal and Fast
&lt;/h2&gt;

&lt;p&gt;Zustand is a &lt;strong&gt;tiny, unopinionated state manager&lt;/strong&gt; that feels like using plain React hooks — but with superpowers.&lt;br&gt;
&lt;/p&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;zustand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zustand&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kd"&gt;set&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="na"&gt;count&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="na"&gt;increase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&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="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;count&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;increase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increase&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Minimal API (~1KB gzipped)&lt;/li&gt;
&lt;li&gt;Direct, predictable mutations&lt;/li&gt;
&lt;li&gt;Excellent for medium-to-large apps&lt;/li&gt;
&lt;li&gt;Works outside React (e.g. vanilla JS)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No built-in async or atom logic (you write it manually)&lt;/li&gt;
&lt;li&gt;Less declarative than Jotai/Recoil&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧬 Jotai: Primitives for React State
&lt;/h2&gt;

&lt;p&gt;Jotai (which literally means &lt;em&gt;“atom”&lt;/em&gt; in Japanese) provides &lt;strong&gt;atomic state primitives&lt;/strong&gt; — tiny pieces of state managed independently.&lt;br&gt;
&lt;/p&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;jotai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useAtom&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jotai&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countAtom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atom&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;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAtom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countAtom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Simple mental model (like Recoil, but smaller)&lt;/li&gt;
&lt;li&gt;Derivable atoms (&lt;code&gt;atom(get =&amp;gt; get(otherAtom) + 1)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;SSR-friendly&lt;/li&gt;
&lt;li&gt;Built on React’s native &lt;code&gt;useSyncExternalStore&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Requires you to think atomically — might feel verbose for simple apps&lt;/li&gt;
&lt;li&gt;Lacks centralized debugging tools (yet)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🪶 Recoil: Facebook’s Take on Atoms and Selectors
&lt;/h2&gt;

&lt;p&gt;Recoil was built by Facebook to solve React’s global state challenges.&lt;br&gt;&lt;br&gt;
It introduces &lt;strong&gt;atoms&lt;/strong&gt; and &lt;strong&gt;selectors&lt;/strong&gt; for derived data.&lt;br&gt;
&lt;/p&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;recoil
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRecoilState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRecoilValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recoil&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countAtom&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;default&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="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doubleCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;doubleCount&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countAtom&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&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;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRecoilState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countAtom&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;double&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRecoilValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doubleCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Count: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Double: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;double&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Increase&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;
  
  
  ✅ Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mature, production-ready (used at Meta)&lt;/li&gt;
&lt;li&gt;Powerful selectors (derived/computed state)&lt;/li&gt;
&lt;li&gt;Great dev tools and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚠️ Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Larger bundle (~15KB)&lt;/li&gt;
&lt;li&gt;Requires &lt;code&gt;RecoilRoot&lt;/code&gt; provider&lt;/li&gt;
&lt;li&gt;Still React-only (no vanilla JS usage)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚖️ When to Choose What
&lt;/h2&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;Best For&lt;/th&gt;
&lt;th&gt;API Style&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Ecosystem&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zustand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scalable apps needing minimal setup&lt;/td&gt;
&lt;td&gt;Mutations&lt;/td&gt;
&lt;td&gt;~1KB&lt;/td&gt;
&lt;td&gt;Strong (PMNDRS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Jotai&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Declarative atomic apps&lt;/td&gt;
&lt;td&gt;Primitives&lt;/td&gt;
&lt;td&gt;~3KB&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Recoil&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Large apps needing selectors and tooling&lt;/td&gt;
&lt;td&gt;Atoms + Selectors&lt;/td&gt;
&lt;td&gt;~15KB&lt;/td&gt;
&lt;td&gt;Mature&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zustand&lt;/strong&gt; → If you want simplicity and speed.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jotai&lt;/strong&gt; → If you want minimalism with atomic reactivity.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recoil&lt;/strong&gt; → If you want structure, selectors, and dev tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three are excellent — the “best” choice depends on your project’s scale and mental model preference.&lt;/p&gt;




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

&lt;p&gt;Atomic state management isn’t just a buzzword — it’s a mindset shift.&lt;br&gt;&lt;br&gt;
It helps React apps stay predictable, performant, and modular as they grow.&lt;/p&gt;

&lt;p&gt;If you haven’t tried these yet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with &lt;strong&gt;Zustand&lt;/strong&gt; to grasp the basics.&lt;/li&gt;
&lt;li&gt;Move to &lt;strong&gt;Jotai&lt;/strong&gt; or &lt;strong&gt;Recoil&lt;/strong&gt; for more reactive patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding! ⚛️✨&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you enjoyed this, follow me for more deep dives on modern React state patterns!&lt;/em&gt;&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://dev.to/taronvardanyan"&gt;@taronva&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>zustand</category>
      <category>jotai</category>
      <category>recoil</category>
    </item>
    <item>
      <title>React 19.2: Deep Dive into Activity and useEffectEvent</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Mon, 10 Nov 2025 10:52:47 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/react-192-deep-dive-into-activity-and-useeffectevent-1f1g</link>
      <guid>https://forem.com/taronvardanyan/react-192-deep-dive-into-activity-and-useeffectevent-1f1g</guid>
      <description>&lt;h3&gt;
  
  
  React 19.2: Deep Dive into Activity and useEffectEvent
&lt;/h3&gt;

&lt;p&gt;React 19.2 introduces two exciting new developer APIs: &lt;strong&gt;Activity&lt;/strong&gt; and &lt;strong&gt;useEffectEvent&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
These features make it easier to manage hidden UI, preserve component state, and handle effects without stale closures or unnecessary re-renders.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore each in detail.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Activity Component
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What it is
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Activity component&lt;/strong&gt; allows you to manage parts of your UI that you want to hide or defer &lt;strong&gt;without fully unmounting them&lt;/strong&gt;, while controlling effect behavior and update priority.  &lt;/p&gt;

&lt;p&gt;It provides a middle ground between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conditional rendering (&lt;code&gt;{visible &amp;amp;&amp;amp; &amp;lt;Component /&amp;gt;}&lt;/code&gt;), which unmounts the component and loses state.&lt;/li&gt;
&lt;li&gt;CSS-based hiding (&lt;code&gt;display: none&lt;/code&gt;), which preserves state but keeps effects running and consuming resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Activity component lets you &lt;strong&gt;preserve state while pausing effects&lt;/strong&gt; when a subtree is hidden.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Wrap a subtree inside &lt;code&gt;&amp;lt;Activity mode={...}&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Supported modes in v19.2 are &lt;code&gt;visible&lt;/code&gt; and &lt;code&gt;hidden&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;visible&lt;/strong&gt;: the component is shown, and effects run normally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hidden&lt;/strong&gt;: effects are paused/unmounted, but state is preserved. Updates may be deprioritized.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This makes Activity ideal for components that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are hidden temporarily (tabs, modals, sidebars).&lt;/li&gt;
&lt;li&gt;Need their internal state preserved while not actively rendering or running effects.&lt;/li&gt;
&lt;li&gt;Benefit from deferred updates for performance optimization.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Key Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tab panels that preserve forms or input state when switching tabs.&lt;/li&gt;
&lt;li&gt;Sidebars or drawers that toggle visibility but keep scroll position and input data.&lt;/li&gt;
&lt;li&gt;Pre-rendering non-critical UI to improve perceived responsiveness.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Important Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hidden components &lt;strong&gt;won’t run effects&lt;/strong&gt;, so data fetching or subscriptions must be handled carefully.&lt;/li&gt;
&lt;li&gt;Updates are deferred, so background updates may not occur until visible.&lt;/li&gt;
&lt;li&gt;Behavior differs from unmounting — components expecting cleanup on hide may need adjustment.&lt;/li&gt;
&lt;li&gt;Check compatibility with SSR and frameworks like Next.js.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 useEffectEvent Hook
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What it is
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;useEffectEvent&lt;/strong&gt; hook allows you to define callbacks that &lt;strong&gt;always see the latest props and state&lt;/strong&gt; without causing unnecessary effect re-runs.  &lt;/p&gt;

&lt;p&gt;It solves the common “stale closure” problem in React hooks, where callbacks inside &lt;code&gt;useEffect&lt;/code&gt; may reference outdated state or require overly broad dependency arrays.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Define an event callback using &lt;code&gt;useEffectEvent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Inside the callback, you can safely access the latest state and props.&lt;/li&gt;
&lt;li&gt;The callback does &lt;strong&gt;not&lt;/strong&gt; trigger the effect to re-run unnecessarily.&lt;/li&gt;
&lt;li&gt;This separates reactive effect setup/cleanup from event logic that depends on dynamic values.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoids stale closures in callbacks inside effects.&lt;/li&gt;
&lt;li&gt;Reduces unnecessary effect re-executions.&lt;/li&gt;
&lt;li&gt;Cleans up code by separating setup/cleanup logic from event handling.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Key Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Still requires proper effect dependencies; it is not a shortcut to ignore dependency arrays.&lt;/li&gt;
&lt;li&gt;Event callbacks should not be treated as general-purpose functions passed around arbitrarily.&lt;/li&gt;
&lt;li&gt;Test behavior carefully with SSR and concurrent rendering scenarios.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔑 Summary
&lt;/h2&gt;

&lt;p&gt;React 19.2 introduces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Activity component&lt;/strong&gt;: Hide UI while preserving state and pausing effects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useEffectEvent hook&lt;/strong&gt;: Define event callbacks that always see the latest props/state without unnecessary effect reruns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tools improve developer ergonomics and app performance, particularly in complex UI-heavy applications and server-rendered environments.&lt;/p&gt;




&lt;p&gt;💬 Have you tried using Activity or useEffectEvent in your projects yet?&lt;br&gt;&lt;br&gt;
How do you see them fitting into your component patterns? Let’s discuss in the comments below.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>hooks</category>
    </item>
    <item>
      <title>Arcjet: Developer-First Security for Modern Apps</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Mon, 10 Nov 2025 09:41:51 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/arcjet-developer-first-security-for-modern-apps-23im</link>
      <guid>https://forem.com/taronvardanyan/arcjet-developer-first-security-for-modern-apps-23im</guid>
      <description>&lt;p&gt;In today’s world of serverless architectures, edge deployments, and AI-driven applications, security needs to evolve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://arcjet.com" rel="noopener noreferrer"&gt;Arcjet&lt;/a&gt;&lt;/strong&gt; is a new player aiming to make security &lt;em&gt;painless for developers&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
It brings intelligent protection like bot blocking, rate limiting, and abuse prevention directly into your code — not just around it.&lt;/p&gt;

&lt;p&gt;In this post, we’ll explore what Arcjet does, why it matters, and where it fits in a modern developer workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚨 The Modern Security Challenge
&lt;/h2&gt;

&lt;p&gt;Traditional app security used to rely on the fortress model — one monolithic app behind one big firewall.&lt;br&gt;&lt;br&gt;
But that approach no longer works in 2025.&lt;/p&gt;

&lt;p&gt;Today’s applications are distributed across microservices, edge functions, and serverless runtimes.&lt;br&gt;&lt;br&gt;
They face threats like automated scraping, signup abuse, API misuse, and token spam.  &lt;/p&gt;

&lt;p&gt;Developers now need &lt;strong&gt;security that integrates with their code&lt;/strong&gt;, not an external layer they have to maintain separately.&lt;/p&gt;

&lt;p&gt;Arcjet’s philosophy is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Bring security into your runtime — where your logic already lives.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧰 What Arcjet Offers
&lt;/h2&gt;

&lt;p&gt;Arcjet focuses on giving developers modern, programmable security tools that work the way they build software.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bot detection and blocking&lt;/strong&gt; — identify and stop malicious automated traffic.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context-aware rate limiting&lt;/strong&gt; — throttle requests dynamically based on user role, plan, or endpoint.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email validation&lt;/strong&gt; — catch disposable or spammy signups before they reach your database.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abuse prevention and data redaction&lt;/strong&gt; — safeguard sensitive routes and forms.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer-first SDKs&lt;/strong&gt; — built for Node.js, Deno, Bun, and Next.js environments.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generous free tier&lt;/strong&gt; — includes multiple rules and developer seats for small teams or startups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because Arcjet operates directly in your code, it has full request context — meaning it can make smarter decisions than a traditional external firewall.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Getting Started at a High Level
&lt;/h2&gt;

&lt;p&gt;Setting up Arcjet typically follows a few straightforward steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign up at &lt;a href="https://arcjet.com" rel="noopener noreferrer"&gt;arcjet.com&lt;/a&gt; and create a project.
&lt;/li&gt;
&lt;li&gt;Install the SDK that matches your runtime (for example, Node.js or Next.js).
&lt;/li&gt;
&lt;li&gt;Define rules that control how your app reacts to different traffic or abuse conditions.
&lt;/li&gt;
&lt;li&gt;Monitor events, blocked bots, and rate limits from the Arcjet dashboard.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This design lets you manage security as part of your normal development workflow — versioned, testable, and easy to evolve.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Where Arcjet Fits Best
&lt;/h2&gt;

&lt;p&gt;Arcjet fits particularly well in use cases where developers need contextual, fine-grained control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SaaS applications with different usage tiers or quotas.
&lt;/li&gt;
&lt;li&gt;Public APIs that need protection from bots and scrapers.
&lt;/li&gt;
&lt;li&gt;Serverless or edge-hosted applications without a traditional network perimeter.
&lt;/li&gt;
&lt;li&gt;Teams looking to shift security “left” — building it directly into their codebase.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Why Arcjet Stands Out
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built for developers:&lt;/strong&gt; Unlike most security tools aimed at ops teams, Arcjet integrates right into your code.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modern threat coverage:&lt;/strong&gt; It tackles issues like API abuse, automated scraping, and even AI token misuse.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong early momentum:&lt;/strong&gt; Arcjet raised a $3.6M seed round in 2024 to expand SDK support and developer features.
&lt;em&gt;Source: &lt;a href="https://seedcamp.com/views/arcjet-raises-3-6m-seed-funding-to-help-developers-protect-their-apps-in-production/" rel="noopener noreferrer"&gt;Seedcamp’s announcement&lt;/a&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s security that feels like a natural extension of your app — not a separate piece of infrastructure you have to fight with.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Questions to Consider
&lt;/h2&gt;

&lt;p&gt;Before adopting Arcjet, it’s worth exploring:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How expressive and flexible is the rule engine?
&lt;/li&gt;
&lt;li&gt;What’s the performance impact in serverless or edge environments?
&lt;/li&gt;
&lt;li&gt;How reliable and accurate is the bot detection?
&lt;/li&gt;
&lt;li&gt;Can its logs integrate with tools like Sentry or Datadog?
&lt;/li&gt;
&lt;li&gt;What happens if the SDK or API is temporarily unavailable?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As with any embedded system, understanding its behavior under load or failure conditions is key.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧭 My Take
&lt;/h2&gt;

&lt;p&gt;Arcjet addresses a real gap in the modern security stack: &lt;strong&gt;the need for application-aware protection&lt;/strong&gt; that developers can actually use and control.  &lt;/p&gt;

&lt;p&gt;For SaaS, APIs, or serverless applications, Arcjet provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Granular, programmable rate limits
&lt;/li&gt;
&lt;li&gt;Smarter abuse prevention
&lt;/li&gt;
&lt;li&gt;Faster, code-driven iteration on security policies
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s not meant to replace traditional network or infrastructure protections — but it’s a powerful addition for anyone building modern apps.&lt;/p&gt;




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

&lt;p&gt;Security shouldn’t be an afterthought or a blocker.&lt;br&gt;&lt;br&gt;
With Arcjet, developers can treat security as &lt;strong&gt;part of the application logic itself&lt;/strong&gt; — configurable, testable, and deployable right alongside the rest of their code.&lt;/p&gt;

&lt;p&gt;If you’re building APIs, SaaS tools, or edge apps, &lt;strong&gt;Arcjet is worth a look&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Learn more:&lt;/strong&gt; &lt;a href="https://arcjet.com" rel="noopener noreferrer"&gt;https://arcjet.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;💬 Have you tried embedding security logic directly into your applications?&lt;br&gt;&lt;br&gt;
What do you think of the “developer-first” approach Arcjet promotes?&lt;br&gt;&lt;br&gt;
Let’s discuss in the comments 👇&lt;/p&gt;

</description>
      <category>security</category>
      <category>saas</category>
      <category>node</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Create a UI Kit with Vite + React + TypeScript + Tailwind CSS + shadcn/ui + NPM Linking</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Fri, 27 Jun 2025 12:35:14 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/create-a-ui-kit-with-vite-react-typescript-tailwind-css-shadcnui-npm-linking-5h9k</link>
      <guid>https://forem.com/taronvardanyan/create-a-ui-kit-with-vite-react-typescript-tailwind-css-shadcnui-npm-linking-5h9k</guid>
      <description>&lt;p&gt;Step-by-step guide to building and locally linking your own UI component kit using modern frontend tools.&lt;/p&gt;

&lt;h1&gt;
  
  
  🧰 Build a UI Kit with Vite + React + TypeScript + Tailwind CSS + shadcn/ui + NPM Linking
&lt;/h1&gt;

&lt;p&gt;If you're working on multiple projects or collaborating with teams, building your own &lt;strong&gt;UI Kit&lt;/strong&gt; helps create reusable, consistent components across apps.&lt;/p&gt;

&lt;p&gt;In this tutorial, you'll learn to build one using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ Vite.js with React + TypeScript
&lt;/li&gt;
&lt;li&gt;🎨 Tailwind CSS
&lt;/li&gt;
&lt;li&gt;🧱 shadcn/ui
&lt;/li&gt;
&lt;li&gt;📦 Local NPM linking (to share across apps)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we begin, ensure the following are installed on your system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt; (v18 or newer)
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pnpm.io/" rel="noopener noreferrer"&gt;pnpm&lt;/a&gt; (recommended) or you can use &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1️⃣ Create Project with Vite + React + TypeScript
&lt;/h2&gt;

&lt;p&gt;Start by scaffolding the project using Vite:&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="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="nx"&gt;vite&lt;/span&gt; &lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;kit&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;kit&lt;/span&gt;
&lt;span class="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📁 This will create a project with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Fast Vite dev server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2️⃣ Install and Configure Tailwind CSS
&lt;/h2&gt;

&lt;p&gt;Tailwind CSS is a utility-first CSS framework that lets you rapidly build custom designs.&lt;/p&gt;

&lt;h3&gt;
  
  
  📦 Install Tailwind and dependencies
&lt;/h3&gt;

&lt;p&gt;Run the following command to install Tailwind CSS along with PostCSS and Autoprefixer:&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="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;D&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="nx"&gt;postcss&lt;/span&gt; &lt;span class="nx"&gt;autoprefixer&lt;/span&gt;
&lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;tailwindcss&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create two configuration files in your project root:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tailwind.config.ts — Tailwind configuration&lt;/li&gt;
&lt;li&gt;postcss.config.js — PostCSS configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ⚙️ Configure tailwind.config.ts
&lt;/h3&gt;

&lt;p&gt;Edit the tailwind.config.ts file to specify where Tailwind should look for class names:&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="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tailwindcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./index.html&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="s1"&gt;./src/**/*.{ts,tsx}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Scan all TS and TSX files in src&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;extend&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="na"&gt;plugins&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🎨 Add Tailwind directives to your CSS
&lt;/h3&gt;

&lt;p&gt;Create or open src/index.css and add the following:&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;tailwind&lt;/span&gt; &lt;span class="nx"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧵 Import Tailwind CSS in your app entry point
&lt;/h3&gt;

&lt;p&gt;Open src/main.tsx and import the stylesheet:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./index.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// Import Tailwind CSS styles&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StrictMode&lt;/span&gt;&lt;span class="p"&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;Now your project is configured to use Tailwind CSS!&lt;/p&gt;

&lt;h2&gt;
  
  
  3️⃣ Setup shadcn/ui
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;shadcn/ui&lt;/code&gt; toolkit provides a beautiful, accessible set of React components styled with Tailwind CSS and powered by Radix UI primitives. It helps you quickly build consistent UI elements in your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 Run the shadcn/ui installer
&lt;/h3&gt;

&lt;p&gt;Use the following command to initialize shadcn/ui in your project:&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="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;dlx&lt;/span&gt; &lt;span class="nx"&gt;shadcn&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;latest&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Answer the CLI prompts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select tailwind.config.ts&lt;/li&gt;
&lt;li&gt;Set your component path to src/components&lt;/li&gt;
&lt;li&gt;Choose components like Button, Card, Input, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now you’ll have ready-to-use UI primitives inside your project!&lt;/p&gt;

&lt;h2&gt;
  
  
  4️⃣ Create Your Own Components
&lt;/h2&gt;

&lt;p&gt;With your UI Kit project set up, you can start building custom reusable components tailored to your design system.&lt;/p&gt;

&lt;h3&gt;
  
  
  📁 Organize components
&lt;/h3&gt;

&lt;p&gt;Create a folder inside &lt;code&gt;src/components/ui&lt;/code&gt; to hold your custom components, for example:&lt;/p&gt;

&lt;p&gt;src/components/ui/&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ Example: Creating a &lt;code&gt;Badge&lt;/code&gt; component
&lt;/h3&gt;

&lt;p&gt;Here’s a simple &lt;code&gt;Badge&lt;/code&gt; component that uses Tailwind CSS utility classes and supports additional styling via props:&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="c1"&gt;// src/components/ui/Badge.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/lib/utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// Utility for conditional classNames (optional)&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;BadgeProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HTMLAttributes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDivElement&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;BadgeProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;cn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inline-block px-2 py-1 text-sm rounded bg-gray-200 text-gray-800&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;className&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;
  
  
  🧩 Usage example
&lt;/h3&gt;

&lt;p&gt;Import and use your Badge component anywhere in your app:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Badge&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/components/ui/Badge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Demo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;New&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5️⃣ Setup NPM Linking for Local Use
&lt;/h2&gt;

&lt;p&gt;To reuse your UI Kit components across multiple local projects during development, you can set up &lt;strong&gt;local npm linking&lt;/strong&gt;. This lets you work on your UI Kit and consume it in other projects without publishing to the npm registry.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✍️ Prepare your &lt;code&gt;package.json&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Make sure your UI Kit's &lt;code&gt;package.json&lt;/code&gt; includes the following important fields:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&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;@your-scope/ui-kit&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;version&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;0.0.1&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;main&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;./dist/index.js&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;types&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;./dist/index.d.ts&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;files&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;dist&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;scripts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;build&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;tsc&lt;/span&gt;&lt;span class="dl"&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;ul&gt;
&lt;li&gt;name: Use a unique package name, preferably scoped (e.g., @your-scope/ui-kit)&lt;/li&gt;
&lt;li&gt;main and types: Point to your build output files&lt;/li&gt;
&lt;li&gt;files: Include only your build folder when publishing&lt;/li&gt;
&lt;li&gt;scripts.build: Build script to compile TypeScript to JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🧠 Add a build tsconfig.json
&lt;/h3&gt;

&lt;p&gt;Create or update tsconfig.json for building your UI Kit as a library:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;target&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;ESNext&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;module&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;ESNext&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;declaration&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outDir&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;./dist&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;jsx&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;react-jsx&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;moduleResolution&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;Node&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;esModuleInterop&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;skipLibCheck&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&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;src&lt;/span&gt;&lt;span class="dl"&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;Run the build command to generate your compiled files:&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="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔗 Link your package globally
&lt;/h3&gt;

&lt;p&gt;In your UI Kit project root, run:&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="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This registers your UI Kit package globally on your machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 Link your package in a consuming project
&lt;/h3&gt;

&lt;p&gt;In any project where you want to use your UI Kit, run:&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="nx"&gt;pnpm&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nb"&gt;global&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;your&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;kit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This links the global UI Kit package into the local project’s node_modules.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 Use your UI Kit components
&lt;/h3&gt;

&lt;p&gt;Now you can import and use your UI Kit components as if they were installed from npm:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Badge&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@your-scope/ui-kit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Demo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Linked Badge&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Badge&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔄 Keep in mind
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;After making changes in your UI Kit, rebuild it (pnpm run build) to update the linked files&lt;/li&gt;
&lt;li&gt;Some bundlers/watchers may require restarting to pick up changes from linked packages&lt;/li&gt;
&lt;li&gt;When ready, you can publish your UI Kit to npm for easier sharing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Local linking allows seamless iterative development of your UI Kit and consuming apps together!&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>react</category>
      <category>storybook</category>
      <category>shadcn</category>
    </item>
    <item>
      <title>🪟 How to Open and Communicate with a Popup Window in React (with TypeScript)</title>
      <dc:creator>Taron Vardanyan</dc:creator>
      <pubDate>Thu, 26 Jun 2025 11:38:07 +0000</pubDate>
      <link>https://forem.com/taronvardanyan/how-to-open-and-communicate-with-a-popup-window-in-react-with-typescript-f98</link>
      <guid>https://forem.com/taronvardanyan/how-to-open-and-communicate-with-a-popup-window-in-react-with-typescript-f98</guid>
      <description>&lt;p&gt;Opening a popup window in React isn't hard—but &lt;strong&gt;managing communication between your app and that popup&lt;/strong&gt; can get tricky. In this article, you'll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a new browser window (popup)&lt;/li&gt;
&lt;li&gt;Send data from the parent React app to the popup&lt;/li&gt;
&lt;li&gt;Detect when the popup is closed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll be using &lt;strong&gt;React Function Components&lt;/strong&gt; with &lt;strong&gt;TypeScript&lt;/strong&gt; to make this solution strongly typed and future-proof.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What You’ll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;How to open a popup window with specific dimensions&lt;/li&gt;
&lt;li&gt;How to communicate with that popup window using &lt;code&gt;postMessage&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;How to watch for popup closure using &lt;code&gt;setInterval&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A clean, reusable TypeScript implementation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📦 Let’s Build It!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create the Popup Component
&lt;/h3&gt;

&lt;p&gt;This component will live inside the popup window and receive data from the parent window using &lt;code&gt;message&lt;/code&gt; events.&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="c1"&gt;// PopupPage.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PopupPage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MessageEvent&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="c1"&gt;// Optionally: restrict to same-origin in production&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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Received message:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&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;setMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&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="p"&gt;};&lt;/span&gt;

    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleMessage&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Popup Window&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Message from parent:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#eee&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No message received&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;PopupPage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create the Main App with Popup Logic
&lt;/h3&gt;

&lt;p&gt;This component handles the logic to &lt;strong&gt;open the popup&lt;/strong&gt;, &lt;strong&gt;send a message&lt;/strong&gt;, and &lt;strong&gt;watch for closure&lt;/strong&gt;.&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="c1"&gt;// App.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;popupRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Window&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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="nx"&gt;timerRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Timer&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&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;popupOpen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setPopupOpen&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;openPopup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;400&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;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;300&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;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;screenX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerWidth&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;screenY&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;outerHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/popup&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="s1"&gt;MyPopup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;`width=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,height=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,left=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,top=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&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;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setPopupOpen&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="nf"&gt;startWatcher&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sendMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from parent!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;startWatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;timerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;timerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;popupRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nf"&gt;setPopupOpen&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="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Popup was closed&lt;/span&gt;&lt;span class="dl"&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="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;React Popup Communication (TS)&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;openPopup&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Open Popup&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;sendMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;popupOpen&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Send Message
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛣️ Setting Up the Route for the Popup
&lt;/h2&gt;

&lt;p&gt;If you're using &lt;strong&gt;React Router&lt;/strong&gt;, you can route the popup 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="c1"&gt;// index.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom/client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PopupPage&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./PopupPage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/popup"&lt;/span&gt; &lt;span class="na"&gt;element&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PopupPage&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BrowserRouter&lt;/span&gt;&lt;span class="p"&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;☕ Enjoyed this post?&lt;/p&gt;

&lt;p&gt;If you'd like to support my work, you can &lt;a href="https://www.buymeacoffee.com/tarokavardo" rel="noopener noreferrer"&gt;buy me a coffee&lt;/a&gt; — it really helps and means a lot!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/tarokavardo" rel="nofollow noopener noreferrer"&gt; &lt;img src="https://camo.githubusercontent.com/7b8f7343bfc6e3c65c7901846637b603fd812f1a5f768d8b0572558bde859eb9/68747470733a2f2f63646e2e6275796d6561636f666665652e636f6d2f627574746f6e732f76322f64656661756c742d79656c6c6f772e706e67" alt="ihsas01" width="545" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

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