<?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: Ankit</title>
    <description>The latest articles on Forem by Ankit (@mehta0007).</description>
    <link>https://forem.com/mehta0007</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%2F1329664%2F177ffceb-54e8-497c-b07c-adcd792736a8.jpg</url>
      <title>Forem: Ankit</title>
      <link>https://forem.com/mehta0007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mehta0007"/>
    <language>en</language>
    <item>
      <title>`useSyncExternalStore` — The React Hook You Didn't Know You Needed</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Tue, 07 Apr 2026 19:08:24 +0000</pubDate>
      <link>https://forem.com/mehta0007/usesyncexternalstore-the-react-hook-you-didnt-know-you-needed-34mp</link>
      <guid>https://forem.com/mehta0007/usesyncexternalstore-the-react-hook-you-didnt-know-you-needed-34mp</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A deep dive into React's most underrated hook — what it is, why it exists, and how to use it like a pro.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The Problem It Solves&lt;/li&gt;
&lt;li&gt;What Is &lt;code&gt;useSyncExternalStore&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;API Signature&lt;/li&gt;
&lt;li&gt;A Simple First Example — Browser Tab Visibility&lt;/li&gt;
&lt;li&gt;Understanding the Three Arguments&lt;/li&gt;
&lt;li&gt;Server-Side Rendering &amp;amp; the &lt;code&gt;getServerSnapshot&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
Real-World Use Cases

&lt;ul&gt;
&lt;li&gt;Subscribing to a Custom Store&lt;/li&gt;
&lt;li&gt;Reading from &lt;code&gt;localStorage&lt;/code&gt; Reactively&lt;/li&gt;
&lt;li&gt;Syncing with a Third-Party Library&lt;/li&gt;
&lt;li&gt;Network Online/Offline Status&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Why Not Just Use &lt;code&gt;useState&lt;/code&gt; + &lt;code&gt;useEffect&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Tearing — The Core Problem This Hook Solves&lt;/li&gt;
&lt;li&gt;Building a Mini State Management Library&lt;/li&gt;
&lt;li&gt;Performance Considerations&lt;/li&gt;
&lt;li&gt;Common Mistakes &amp;amp; Pitfalls&lt;/li&gt;
&lt;li&gt;Compatibility &amp;amp; Polyfill&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Problem It Solves
&lt;/h2&gt;

&lt;p&gt;Before we jump into the API, let's understand &lt;em&gt;why&lt;/em&gt; this hook was introduced in the first place.&lt;/p&gt;

&lt;p&gt;React 18 shipped with &lt;strong&gt;Concurrent Mode&lt;/strong&gt; — a new rendering engine that can pause, resume, and prioritize renders. This is fantastic for performance, but it introduced a subtle bug in how React components read from external (non-React) state sources.&lt;/p&gt;

&lt;p&gt;Imagine you have a global store (like a Redux store, a Zustand store, or even a plain JS &lt;code&gt;Map&lt;/code&gt;) and two components read from it. In Concurrent Mode, React might render these components at &lt;em&gt;different points in time&lt;/em&gt;, meaning one component reads the old value while the other reads the new one. This inconsistency in the UI is called &lt;strong&gt;tearing&lt;/strong&gt;, and it's visually jarring.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; was built specifically to eliminate tearing when subscribing to external stores.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is &lt;code&gt;useSyncExternalStore&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; is a React 18 hook that lets your components safely subscribe to &lt;strong&gt;external data sources&lt;/strong&gt; — anything that lives outside of React's own state management (&lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useReducer&lt;/code&gt;, &lt;code&gt;useContext&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;External sources include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom global stores&lt;/li&gt;
&lt;li&gt;Browser APIs (&lt;code&gt;navigator.onLine&lt;/code&gt;, &lt;code&gt;document.visibilityState&lt;/code&gt;, &lt;code&gt;localStorage&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Third-party libraries (Zustand, Redux, Valtio, etc.)&lt;/li&gt;
&lt;li&gt;Any pub-sub observable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was formally introduced in &lt;strong&gt;React 18&lt;/strong&gt; but is also available as a standalone package (&lt;code&gt;use-sync-external-store&lt;/code&gt;) for React 16 and 17.&lt;/p&gt;




&lt;h2&gt;
  
  
  API Signature
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;snapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="k"&gt;void&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getSnapshot&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="nx"&gt;Snapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;getServerSnapshot&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="nx"&gt;Snapshot&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three arguments, one return value. Clean and minimal.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Simple First Example
&lt;/h2&gt;

&lt;p&gt;Let's start with a classic: tracking whether the browser tab is visible or hidden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSyncExternalStore&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;function&lt;/span&gt; &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&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;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;visibilitychange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;document&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;visibilitychange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;getSnapshot&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="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visibilityState&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;usePageVisibility&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="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage in a component&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;StatusBadge&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;visibility&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;usePageVisibility&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Tab&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;strong&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;visibility&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;visible&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;👁 Visible&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;🙈 Hidden&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/strong&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/span&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is already cleaner and safer than the classic &lt;code&gt;useEffect&lt;/code&gt; + &lt;code&gt;useState&lt;/code&gt; approach. No race conditions, no tearing, and the &lt;code&gt;subscribe&lt;/code&gt; function can be defined &lt;em&gt;outside&lt;/em&gt; the component — meaning it doesn't get recreated on every render.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding the Three Arguments
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;subscribe(callback)&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This function is called once by React when the component mounts. It should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attach a listener to your external store.&lt;/li&gt;
&lt;li&gt;Call &lt;code&gt;callback&lt;/code&gt; whenever the store changes.&lt;/li&gt;
&lt;li&gt;Return a &lt;strong&gt;cleanup function&lt;/strong&gt; that removes the listener.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="k"&gt;void&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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="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;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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical rule&lt;/strong&gt;: &lt;code&gt;subscribe&lt;/code&gt; must be a stable reference (defined outside the component or wrapped in &lt;code&gt;useCallback&lt;/code&gt;). If you pass a new function reference on every render, React will keep re-subscribing — causing an infinite loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;getSnapshot()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This function is called by React to read the &lt;em&gt;current&lt;/em&gt; value from the store. React calls it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During rendering to get the current value.&lt;/li&gt;
&lt;li&gt;After every store update to check if the value has changed.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSnapshot&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// returns true or false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical rule&lt;/strong&gt;: &lt;code&gt;getSnapshot&lt;/code&gt; must return the same value when called multiple times if the store hasn't changed. React uses &lt;code&gt;Object.is&lt;/code&gt; comparison. If you return a new object reference every time (&lt;code&gt;return { ...state }&lt;/code&gt;), React will re-render infinitely.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;getServerSnapshot()&lt;/code&gt; (optional)
&lt;/h3&gt;

&lt;p&gt;This is for Server-Side Rendering (SSR). Since browser APIs aren't available on the server, you need to provide a fallback value. If omitted and you use SSR, React will throw an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getServerSnapshot&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// assume online on the server&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Server-Side Rendering &amp;amp; the &lt;code&gt;getServerSnapshot&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;If your app uses SSR (Next.js, Remix, etc.), the &lt;code&gt;getServerSnapshot&lt;/code&gt; argument is not optional — it's essential.&lt;/p&gt;

&lt;p&gt;Here's the full pattern for a safe, SSR-compatible hook:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSyncExternalStore&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;function&lt;/span&gt; &lt;span class="nf"&gt;useNetworkStatus&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="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="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;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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// client snapshot&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;                  &lt;span class="c1"&gt;// server snapshot (assume online)&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;On the server, React uses &lt;code&gt;getServerSnapshot&lt;/code&gt;. On the client, it uses &lt;code&gt;getSnapshot&lt;/code&gt;. This ensures hydration matches.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Subscribing to a Custom Store
&lt;/h3&gt;

&lt;p&gt;Let's build a simple reactive counter store and consume it with &lt;code&gt;useSyncExternalStore&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// store.ts&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Listener&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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;listeners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Listener&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;const&lt;/span&gt; &lt;span class="nx"&gt;counterStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;getSnapshot&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="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Listener&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;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listener&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="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listener&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="o"&gt;=&amp;gt;&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="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;l&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;decrement&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="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="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;l&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Counter.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;useSyncExternalStore&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;counterStore&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;./store&lt;/span&gt;&lt;span class="dl"&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;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;counterStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;counterStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getSnapshot&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;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;counterStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;increment&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;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;counterStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;decrement&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;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;p&gt;Any number of &lt;code&gt;Counter&lt;/code&gt; components rendered anywhere in your tree will always see the same value — no tearing, no stale reads.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Reading from &lt;code&gt;localStorage&lt;/code&gt; Reactively
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;localStorage&lt;/code&gt; is a classic external store. Here's a hook that keeps a value in sync:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useCallback&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;function&lt;/span&gt; &lt;span class="nf"&gt;useLocalStorage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;subscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="k"&gt;void&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="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;storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(():&lt;/span&gt; &lt;span class="nx"&gt;T&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;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;item&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;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;initialValue&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="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;initialValue&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;getServerSnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(():&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;initialValue&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getServerSnapshot&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;setValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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;newValue&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="c1"&gt;// Dispatch a storage event manually for same-tab updates&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;dispatchEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;storage&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="nx"&gt;key&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kd"&gt;const&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;&lt;strong&gt;Note&lt;/strong&gt;: The native &lt;code&gt;storage&lt;/code&gt; event only fires across tabs, not within the same tab. The manual &lt;code&gt;dispatchEvent&lt;/code&gt; handles same-tab updates.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Syncing with a Third-Party Library
&lt;/h3&gt;

&lt;p&gt;Say you're using a third-party pub-sub or observable. Here's how to wrap it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSyncExternalStore&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;someExternalEmitter&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;some-library&lt;/span&gt;&lt;span class="dl"&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;useExternalData&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="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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;unsubscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;someExternalEmitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;unsubscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;someExternalEmitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCurrentValue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the pattern that state management libraries like Zustand and Redux use internally.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Network Online/Offline Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useSyncExternalStore&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;subscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="k"&gt;void&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="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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="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;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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useIsOnline&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="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;subscribe&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&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="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// In a component&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NetworkBanner&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;isOnline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useIsOnline&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;isOnline&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&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;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&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;8px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;center&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;offline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Some&lt;/span&gt; &lt;span class="nx"&gt;features&lt;/span&gt; &lt;span class="nx"&gt;may&lt;/span&gt; &lt;span class="nx"&gt;not&lt;/span&gt; &lt;span class="nx"&gt;be&lt;/span&gt; &lt;span class="nx"&gt;available&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&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;h2&gt;
  
  
  Why Not Just Use &lt;code&gt;useState&lt;/code&gt; + &lt;code&gt;useEffect&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;This is the most common question. You've probably written this pattern before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The classic pattern — looks fine, but has issues&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useIsOnline&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;isOnline&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsOnline&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onLine&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;handleOnline&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="nf"&gt;setIsOnline&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleOffline&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="nf"&gt;setIsOnline&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="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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleOnline&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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleOffline&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="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;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;online&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleOnline&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;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;offline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleOffline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isOnline&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This seems reasonable. But it has three subtle problems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 1 — The initial value might be stale.&lt;/strong&gt; By the time the effect runs (after paint), the network status could have already changed. There's a window where the component renders with a stale value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 2 — Tearing in Concurrent Mode.&lt;/strong&gt; In React 18 with Concurrent rendering, two components using this hook could read different values of &lt;code&gt;isOnline&lt;/code&gt; if a network change happens mid-render.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem 3 — No SSR safety.&lt;/strong&gt; Calling &lt;code&gt;navigator.onLine&lt;/code&gt; inside &lt;code&gt;useState&lt;/code&gt; initializer will throw during SSR because &lt;code&gt;navigator&lt;/code&gt; doesn't exist on the server.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; solves all three of these at the framework level.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tearing — The Core Problem This Hook Solves
&lt;/h2&gt;

&lt;p&gt;Let's make tearing concrete. Imagine two components read a global variable &lt;code&gt;externalCount&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React starts rendering Component A → reads externalCount = 5
...concurrent pause happens...
externalCount changes to 6
...rendering resumes...
React renders Component B → reads externalCount = 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your UI shows two different values for the same piece of data. That's tearing. It's a race condition baked into the rendering model.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; tells React: &lt;em&gt;"When you render any component subscribed to this store, make sure all of them see the same snapshot."&lt;/em&gt; React guarantees this by synchronizing the render.&lt;/p&gt;

&lt;p&gt;This is what the word &lt;strong&gt;"Sync"&lt;/strong&gt; in the hook name means — it forces React to synchronize with the external store, even in Concurrent Mode.&lt;/p&gt;




&lt;h2&gt;
  
  
  Building a Mini State Management Library
&lt;/h2&gt;

&lt;p&gt;Let's go further and use &lt;code&gt;useSyncExternalStore&lt;/code&gt; to build a fully functional, type-safe, minimal state manager in ~40 lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// createStore.ts&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;useSyncExternalStore&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;type&lt;/span&gt; &lt;span class="nx"&gt;SetState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;updater&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;prev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Selector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;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;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;R&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;createStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;object&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;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialState&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;listeners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&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;getState&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="nx"&gt;state&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;setState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SetState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;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;updater&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;partial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
      &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;updater&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;updater&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="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updater&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;=&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;partial&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;l&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;subscribe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="k"&gt;void&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;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&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;useStore&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;T&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;useStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&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;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Selector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&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;R&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;useStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&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;selector&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Selector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&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;T&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;useSyncExternalStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;subscribe&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="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;selector&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="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;getState&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="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useStore&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Usage&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;useStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&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="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&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="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ThemeToggle&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;theme&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="nx"&gt;s&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;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// only re-renders when theme changes&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;setState&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="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&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;dark&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;light&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;
      Switch to &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&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;Dark&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;Light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; Mode
    &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;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;useStore&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&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;s&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="c1"&gt;// only re-renders when count changes&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;setState&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&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;s&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;p&gt;That's a fully working, selector-based, tear-free state manager in ~40 lines of code. This is essentially what Zustand does under the hood.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Define &lt;code&gt;subscribe&lt;/code&gt; outside the component.&lt;/strong&gt; Defining it inside causes a new function reference on every render, which triggers React to re-subscribe. Move it to module scope or wrap it in &lt;code&gt;useCallback&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;getSnapshot&lt;/code&gt; must be pure and stable.&lt;/strong&gt; React calls it frequently. Keep it fast — just return a value, don't compute expensive things inside it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use selectors for large stores.&lt;/strong&gt; Instead of subscribing to the entire store object, narrow down with a selector. React uses &lt;code&gt;Object.is&lt;/code&gt; to compare snapshots, so if the selected slice hasn't changed, no re-render happens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid returning new objects from &lt;code&gt;getSnapshot&lt;/code&gt;.&lt;/strong&gt; This is the most common performance bug:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ BAD — returns a new object reference every call&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&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="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;store&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="c1"&gt;// ✅ GOOD — returns a stable primitive or the same reference&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&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="nx"&gt;store&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="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; Pitfalls
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mistake&lt;/th&gt;
&lt;th&gt;Why It's a Problem&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Defining &lt;code&gt;subscribe&lt;/code&gt; inside the component&lt;/td&gt;
&lt;td&gt;New reference every render → infinite re-subscriptions&lt;/td&gt;
&lt;td&gt;Move to module scope or use &lt;code&gt;useCallback&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Returning new objects from &lt;code&gt;getSnapshot&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Object.is&lt;/code&gt; always false → infinite re-renders&lt;/td&gt;
&lt;td&gt;Return primitives or stable references&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forgetting &lt;code&gt;getServerSnapshot&lt;/code&gt; in SSR apps&lt;/td&gt;
&lt;td&gt;React throws a hydration error&lt;/td&gt;
&lt;td&gt;Always provide it for any browser API access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Not returning the cleanup function from &lt;code&gt;subscribe&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Memory leak — listeners pile up indefinitely&lt;/td&gt;
&lt;td&gt;Always &lt;code&gt;return () =&amp;gt; removeListener(...)&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Using &lt;code&gt;getSnapshot&lt;/code&gt; to compute derived state&lt;/td&gt;
&lt;td&gt;Can cause subtle bugs with stale closures&lt;/td&gt;
&lt;td&gt;Compute derived values outside the hook&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Compatibility &amp;amp; Polyfill
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; is available natively in &lt;strong&gt;React 18+&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For &lt;strong&gt;React 16.8–17&lt;/strong&gt;, use the official shim:&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;use-sync-external-store
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// For React 16/17&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;useSyncExternalStore&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;use-sync-external-store/shim&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// With server snapshot support&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;useSyncExternalStore&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;use-sync-external-store/shim/with-selector&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The shim is maintained by the React team and is fully compatible.&lt;/p&gt;




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

&lt;p&gt;&lt;code&gt;useSyncExternalStore&lt;/code&gt; is the right tool whenever your component needs to read from &lt;em&gt;anything that's not React state&lt;/em&gt;. It's not a niche hook for library authors only — it's a fundamental primitive for anyone doing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom hooks that read from browser APIs&lt;/li&gt;
&lt;li&gt;Integrating third-party stores or observables&lt;/li&gt;
&lt;li&gt;Building micro state management solutions&lt;/li&gt;
&lt;li&gt;Avoiding tearing in concurrent-mode apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the mental checklist: if you find yourself writing &lt;code&gt;useEffect(() =&amp;gt; { externalThing.subscribe(...) }, [])&lt;/code&gt; to keep local state in sync with something outside React — reach for &lt;code&gt;useSyncExternalStore&lt;/code&gt; instead. It's safer, cleaner, and React 18-compatible from the ground up.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Happy building. Keep your stores external and your snapshots stable.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Shallow Copy vs Deep Copy in JavaScript (Explained Like You’re Five) — By Ankit Mehta</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Sat, 13 Dec 2025 04:39:03 +0000</pubDate>
      <link>https://forem.com/mehta0007/shallow-copy-vs-deep-copy-in-javascript-explained-like-youre-five-by-ankit-mehta-3n57</link>
      <guid>https://forem.com/mehta0007/shallow-copy-vs-deep-copy-in-javascript-explained-like-youre-five-by-ankit-mehta-3n57</guid>
      <description>&lt;p&gt;Have you every copied something in JavaScript…&lt;/p&gt;

&lt;p&gt;…changed one small thing…&lt;/p&gt;

&lt;p&gt;…and suddenly your original data also changed?&lt;/p&gt;

&lt;p&gt;If yes, then you’re welcomed to the Shallow Copy vs Deep Copy problem.&lt;/p&gt;

&lt;p&gt;When I first learned JS, this concept confused me so badly that i felt JS was betraying me. So i finally sat down, understood, and here’s the simplest explanation you’ll ever find.&lt;/p&gt;

&lt;p&gt;Let’s start with ‘ What ’ Question.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⭐What Does “ Copying ” Even Mean ?
&lt;/h3&gt;

&lt;p&gt;If someone asks you to “copy” your homework, you’ll probably &lt;strong&gt;create a new page&lt;/strong&gt;, right?&lt;/p&gt;

&lt;p&gt;However, In JavaScript, copying works a little differently depending on whether the data is:&lt;/p&gt;

&lt;p&gt;👉Primitive → numbers, strings, booleans&lt;/p&gt;

&lt;p&gt;👉Non-primitive → arrays and objects&lt;/p&gt;

&lt;p&gt;And things get a little weird with non-primitives.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⭐The Core Idea ( Point To Remember! )
&lt;/h3&gt;

&lt;p&gt;There’s a golden rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A shallow copy copies the reference.
A deep copy copies the value.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple.&lt;/p&gt;

&lt;p&gt;But to fully understand i’ll break it down with an analogy.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⭐The Pizza Analogy (So Simple You’ll Never Forget)
&lt;/h3&gt;

&lt;p&gt;Just Imagine, you and your friend share a pizza.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shallow Copy = You both get the SAME pizza.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your friend eats a slice → your pizza also shrinks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep Copy = You each get your OWN pizza.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your friend eats → your pizza is safe.&lt;/p&gt;

&lt;p&gt;And That’s it.&lt;/p&gt;

&lt;p&gt;This is the entire concept.&lt;/p&gt;

&lt;p&gt;Now let’s look at JavaScript examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⭐Shallow Copy in JavaScript
&lt;/h3&gt;

&lt;p&gt;A shallow copy looks like a new copy…&lt;/p&gt;

&lt;p&gt;..but inside, it still points to the same memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
const original = { name: "Ankit" };

const copy = original; //not a real copy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;if you change &lt;em&gt;copy.name&lt;/em&gt;, the original also changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;copy.name =  "Ankit"

console.log(original.name); // "Ankit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because both original and copy point to the same object in memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ⭐Real Shallow Copy Methods in JavaScript
&lt;/h3&gt;

&lt;p&gt;These create a &lt;strong&gt;new&lt;/strong&gt; object/array…&lt;/p&gt;

&lt;p&gt;…but only the top level values are copied.&lt;/p&gt;

&lt;p&gt;Become a member&lt;br&gt;
&lt;strong&gt;Array shallow copies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const arr = [1, 2, 3];
const shallow = [...arr];
// OR arr.slice();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Object shallow copies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const obj = { a: 1, b: 2 };
const shallow = { ...obj };
// OR Object.assign({}, obj);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the trap:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the object contains nested objects, those nested ones are STILL shared.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const user = {
  name: "Ankit",
  hobbies: ["coding", "gaming"],
};

const shallowCopy = { ...user };

shallowCopy.hobbies.push("fitness");

console.log(user.hobbies);  
// ["coding", "gaming", "fitness"] 😱
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because inside the object, hobbies is still the &lt;strong&gt;same array&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⭐Deep Copy in JavaScript
&lt;/h3&gt;

&lt;p&gt;A deep copy makes a completely new object.&lt;/p&gt;

&lt;p&gt;Nothing is shared.&lt;br&gt;
Changes in the copy &lt;strong&gt;never&lt;/strong&gt; affect the original.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const original = { name: "Ankit", skills: ["JS", "C++"] };

const deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.skills.push("Node.js");

console.log(original.skills); 
// ["JS", "C++"] ✔️ unchanged
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⭐Ways to Do Deep Copy
&lt;/h3&gt;

&lt;p&gt;some common methods are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. JSON.parse( JSON.stringify() )&lt;/strong&gt;&lt;br&gt;
✔️easy&lt;/p&gt;

&lt;p&gt;❌does NOT work for functions, dates, undefined, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. structuredClone() (Modern JS — BEST)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const deepCopy = structuredClone(original);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✔️ perfect deep copy&lt;br&gt;
✔️ handles nested data&lt;br&gt;
✔️ keeps types&lt;br&gt;
✔️ fastest, cleanest&lt;br&gt;
❌ not supported in very old browsers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Lodash cloneDeep()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;if you use lodash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const deepCopy = _.cloneDeep(obj);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  When Should You Use What?
&lt;/h3&gt;

&lt;p&gt;Use &lt;strong&gt;Shallow Copy&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no nested objects inside&lt;/li&gt;
&lt;li&gt;performance matters&lt;/li&gt;
&lt;li&gt;the data is simple&lt;/li&gt;
&lt;li&gt;you just need a quick copy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;strong&gt;Deep Copy&lt;/strong&gt; when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there are nested objects/arrays&lt;/li&gt;
&lt;li&gt;modifying the copy shouldn’t touch original&lt;/li&gt;
&lt;li&gt;you’re dealing with APIs, forms, configs, Redux state, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Points (Remember This!)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Shallow copy → copies &lt;strong&gt;reference&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Deep copy → copies &lt;strong&gt;actual value&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Spread operator (&lt;code&gt;...&lt;/code&gt;) is &lt;strong&gt;shallow&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;structuredClone()&lt;/code&gt; is the best deep copy method&lt;/li&gt;
&lt;li&gt;If your nested data is changing unexpectedly → you made a shallow copy by mistake&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ❤️Lastly…
&lt;/h3&gt;

&lt;p&gt;If you are learning JavaScript, you will face bugs caused by shallow copying.&lt;/p&gt;

&lt;p&gt;I faced them too. Everyone does.&lt;/p&gt;

&lt;p&gt;But once you understand the difference between shallow and deep copy, your debugging will become easier, your code becomes cleaner and JS starts to make sense.&lt;/p&gt;

&lt;p&gt;This article is not just for readers, it helped me understand the topic too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Two birds, one stone.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>npm Supply Chain Attack: A Wake-Up Call for JavaScript Developers</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Wed, 10 Sep 2025 11:04:05 +0000</pubDate>
      <link>https://forem.com/mehta0007/npm-supply-chain-attack-a-wake-up-call-for-javascript-developers-5917</link>
      <guid>https://forem.com/mehta0007/npm-supply-chain-attack-a-wake-up-call-for-javascript-developers-5917</guid>
      <description>&lt;p&gt;On September 9th, 2025, the JavaScript world got a reminder that our tools are only as safe as the people who maintain them. A phishing email tricked a well-known developer, Josh Junan (aka Quicks Online), the maintainer of widely-used packages like chalk and debug. That one click gave attackers access to his npm account, and from there, they pushed out malicious updates.&lt;/p&gt;

&lt;h4&gt;
  
  
  What actually happened?
&lt;/h4&gt;

&lt;p&gt;The malicious code wasn’t just random spam. It was a crypto clipper, a sneaky bit of malware that swaps out wallet addresses when users send cryptocurrency. To make it even trickier, it used the Levenshtein distance algorithm to generate fake addresses that looked almost identical to the real ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In plain English&lt;/strong&gt;: imagine copying your friend’s wallet address to send them Ethereum, and at the last second, the malware replaces it with a scammer’s address that looks the same at a glance. That’s what happened at scale.&lt;/p&gt;

&lt;p&gt;Within just a couple of hours, these compromised packages were downloaded millions of times.&lt;/p&gt;

&lt;h4&gt;
  
  
  The damage (and the irony)
&lt;/h4&gt;

&lt;p&gt;You’d think with that reach, attackers would walk away with millions. In reality, they only got about $50 worth of ETH. Pretty anticlimactic, but the real cost here isn’t the money it’s trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers are now (once again) asking&lt;/strong&gt;: how safe is our supply chain? If even widely trusted packages can be compromised so quickly, what does that say about the security practices across the ecosystem?&lt;/p&gt;

&lt;p&gt;Some have even joked about renaming npm install to npm prey. Funny, but also a little too real.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lessons worth taking seriously
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;If you’re a developer, this incident is a reminder to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don’t trust every email (even if it looks “official”).&lt;/li&gt;
&lt;li&gt;Enable 2FA on your npm and GitHub accounts non negotiable.&lt;/li&gt;
&lt;li&gt;Audit dependencies when possible, especially for critical apps.&lt;/li&gt;
&lt;li&gt;Keep an eye on security advisories in the community.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open-source thrives on trust, and that trust is fragile. Security isn’t something we bolt on at the end it has to be part of the workflow.&lt;/p&gt;

&lt;p&gt;🔒 &lt;em&gt;At the end of the day, this attack wasn’t about the $50. It was a loud reminder: our supply chain is only as strong as its weakest link&lt;/em&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>npm</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>JavaScript vs Python for AI Product Development: Which One Should You Choose?</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Thu, 04 Sep 2025 15:26:20 +0000</pubDate>
      <link>https://forem.com/mehta0007/javascript-vs-python-for-ai-product-development-which-one-should-you-choose-4cjn</link>
      <guid>https://forem.com/mehta0007/javascript-vs-python-for-ai-product-development-which-one-should-you-choose-4cjn</guid>
      <description>&lt;p&gt;Artificial Intelligence (AI) is shaping the future of software products—but one question developers often face is: Should I use Python or JavaScript for AI product development?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Python?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Python has long been the backbone of AI and machine learning.&lt;/p&gt;

&lt;p&gt;Rich libraries: TensorFlow, PyTorch, scikit-learn&lt;/p&gt;

&lt;p&gt;Simplicity in syntax → faster prototyping&lt;/p&gt;

&lt;p&gt;Strong community in research &amp;amp; academia&lt;/p&gt;

&lt;p&gt;Best use-case: building, training, and experimenting with AI models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why JavaScript?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While Python dominates research, JavaScript powers the web.&lt;/p&gt;

&lt;p&gt;Frameworks like TensorFlow.js &amp;amp; ONNX.js bring AI directly to browsers&lt;/p&gt;

&lt;p&gt;Ideal for deploying models to millions of users without heavy backend&lt;/p&gt;

&lt;p&gt;Perfect for building interactive, real-time AI products&lt;/p&gt;

&lt;p&gt;Best use-case: integrating AI into scalable, user-facing applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, which one to choose?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to research and prototype AI models → Python is unmatched.&lt;/p&gt;

&lt;p&gt;If you want to ship AI products to end-users quickly → JavaScript shines.&lt;/p&gt;

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

&lt;p&gt;Think of it this way:&lt;/p&gt;

&lt;p&gt;👉 Python builds the brain.&lt;br&gt;
👉 JavaScript brings the brain to life on the web.&lt;/p&gt;

&lt;p&gt;For modern AI product development, the smartest path may not be choosing one over the other—but knowing when to use both together.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>python</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introduction to System Design</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Mon, 01 Sep 2025 06:50:28 +0000</pubDate>
      <link>https://forem.com/mehta0007/introduction-to-system-design-1j20</link>
      <guid>https://forem.com/mehta0007/introduction-to-system-design-1j20</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;System design involves understanding various components like load balancers, API gateways, caching, queue systems, and microservices to build robust, scalable, and highly available systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This guide provides a beginner-friendly overview of how these components work together in a real-world production environment. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Core Components: Client and Server
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A client is any device (e.g., mobile, laptop, IoT device) that uses an application and sends requests to a server. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A server is a machine capable of running 24/7 with a public IP address, which is a unique address on the internet for reaching the server. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cloud providers like AWS offer virtual machines that act as servers, providing 24/7 availability and public IPs, as it's impractical for personal computers to serve this role.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  DNS (Domain Name System)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A DNS server is a global directory that maps human-readable domain names (e.g., amazon.com) to their corresponding IP addresses.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When a user types a domain name, the initial request goes to the DNS server, which returns the IP address, a process known as DNS resolution.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Scaling Strategies
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Servers can become overwhelmed by increased user traffic, leading to crashes if their physical resources (CPU, RAM) are insufficient. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To handle high loads and ensure fault tolerance, systems must implement scaling.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Vertical Scaling
&lt;/h4&gt;

&lt;p&gt;Increasing the physical resources (CPU, RAM, disk space) of a single existing server or virtual machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improves capacity of a single machine to handle more traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires down time (server restart) to add physical resources, making it unsuitable for applications requiring zero downtime during traffic spikes.&lt;/li&gt;
&lt;li&gt;Can lead to resource waste and increased costs during periods of low traffic, as resources are provisioned for peak load.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Horizontal Scaling
&lt;/h4&gt;

&lt;p&gt;Adding more identical servers (replicas) to distribute the workload, rather than increasing resources of a single server. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provides zero down time during scaling, as new machines boot up while existing ones handle traffic.&lt;/li&gt;
&lt;li&gt;Offers greater fault tolerance and resilience, as the failure of one server does not bring down the entire system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Requires an additional component, a load balancer, to effectively distribute traffic among the multiple server replicas, as DNS can only return one IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Load Balancers
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A load balancer is a critical component placed in front of horizontally scaled servers to distribute incoming requests efficiently. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The DNS maps the domain name to the load balancer's IP address, which then intelligently routes requests to individual servers. s s&lt;br&gt;
Load balancers use various algorithms (e.g., Round Robin, which distributes requests sequentially) to balance the load across servers. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They perform health checks to ensure that servers are active and ready to handle traffic before routing requests to them. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In cloud environments like Amazon, this service is often referred to as an Elastic Load Balancer (ELB), designed to be highly available and manage its own internal resources effectively. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Microservices and API Gateway
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In a microservice architecture, an application is decomposed into smaller, independent services (e.g., authentication, orders, payments). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each microservice can be independently scaled horizontally and typically has its own dedicated load balancer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An API Gateway serves as a centralized entry point for all client requests, acting as a reverse proxy that routes requests to the appropriate microservice's load balancer based on defined rules (e.g., /auth requests go to the authentication service).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can also integrate an authenticator service (e.g., Auth0) to authenticate users before routing their requests. s&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykz90zppsgj9xmflo4l8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykz90zppsgj9xmflo4l8.png" alt=" " width="800" height="628"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Asynchronous Communication
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For tasks like sending bulk emails or processing large data uploads, batch processing and background services are essential, as synchronous calls would overwhelm the system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Synchronous communication, where a service waits for a response from another service, is not scalable for time-consuming operations. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asynchronous communication allows services to interact without waiting, significantly improving system scalability and responsiveness.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Queue Systems (e.g., Amazon SQS)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Queue systems provide an asynchronous, First-In-First-Out (FIFO) communication channel between services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A service pushes events (e.g., order IDs) into the queue, and dedicated worker processes pull and process these events independently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This approach increases parallelism (multiple workers processing events concurrently) and enables rate limiting to manage dependencies on external APIs (e.g., limiting email sends to 10 per second to avoid hitting API limits).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Worker processes can use pull mechanisms to retrieve messages: short polling (frequent, short-duration checks) or long polling (waiting for a longer period, blocking until messages arrive or a timeout occurs). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Queue systems offer acknowledgment of message processing and support Dead Letter Queues (DLQ) for failed messages, allowing for retries and guaranteed processing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SQS guarantees that each message is processed exactly once by a single consumer. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Pub/Sub Model (e.g., Amazon SNS)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Pub/Sub (Publish/Subscribe) model is used when a single event needs to notify multiple services (one-to-many communication).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A service publishes an event (e.g., payment completed) to a notification service (topic), and all subscribed services receive and process it. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This forms the basis of an event-driven architecture. s s&lt;br&gt;
A key limitation is the lack of inherent acknowledgment or retry mechanisms; if a subscriber fails to process a message, it might be lost without a built-in recovery process. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Fan-out Architecture
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The Fan-out architecture combines the Pub/Sub model (SNS) with Queue systems (SQS) to achieve both multi-service notification and reliable message processing. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fma4ho98erwwzyi80ichm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fma4ho98erwwzyi80ichm.png" alt=" " width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Rate Limiting
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rate limiting is essential to protect systems from being overwhelmed by excessive requests, including malicious DDoS/DoS attacks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It defines how many requests a user or system can send within a specific time frame (e.g., 5 requests per second), blocking additional requests once the limit is hit. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Common strategies include Leaky Bucket and Token Bucket algorithms, which control the flow of requests to maintain system stability.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Database Optimization
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A single database can become overwhelmed by a high volume of read and write requests from increasing services. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Read Replicas are copies of the primary database that handle read operations, especially for tasks like analytics or logging where slight data delay is acceptable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All write operations and real-time data reads are directed to the primary (master) node to ensure consistency. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This strategy significantly reduces the load on the primary database, improving overall performance. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Caching
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Caching stores frequently accessed data or results of complex computations in a faster, in-memory database (e.g., Redis) to reduce direct calls to the main database. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When data is requested, the system first checks the cache. If found, it's returned immediately; otherwise, it's fetched from the main database, stored in the cache, and then returned. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Caching dramatically optimizes system performance and reduces the load on backend databases. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Content Delivery Network (CDN)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A Content Delivery Network (CDN), such as Amazon CloudFront, deploys edge machines (micro machines) globally to serve content closer to users, minimizing latency. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;These edge locations are internally routed to the main load balancer, and a single Anycast IP can be assigned to multiple CDN edges, directing users to the nearest available server. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CDNs cache content (e.g., images, videos) at these edge locations.&lt;br&gt;
If a user requests content that is already cached in their regional&lt;br&gt;
edge, it is served directly from the cache, bypassing the origin&lt;br&gt;
server. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This process significantly improves user experience by reducing latency, saves network bandwidth, and decreases the load on the origin servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjcs33llijyhmbx1l0z4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjcs33llijyhmbx1l0z4.png" alt=" " width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This process significantly improves user experience by reducing latency, saves network bandwidth, and decreases the load on the origin servers. ...&lt;br&gt;
Here is a mind map illustrating the benefits of a CDN:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An event is published to an SNS topic, which then automatically delivers copies of the message to multiple SQS queues. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Each SQS queue is processed by its dedicated workers, benefiting from SQS's reliable features like acknowledgment, retries, and DLQs, ensuring that each downstream service reliably processes its part of the event. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This pattern is ideal for scenarios where one event triggers multiple independent and reliable actions, such as uploading a video and simultaneously triggering processes for transcription, different resolutions, and thumbnail generation. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are ultimate physical limits to how much a single machine can be upgraded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IP addresses are difficult to remember, prompting the need for user-friendly domain names. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>systemdesign</category>
      <category>webdev</category>
      <category>aws</category>
      <category>learning</category>
    </item>
    <item>
      <title>Everything You Need to Know About new in JavaScript</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Thu, 28 Aug 2025 05:34:14 +0000</pubDate>
      <link>https://forem.com/mehta0007/everything-you-need-to-know-about-new-in-javascript-2ak5</link>
      <guid>https://forem.com/mehta0007/everything-you-need-to-know-about-new-in-javascript-2ak5</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. What does &lt;code&gt;new&lt;/code&gt; do?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you use &lt;code&gt;new&lt;/code&gt;, Javascript:&lt;/li&gt;
&lt;li&gt;Creates a new empty object: &lt;code&gt;{}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sets the new object's prototype to the constructor's prototype
 (&lt;code&gt;obj.__proto__ = Constructor.prototype&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Runs the Constructor function with &lt;code&gt;this&lt;/code&gt; bound to the new object&lt;/li&gt;
&lt;li&gt;Returns the new object (unless the constructor explicitly returns          another object)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Using &lt;code&gt;new&lt;/code&gt; with a Constructor Function&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Person(name) {
  this.name = name;
}

const user = new Person("Ankit");
console.log(user.name); // "Ankit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you call &lt;code&gt;person("Ankit")&lt;/code&gt; without &lt;code&gt;new&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It won't create a new object.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;this&lt;/code&gt; will refer to the global object (or &lt;code&gt;undefined&lt;/code&gt; in strict mode)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; will be set on the wrong thing → Bug!
That's why new is important.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Using new with a Class&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Car {
  constructor(brand) {
    this.brand = brand;
  }
}

const c1 = new Car("Tesla");
console.log(c1.brand); // Tesla
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your must use new with classes, or Js will throw an error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. What if the Constructor Returns Something?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If it returns an object, that object is returned instead of the new one.&lt;/li&gt;
&lt;li&gt;If it returns a primitive (string, number, etc.), it's ignore, and the new object is returned.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Test() {
  this.value = 10;
  return { msg: "I override!" };
}

const t = new Test();
console.log(t); // { msg: "I override!" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Built-in Objects that use new&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many built-ins in JS can be created with new:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let now = new Date();
let regex = new RegExp("abc");
let obj = new Object();
let arr = new Array(3); // [empty × 3]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But some are fine without new:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let str = String(123); // "123"
let num = Number("5"); // 5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. When NOT to use new:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't use new with normal functions that are not constructors.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function greet() {
  console.log("Hello!");
}

new greet(); // Works but makes no sense → {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building a Full-Stack App with Next.js &amp; Prisma: Part 1 – Setting Up the Database Client</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Tue, 26 Aug 2025 11:45:15 +0000</pubDate>
      <link>https://forem.com/mehta0007/building-a-full-stack-app-with-nextjs-prisma-part-1-setting-up-the-database-client-5634</link>
      <guid>https://forem.com/mehta0007/building-a-full-stack-app-with-nextjs-prisma-part-1-setting-up-the-database-client-5634</guid>
      <description>&lt;h4&gt;
  
  
  0) Mental Model - What happens on a request?
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;User hits a route → &lt;code&gt;middleware.ts&lt;/code&gt; checks whether they’re logged in and whether the route is &lt;code&gt;public/protected/auth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If sign-in is needed, user goes to &lt;code&gt;/auth/sign-in&lt;/code&gt; and chooses Google or GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NextAuth&lt;/strong&gt; + &lt;strong&gt;PrismaAdapter&lt;/strong&gt; look up the user; if new, create &lt;strong&gt;User&lt;/strong&gt; + &lt;strong&gt;Account&lt;/strong&gt;; if existing, link the provider.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Callbacks&lt;/strong&gt; enrich the JWT and session with id and role.&lt;/li&gt;
&lt;li&gt;Client now has &lt;code&gt;session.user.id&lt;/code&gt; and &lt;code&gt;session.user.role&lt;/code&gt; for RBAC and UI.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1) Database Client (Prisma) — &lt;code&gt;lib/db.ts&lt;/code&gt;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { PrismaClient } from "@prisma/client"

const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }

export const db = globalForPrisma.prisma || new PrismaClient()

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first glance, this may look a bit tricky. Let’s break it down.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { PrismaClient } from "@prisma/client"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PrismaClient&lt;/code&gt; is the main tool you use to talk to your database&lt;/li&gt;
&lt;li&gt;Think of it like a “bridge” that connects your code with your database (MySQL, PostgreSQL, SQLite, etc.).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In Next.js (or any serverless environment), new instances of the code can spin up frequently.&lt;/li&gt;
&lt;li&gt;If you create a new database client every time, you risk having too many open connections.&lt;/li&gt;
&lt;li&gt;To prevent this, we attach Prisma to the global object (&lt;code&gt;globalThis&lt;/code&gt;), so it can be reused.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that if Prisma is already created, we don’t create it again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const db = globalForPrisma.prisma || new PrismaClient()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Here, we check:

&lt;ul&gt;
&lt;li&gt;If a Prisma instance already exists (&lt;code&gt;globalForPrisma.prisma&lt;/code&gt;), use it.&lt;/li&gt;
&lt;li&gt;Otherwise, create a new one (&lt;code&gt;new PrismaClient()&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is the key step that prevents multiple Prisma clients from being created unnecessarily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = db
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt; In development mode, your app refreshes and hot-reloads often.&lt;/li&gt;
&lt;li&gt; Without this line, Prisma would create a &lt;strong&gt;new connection each time&lt;/strong&gt;, eventually causing errors like:
“Too many connections”.&lt;/li&gt;
&lt;li&gt;This line ensures the same &lt;code&gt;db&lt;/code&gt; instance is reused during development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;strong&gt;production&lt;/strong&gt;, Next.js doesn’t hot-reload, so we don’t need this safeguard.&lt;/p&gt;

&lt;h4&gt;
  
  
  So Why Does This Matters
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Prevents performance issues&lt;/strong&gt; caused by too many connections.&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Works well with Next.js serverless functions.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Shows professionalism:&lt;/strong&gt; any recruiter or developer reviewing your code will see you understand real-world database issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Finally
&lt;/h4&gt;

&lt;p&gt;This small snippet may look simple, but it solves a very common real-world problem. &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>JavaScript Event Loop: Microtasks vs Macrotasks Explained</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Fri, 22 Aug 2025 15:15:10 +0000</pubDate>
      <link>https://forem.com/mehta0007/javascript-event-loop-microtasks-vs-macrotasks-explained-4124</link>
      <guid>https://forem.com/mehta0007/javascript-event-loop-microtasks-vs-macrotasks-explained-4124</guid>
      <description>&lt;p&gt;JavaScript is single-threaded. That means it can only do &lt;strong&gt;one thing at a time&lt;/strong&gt;. So how does it handle asynchronous operations like &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;fetch&lt;/code&gt;, or &lt;code&gt;Promise&lt;/code&gt;? The answer lies in the &lt;strong&gt;Event Loop&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Call Stack
&lt;/h2&gt;

&lt;p&gt;JavaScript executes code line by line in the call stack. Once a function finishes, it gets popped off the stack. Simple enough — but async tasks can’t block the stack forever.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Event Loop
&lt;/h2&gt;

&lt;p&gt;The Event Loop is like a traffic cop. It constantly checks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the call stack empty?&lt;/li&gt;
&lt;li&gt;If yes, are there any pending tasks waiting in queues?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If so, it pushes them into the stack for execution.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Task Queues
&lt;/h2&gt;

&lt;p&gt;Not all tasks are equal. They are divided into &lt;strong&gt;Macrotasks&lt;/strong&gt; and &lt;strong&gt;Microtasks&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔹 Macrotasks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Examples: &lt;code&gt;setTimeout&lt;/code&gt;, &lt;code&gt;setInterval&lt;/code&gt;, &lt;code&gt;setImmediate&lt;/code&gt;, DOM events&lt;/li&gt;
&lt;li&gt;They are scheduled in the &lt;strong&gt;Macrotask queue&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Executed one per loop iteration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔹 Microtasks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Examples: &lt;code&gt;Promise.then&lt;/code&gt;, &lt;code&gt;process.nextTick&lt;/code&gt; (Node.js), &lt;code&gt;MutationObserver&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stored in the &lt;strong&gt;Microtask queue&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;All microtasks are executed &lt;strong&gt;before the event loop continues to the next Macrotask&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Example in Action
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="s2"&gt;Start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&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;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="s2"&gt;Macrotask: setTimeout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="o"&gt;=&amp;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="s2"&gt;Microtask: Promise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Output:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start
End
Microtask: Promise
Macrotask: setTimeout
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Even though &lt;code&gt;setTimeout&lt;/code&gt; was given &lt;code&gt;0ms&lt;/code&gt;, the &lt;strong&gt;Promise runs first&lt;/strong&gt; because microtasks have higher priority.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Why It Matters
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Misunderstanding this order can cause &lt;strong&gt;hard-to-debug async issues&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Knowing it helps optimize performance, avoid race conditions, and write predictable async code.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6. Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;JavaScript runs one task at a time (single-threaded).&lt;/li&gt;
&lt;li&gt;Event Loop decides what runs next.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks &amp;gt; Macrotasks&lt;/strong&gt; in priority.&lt;/li&gt;
&lt;li&gt;Promises resolve before timers.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;⚡ Mastering the Event Loop is not trivia — it’s critical to writing reliable async JavaScript.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Why AI Won't Take Your Job, But Someone Using AI Will</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Wed, 20 Aug 2025 04:02:06 +0000</pubDate>
      <link>https://forem.com/mehta0007/why-ai-wont-take-your-job-but-someone-using-ai-will-5d3h</link>
      <guid>https://forem.com/mehta0007/why-ai-wont-take-your-job-but-someone-using-ai-will-5d3h</guid>
      <description>&lt;p&gt;We've all seen the headlines. "AI Will Replace 300 Million Jobs!"&lt;/p&gt;

&lt;p&gt;"Developers Obsolete by 2030!" "The Robot Apocalypse is Here!" But here's the thing: after working with AI tools daily and watching this transformation unfold in real-time, I've realized we're asking the wrong question.&lt;br&gt;
The question isn't "Will AI take my job?" It's "Am I learning to work with AI fast enough?"&lt;/p&gt;

&lt;h2&gt;
  
  
  The Automation Paradox We've Seen Before
&lt;/h2&gt;

&lt;p&gt;Remember when calculators were going to make mathematicians obsolete? Or when IDEs would eliminate the need for programmers because "anyone could code"?&lt;br&gt;
What actually happened was more nuanced. These tools didn't replace professionals—they amplified the capable ones and left behind those who refused to adapt.&lt;br&gt;
Today's AI revolution follows the same pattern, but at warp speed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI Alone Can't Replace You (Yet)
&lt;/h2&gt;

&lt;p&gt;Let's be honest about what current AI can and can't do:&lt;br&gt;
&lt;strong&gt;What AI excels at:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Generating boilerplate code faster than you can type&lt;br&gt;
Explaining complex concepts in multiple ways&lt;br&gt;
Debugging obvious syntax errors&lt;br&gt;
Creating initial drafts of documentation&lt;br&gt;
Brainstorming solutions to well-defined problems&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What AI struggles with:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding business context and stakeholder needs&lt;br&gt;
Making architectural decisions that scale&lt;br&gt;
Navigating office politics and client relationships&lt;br&gt;
Knowing when to break the rules (and which rules to break)&lt;br&gt;
Learning your team's specific workflows and conventions&lt;br&gt;
Taking responsibility when things go wrong&lt;/p&gt;

&lt;p&gt;AI is incredibly powerful, but it's still a tool. A very sophisticated tool, but a tool nonetheless.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Threat: Your AI-Powered Colleague
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting. While AI won't replace you directly, someone who's mastered AI might.&lt;br&gt;
Picture two developers applying for the same role:&lt;br&gt;
&lt;strong&gt;Developer A&lt;/strong&gt; writes code the same way they did five years ago. Solid skills, reliable, but their productivity hasn't changed much.&lt;br&gt;
&lt;strong&gt;Developer B&lt;/strong&gt; uses AI to:&lt;/p&gt;

&lt;p&gt;Generate first drafts of functions and let them focus on architecture&lt;br&gt;
Quickly prototype multiple approaches to compare solutions&lt;br&gt;
Create comprehensive tests faster&lt;br&gt;
Explain their code to stakeholders in plain English&lt;br&gt;
Learn new technologies at 3x speed&lt;/p&gt;

&lt;p&gt;Who do you think gets the job? Who gets the promotion? Who becomes indispensable to their team?&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Multiplication Effect
&lt;/h2&gt;

&lt;p&gt;The developers I know who've embraced AI aren't just a little more productive—they're operating on a different level entirely. They're:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shipping features faster&lt;/strong&gt; because they spend less time on boilerplate&lt;br&gt;
&lt;strong&gt;Exploring more solutions&lt;/strong&gt; because iteration is cheaper&lt;br&gt;
&lt;strong&gt;Learning continuously&lt;/strong&gt; because AI makes unfamiliar codebases approachable&lt;br&gt;
&lt;strong&gt;Communicating better&lt;/strong&gt; because AI helps them explain technical concepts&lt;br&gt;
&lt;strong&gt;Taking on bigger challenges&lt;/strong&gt; because they have a powerful thinking partner&lt;/p&gt;

&lt;p&gt;Meanwhile, developers who avoid AI are essentially choosing to compete with one hand tied behind their back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Become the AI-Powered Developer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The good news? Learning to work effectively with AI isn't about mastering complex new technologies. It's about developing new habits and mindsets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Learn to Prompt Like a Pro&lt;/strong&gt;&lt;br&gt;
Bad prompt: "Make a login function"&lt;br&gt;
Good prompt: "Create a secure login function in Node.js with bcrypt hashing, rate limiting, and proper error handling. Include JSDoc comments and handle edge cases like empty inputs and SQL injection attempts."&lt;br&gt;
The difference? Specificity, context, and clear expectations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use AI as a Thinking Partner, Not a Replacement&lt;/strong&gt;&lt;br&gt;
Don't ask AI to solve your problems. Ask it to help you think through them:&lt;/p&gt;

&lt;p&gt;"What are the pros and cons of using Redis vs. Memcached for this use case?"&lt;br&gt;
"What potential security vulnerabilities should I consider with this approach?"&lt;br&gt;
"How would you refactor this function for better testability?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Master the Feedback Loop&lt;/strong&gt;&lt;br&gt;
AI's first answer is rarely its best. Learn to iterate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get an initial solution&lt;/li&gt;
&lt;li&gt;Ask for improvements or alternatives&lt;/li&gt;
&lt;li&gt;Request explanations for parts you don't understand&lt;/li&gt;
&lt;li&gt;Have AI review and critique its own work&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;4. Know When to Ignore AI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This might be the most important skill. AI can be confidently wrong, and knowing when to trust your expertise over the AI's suggestion is crucial.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Skills That Matter More Than Ever
&lt;/h2&gt;

&lt;p&gt;As AI handles more routine tasks, certain human skills become incredibly valuable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Systems thinking:&lt;/strong&gt; Understanding how pieces fit together in complex architectures&lt;br&gt;
&lt;strong&gt;Product sense:&lt;/strong&gt; Knowing what users actually need vs. what they ask for&lt;br&gt;
&lt;strong&gt;Communication:&lt;/strong&gt; Translating between technical and business stakeholders&lt;br&gt;
&lt;strong&gt;Judgment:&lt;/strong&gt; Making decisions with incomplete information&lt;br&gt;
&lt;strong&gt;Creativity:&lt;/strong&gt; Finding novel solutions to unique problems&lt;br&gt;
&lt;strong&gt;Leadership:&lt;/strong&gt; Guiding teams through ambiguous challenges&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future is Collaborative
&lt;/h2&gt;

&lt;p&gt;The most successful developers of the next decade won't be those who fight AI or those who surrender to it. They'll be the ones who learn to dance with it.&lt;br&gt;
Think of AI as the ultimate junior developer: incredibly fast, vast knowledge, but needs direction and oversight. Your job isn't to compete with it—it's to conduct the orchestra.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start Now, Start Small&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don't need to revolutionize your workflow overnight. Start with these small steps:&lt;/p&gt;

&lt;p&gt;This week: Try using AI to explain a piece of code you didn't write&lt;br&gt;
This month: Use AI to generate unit tests for an existing function&lt;br&gt;
Next month: Have AI help you learn a new framework or library&lt;br&gt;
Ongoing: Pay attention to which AI suggestions you accept vs. reject, and why&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Bottom Line&lt;/strong&gt;&lt;br&gt;
AI won't take your job, but it will fundamentally change what your job looks like. The question isn't whether this transformation will happen—it's whether you'll be leading it or scrambling to catch up.&lt;br&gt;
The developers who thrive in the AI era won't be the ones with the most impressive GitHub profiles or the deepest knowledge of obscure frameworks. They'll be the ones who learned to amplify their human intelligence with artificial intelligence.&lt;br&gt;
&lt;strong&gt;Don't fear the AI revolution. Join it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What's your experience working with AI tools? Are you seeing similar patterns in your workplace? Share your thoughts in the comments below.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>career</category>
      <category>learning</category>
    </item>
    <item>
      <title>APIs Explained Simply: Talking to Servers like ordering at a Restaurant</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Tue, 19 Aug 2025 15:25:07 +0000</pubDate>
      <link>https://forem.com/mehta0007/apis-explained-simply-talking-to-servers-like-ordering-at-a-restaurant-20e9</link>
      <guid>https://forem.com/mehta0007/apis-explained-simply-talking-to-servers-like-ordering-at-a-restaurant-20e9</guid>
      <description>&lt;p&gt;APIs can sound scary when you first hear about them.“Application Programming Interface” feels like a mouthful, right? But the truth is… you already use APIs every single day without even realizing it.&lt;/p&gt;

&lt;p&gt;Let’s break it down with something we all love: food.&lt;/p&gt;

&lt;p&gt;*&lt;strong&gt;&lt;em&gt;The Restaurant Analogy *&lt;/em&gt;🍕&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you’re sitting in a restaurant.&lt;/p&gt;

&lt;p&gt;You (the user) are hungry.&lt;/p&gt;

&lt;p&gt;The kitchen is where all the magic (data processing) happens.&lt;/p&gt;

&lt;p&gt;But you don’t just walk into the kitchen and cook, right?&lt;/p&gt;

&lt;p&gt;Instead, you use a waiter. 🧑‍🍳&lt;/p&gt;

&lt;p&gt;You tell the waiter what you want: “One pizza with extra cheese, please.”&lt;/p&gt;

&lt;p&gt;The waiter (the API) takes your request to the kitchen.&lt;/p&gt;

&lt;p&gt;The kitchen prepares the pizza.&lt;/p&gt;

&lt;p&gt;The waiter brings it back to you.&lt;/p&gt;

&lt;p&gt;That’s exactly how APIs work.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Tech Terms ⚙️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You (the user/app) → make a request.&lt;/p&gt;

&lt;p&gt;The API (the waiter) → delivers your request to the server.&lt;/p&gt;

&lt;p&gt;The Server (the kitchen) → does the heavy work.&lt;/p&gt;

&lt;p&gt;The Response (your pizza) → comes back to you.&lt;/p&gt;

&lt;p&gt;Simple!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Real-World Example 🌦️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say you open a weather app.&lt;/p&gt;

&lt;p&gt;You want to know today’s temperature.&lt;/p&gt;

&lt;p&gt;The app asks the weather API: “Hey, what’s the temperature in Delhi?”&lt;/p&gt;

&lt;p&gt;The API runs to the weather server, grabs the info, and serves it back.&lt;/p&gt;

&lt;p&gt;Your app shows: “It’s 32°C and sunny 🌞.”&lt;/p&gt;

&lt;p&gt;No need for you to dig into satellites or climate databases — the API handles it all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why APIs Are Awesome 🚀&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They save time (you don’t reinvent the kitchen every time you want pizza).&lt;/p&gt;

&lt;p&gt;They create consistency (the menu stays the same even if the kitchen changes).&lt;/p&gt;

&lt;p&gt;They connect apps together (Google Maps inside your food delivery app? Yep, API!).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Bite 🍴&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next time you hear API, don’t panic. Just think of a waiter at your favorite restaurant — taking your order, talking to the kitchen, and bringing you exactly what you asked for.&lt;/p&gt;

&lt;p&gt;APIs are not complicated monsters. They’re just the polite middlemen that keep our tech world running smoothly.&lt;/p&gt;

</description>
      <category>api</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Why 2 Lines of Code Can Be Worse Than 100</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Sun, 17 Aug 2025 03:53:57 +0000</pubDate>
      <link>https://forem.com/mehta0007/why-2-lines-of-code-can-be-worse-than-100-33k6</link>
      <guid>https://forem.com/mehta0007/why-2-lines-of-code-can-be-worse-than-100-33k6</guid>
      <description>&lt;p&gt;We often hear developers glorify “short code.” The common belief is: fewer lines = better code. But in reality, short code does not always mean good code. In fact, sometimes 100 lines of code can be far better than 2 lines of code.&lt;/p&gt;

&lt;p&gt;Let’s understand this with a simple example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 9 Balls Puzzle&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have 9 balls, where 8 weigh the same and 1 is heavier. Your goal is to find the heavy ball using the minimum number of weighings.&lt;/p&gt;

&lt;p&gt;The optimal solution requires just 2 weighings:&lt;/p&gt;

&lt;p&gt;Divide the balls into 3 groups of 3.&lt;/p&gt;

&lt;p&gt;Compare two groups. Then compare 2 balls from the heavier group.&lt;/p&gt;

&lt;p&gt;In real life, this logic is simple when explained step by step.&lt;/p&gt;

&lt;p&gt;But imagine if someone compressed the entire logic into two ultra-clever lines of code. Sure, it might run. But will the next developer (or even your future self) be able to read it, debug it, or extend it easily? Probably not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Illusion of Fewer Lines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;2 lines of code: might look “smart” but can hide the actual thought process. It’s like solving the 9 balls puzzle by blurting out the answer without showing how you reached it. Impressive at first glance, but impossible to follow later.&lt;/p&gt;

&lt;p&gt;100 lines of code: may seem long, but if written with clarity, comments, and step-by-step logic, anyone can trace the reasoning. Just like the step-by-step weighing process, it makes the solution transparent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Readability &amp;gt; Brevity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code is read far more often than it is written. When debugging at 3 a.m., you’d much rather have 100 clear lines than 2 “magical” ones.&lt;/p&gt;

&lt;p&gt;Short code is not always efficient code. Efficient code is code that is easy to understand, maintain, and extend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In other words:&lt;/strong&gt;&lt;br&gt;
👉 100 lines that anyone can understand are better than 2 lines that only you understand.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>🔥 Nobody Talks About the Mental Debt of Being a Developer</title>
      <dc:creator>Ankit</dc:creator>
      <pubDate>Wed, 28 May 2025 10:13:55 +0000</pubDate>
      <link>https://forem.com/mehta0007/nobody-talks-about-the-mental-debt-of-being-a-developer-4dcd</link>
      <guid>https://forem.com/mehta0007/nobody-talks-about-the-mental-debt-of-being-a-developer-4dcd</guid>
      <description>&lt;p&gt;Let's be honest.&lt;br&gt;
We all talk about technical debt - bad code, rushed features, and spaghetti logic that haunts our codebase.&lt;br&gt;
 But there's a deeper, darker kind of debt that nobody warns you about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mental Debt&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;-The cost of constantly switching contexts.&lt;br&gt;
-The anxiety of open tabs.&lt;br&gt;
-The guilt of unfinished side projects.&lt;br&gt;
-The burnout masked  as "grind".&lt;br&gt;
and the worst part? it's normalized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context-Switching Isn’t a Skill - It’s a Trap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every dev today is juggling:&lt;br&gt;
-Frontend logic&lt;br&gt;
-Backend APIs&lt;br&gt;
-PR reviews&lt;br&gt;
-CI/CD issues&lt;br&gt;
-Slack messages&lt;br&gt;
-"Just a quick call"&lt;/p&gt;

&lt;p&gt;We treat multitasking like a flex.&lt;br&gt;
It's not. &lt;br&gt;
It's cognitive sef-harm.&lt;br&gt;
your write 30 lines of code, get interupted,&lt;br&gt;
and then return with zero flow.&lt;/p&gt;

&lt;p&gt;But nobody teaches you how to protect your brain from the chaos.&lt;br&gt;
you are expected to "manage"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Never Ends - and That’s Exhausting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every week, there's a new tool, a new JS framework, or a hot backend trick.&lt;br&gt;
And if you are not constantly learning, then you're "falling behind"&lt;/p&gt;

&lt;p&gt;But,&lt;br&gt;
-what if you are tired?&lt;br&gt;
-what if you just want to do good work with what you know?&lt;/p&gt;

&lt;p&gt;That's not laziness.&lt;br&gt;
That's sustainability&lt;br&gt;
The pressure to never stop learning can quietly burn you out, even if you love tech.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Side Projects Are Romanticized Guilt Machines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Everyone says: "Build side projects!"&lt;br&gt;
But what they don't say is:&lt;/p&gt;

&lt;p&gt;-you"ll doubt yourself halfway through.&lt;br&gt;
-you'll compare it to polished Dribble shots.&lt;br&gt;
-you'll start thinking you're not good enough to build something "worthy".&lt;/p&gt;

&lt;p&gt;We made side projects into portfolio, not playgrouds.&lt;br&gt;
We stopped building for fun.&lt;/p&gt;

&lt;p&gt;Now we build to prove something.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Myth of loving what You Do&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;"you are lucky to code for a living".&lt;/p&gt;

&lt;p&gt;Yes we are,&lt;br&gt;
But when passion becomes pressure, it becomes poison|&lt;/p&gt;

&lt;p&gt;When "doing what you love" becomes "doing 24/7" - you burn out.&lt;/p&gt;

&lt;p&gt;And here's the truth:&lt;br&gt;
You don't have to always love coding.&lt;br&gt;
Your just have respect your boundaries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;The Conclusion is:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are not robots,&lt;br&gt;
we are not pipelines.&lt;br&gt;
We are people who think, feel, get overwhelmed, and need breaks.&lt;/p&gt;

&lt;p&gt;Let's normalize:&lt;/p&gt;

&lt;p&gt;-Saying no&lt;br&gt;
-Building slowly&lt;br&gt;
-Logging off&lt;br&gt;
-Not learning every new thing&lt;br&gt;
-Protecting out energy&lt;/p&gt;

&lt;p&gt;If you are feeling tired then you are not alone.&lt;br&gt;
And no, you don't need to ship more to matter.&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>developerlife</category>
      <category>productivity</category>
      <category>burnout</category>
    </item>
  </channel>
</rss>
