<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: John Yaghobieh</title>
    <description>The latest articles on DEV Community by John Yaghobieh (@john_yaghobieh_8f294091f6).</description>
    <link>https://dev.to/john_yaghobieh_8f294091f6</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3731217%2F7e25fd9f-2038-4aa3-859c-2db577422ede.jpg</url>
      <title>DEV Community: John Yaghobieh</title>
      <link>https://dev.to/john_yaghobieh_8f294091f6</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/john_yaghobieh_8f294091f6"/>
    <language>en</language>
    <item>
      <title>The ForgeStack Release Wave: Four New Libraries and the Missing Pieces for Real-Time, AI-Powered Apps</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Sun, 12 Jul 2026 20:34:44 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/the-forgestack-release-wave-four-new-libraries-and-the-missing-pieces-for-real-time-ai-powered-1dph</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/the-forgestack-release-wave-four-new-libraries-and-the-missing-pieces-for-real-time-ai-powered-1dph</guid>
      <description>&lt;p&gt;&lt;strong&gt;Source and repos:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh" rel="noopener noreferrer"&gt;github.com/yaghobieh&lt;/a&gt; · &lt;strong&gt;Portal:&lt;/strong&gt; &lt;a href="https://forgedevstack.com" rel="noopener noreferrer"&gt;forgedevstack.com&lt;/a&gt;&lt;br&gt;
On July 12, 2026 we pushed the largest coordinated release in ForgeStack's history to npm: four brand-new libraries and updates across seven existing ones. The theme is simple. Until today, you could build most of an app on ForgeStack — UI with Bear, routing with Compass, state with Synapse, data with Forge Query, backend with Harbor. But the moment your app needed live updates, real authentication, or an AI feature, you had to leave the stack. This wave closes those gaps.&lt;/p&gt;

&lt;p&gt;Here is what we shipped and why.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem We Kept Hitting
&lt;/h2&gt;

&lt;p&gt;Every modern product brief now includes the same three requirements: it should update in real time, it should have proper login, and it should have some AI in it. A chat app. A live dashboard. A document Q&amp;amp;A feature. Building these on ForgeStack meant wiring in Socket.IO, an auth SaaS, and a LangChain-sized dependency tree — three ecosystems with three different philosophies bolted onto a stack whose whole point is coherence.&lt;/p&gt;

&lt;p&gt;So we built the missing pillars ourselves, the ForgeStack way: TypeScript-first, minimal or zero dependencies, and small APIs that compose with the rest of the stack.&lt;/p&gt;


&lt;h2&gt;
  
  
  Pillar 1: Real Time — Harbor WS Hub + Forge Socket
&lt;/h2&gt;

&lt;p&gt;Harbor 1.6.3 (&lt;a href="https://github.com/yaghobieh/Harbor" rel="noopener noreferrer"&gt;github.com/yaghobieh/Harbor&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@forgedevstack/harbor" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) adds a first-class WebSocket Hub under a new &lt;code&gt;@forgedevstack/harbor/ws&lt;/code&gt; subpath. It handles the parts that are annoying to get right: authentication runs &lt;em&gt;before&lt;/em&gt; the upgrade is accepted (rejected clients get a proper HTTP 401 and never open a socket), all traffic uses a typed &lt;code&gt;{ event, payload }&lt;/code&gt; envelope, rooms clean up after themselves, heartbeats terminate dead connections, and a pub/sub adapter contract lets you fan out across multiple instances (in-memory by default, Redis-compatible by contract).&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;createServer&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;@forgedevstack/harbor&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;createWsHub&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;@forgedevstack/harbor/ws&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&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;hub&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createWsHub&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;authenticate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;??&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;http://localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;searchParams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;token&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;verifyToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&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="na"&gt;accept&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&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="na"&gt;accept&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="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat:send&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="k"&gt;void&lt;/span&gt; &lt;span class="nx"&gt;hub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;broadcastToRoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lobby&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;chat:new&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="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the other side of the wire sits the brand-new &lt;strong&gt;Forge Socket 1.0.0&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/forge-socket" rel="noopener noreferrer"&gt;github.com/yaghobieh/forge-socket&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@forgedevstack/forge-socket" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) — a typed WebSocket client for the browser and Node with zero runtime dependencies. It speaks the same envelope protocol as the hub and handles reconnection with capped exponential backoff and jitter, heartbeat keepalive, room membership that automatically rejoins after a reconnect, and an offline queue for messages sent while the connection is down.&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;ForgeSocket&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;@forgedevstack/forge-socket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Incoming&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat:new&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="nl"&gt;from&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="nl"&gt;text&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="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Outgoing&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat:send&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="nl"&gt;text&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="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ForgeSocket&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Incoming&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Outgoing&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;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wss://example.com/chat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;socket&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;chat:new&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="nx"&gt;payload&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;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lobby&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chat:send&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&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;lobby&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;Server and client were designed as twins. You define your event map once and both ends are typed.&lt;/p&gt;

&lt;p&gt;And to complete the loop into the UI layer, Forge Query 1.0.1 (&lt;a href="https://github.com/yaghobieh/forge-query" rel="noopener noreferrer"&gt;github.com/yaghobieh/forge-query&lt;/a&gt;) adds &lt;code&gt;useSubscription&lt;/code&gt; — a hook that keeps a cached query updated from any push source. It is adapter-based, so the library has zero transport dependencies: hand it a &lt;code&gt;subscribe(listener) =&amp;gt; cleanup&lt;/code&gt; source (a Forge Socket handler fits naturally), give it an &lt;code&gt;onEvent&lt;/code&gt; reducer, and events fold into the cache. The same release brings declarative optimistic updates to &lt;code&gt;useMutation&lt;/code&gt;, with automatic snapshot and rollback on error.&lt;/p&gt;

&lt;p&gt;Harbor 1.6.3 also ships streaming multipart uploads (&lt;code&gt;@forgedevstack/harbor/upload&lt;/code&gt;): file bytes flow straight to a storage adapter without buffering whole files in memory, with per-file size limits, mime allowlists, and a built-in local disk adapter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pillar 2: Auth — Forge Auth 2.0.0
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Forge Auth&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/forge-auth" rel="noopener noreferrer"&gt;github.com/yaghobieh/forge-auth&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@forgedevstack/forge-auth" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) is an auth toolkit for Node.js built entirely on &lt;code&gt;node:crypto&lt;/code&gt; — zero runtime dependencies. It covers HMAC-SHA256 signed session tokens with TTL, scrypt password hashing with self-describing hash strings, API key generation and timing-safe verification, and OIDC authorization-code helpers with PKCE (S256).&lt;/p&gt;

&lt;p&gt;The design bet is framework-agnostic guards: plain functions over a minimal &lt;code&gt;{ headers }&lt;/code&gt; request shape that return &lt;code&gt;{ authorized, context }&lt;/code&gt;. They work with Harbor, Express, Fastify, or raw &lt;code&gt;node:http&lt;/code&gt; — and the same session guard that protects an HTTP route can protect a WebSocket upgrade in the WS Hub's &lt;code&gt;authenticate&lt;/code&gt; 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;createSession&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createSessionGuard&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;@forgedevstack/forge-auth&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;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ttlSeconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3600&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;guard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSessionGuard&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&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="nl"&gt;role&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;secret&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;guard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorized&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Pillar 3: AI — Forge AI 1.0.0
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Forge AI&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/forge-ai" rel="noopener noreferrer"&gt;github.com/yaghobieh/forge-ai&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@forgedevstack/forge-ai" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) is deliberately a &lt;em&gt;thin&lt;/em&gt; RAG toolkit, not a framework. It gives you text chunking (fixed-size or sentence-boundary strategies with overlap), provider-agnostic embeddings (a built-in client for any OpenAI-compatible endpoint, or implement the &lt;code&gt;EmbeddingProvider&lt;/code&gt; interface for anything else), and pgvector SQL helpers for table creation and cosine-similarity queries. Document extraction for pdf/docx/xlsx is defined as a contract with an extractor registry — parsers like &lt;code&gt;pdf-parse&lt;/code&gt;, &lt;code&gt;mammoth&lt;/code&gt;, and &lt;code&gt;xlsx&lt;/code&gt; are optional peer dependencies you register yourself, so the core stays at zero runtime dependencies.&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;chunkText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createOpenAiEmbeddingProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buildSimilarityQuerySql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;formatVectorLiteral&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;@forgedevstack/forge-ai&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;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;chunkText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;documentText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sentence&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;chunkSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;overlap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;64&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;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createOpenAiEmbeddingProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.openai.com/v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OPENAI_API_KEY&lt;/span&gt; &lt;span class="o"&gt;??&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;chunk&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;chunk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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;queryEmbedding&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;What is ForgeStack?&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;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;buildSimilarityQuerySql&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;table&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;documents&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;topK&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;formatVectorLiteral&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queryEmbedding&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;If you have ever wanted RAG without adopting an entire orchestration framework, this is the shape we wanted it to have: functions you call, SQL you can read, and your own database.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pillar 4: MCP — Forge MCP 1.0.0
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Forge MCP&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/forge-mcp" rel="noopener noreferrer"&gt;github.com/yaghobieh/forge-mcp&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@forgedevstack/forge-mcp" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) is a tiny helper for building API-key-protected stdio &lt;a href="https://modelcontextprotocol.io" rel="noopener noreferrer"&gt;MCP&lt;/a&gt; servers — the protocol that lets agents like Cursor and Claude Desktop call your tools. It wraps the official SDK so you define tools with plain JSON schemas (no zod, no boilerplate) and get a working server from one &lt;code&gt;createMcpServer&lt;/code&gt; call. The API key resolves eagerly so a misconfigured server fails at startup, not on the first tool call. If you are shipping a product in 2026, an MCP server is becoming as standard as a REST API; this makes it a twenty-line task.&lt;/p&gt;




&lt;h2&gt;
  
  
  Grid Table Grows Up
&lt;/h2&gt;

&lt;p&gt;Grid Table 1.1.1 (&lt;a href="https://github.com/yaghobieh/grid-table" rel="noopener noreferrer"&gt;github.com/yaghobieh/grid-table&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/@forgedevstack/grid-table" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) is the biggest single-library drop in the wave, and it moves the grid firmly into AG-Grid territory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Set filters&lt;/strong&gt; (checkbox lists) and &lt;strong&gt;date range filters&lt;/strong&gt; in the filter popup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expandable group rows&lt;/strong&gt; with collapse/expand on group headers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excel-style range selection&lt;/strong&gt; with drag-to-select, plus &lt;strong&gt;clipboard paste&lt;/strong&gt; of tab-separated data into a selected range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSRM-style infinite scroll&lt;/strong&gt; with block loading (&lt;code&gt;onLoadBlock&lt;/code&gt;, &lt;code&gt;blockSize&lt;/code&gt;, &lt;code&gt;totalRowCount&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-row column group headers&lt;/strong&gt; with real colspan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delta row updates&lt;/strong&gt; via an &lt;code&gt;applyTransaction&lt;/code&gt; utility for &lt;code&gt;{ add, update, remove }&lt;/code&gt; batches, with &lt;strong&gt;flash cells&lt;/strong&gt; highlighting what changed&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;fill handle&lt;/strong&gt; and &lt;strong&gt;bulk edit&lt;/strong&gt; config for spreadsheet-style editing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Export scope&lt;/strong&gt; control (&lt;code&gt;all&lt;/code&gt; / &lt;code&gt;filtered&lt;/code&gt; / &lt;code&gt;sorted&lt;/code&gt; / &lt;code&gt;selected&lt;/code&gt;) and &lt;strong&gt;saved views synced to the URL&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pair delta updates and flash cells with Forge Socket and you have a live-updating dashboard grid without a commercial grid license.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Supporting Cast
&lt;/h2&gt;

&lt;p&gt;The rest of the stack kept pace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bear 1.2.5&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;github.com/yaghobieh/bear&lt;/a&gt;) adds &lt;code&gt;MessageList&lt;/code&gt; — a chat message list with consecutive-author grouping, day separators, auto-scroll, and a "new messages" affordance — plus &lt;code&gt;pauseOnHover&lt;/code&gt; and &lt;code&gt;maxToasts&lt;/code&gt; for toasts, a multiline mode for &lt;code&gt;MentionsInput&lt;/code&gt;, and full light-mode support for &lt;code&gt;CommandPalette&lt;/code&gt;. Notice a pattern? The chat-app UI pieces landed in the same wave as the socket layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synapse 1.2.1&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/synapse" rel="noopener noreferrer"&gt;github.com/yaghobieh/synapse&lt;/a&gt;) wires persistence directly into &lt;code&gt;createNucleus&lt;/code&gt; (hydrate on creation, debounced writes, versioned migrations), ships storage adapters for local/session/memory, makes the middleware pipeline functional with a new &lt;code&gt;interceptor&lt;/code&gt;, and adds a zero-dependency Redux DevTools connector.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forge Query 1.0.1&lt;/strong&gt; — live subscriptions and optimistic updates, covered above.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forge Compass 1.0.3&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/compass" rel="noopener noreferrer"&gt;github.com/yaghobieh/compass&lt;/a&gt;) — browser back/forward now behaves exactly as users expect on &lt;code&gt;popstate&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kiln 1.0.6&lt;/strong&gt; (&lt;a href="https://github.com/yaghobieh/kiln" rel="noopener noreferrer"&gt;github.com/yaghobieh/kiln&lt;/a&gt;) — our Storybook alternative keeps maturing, with URL-addressable story routes and a docs-first tab option.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What This Adds Up To
&lt;/h2&gt;

&lt;p&gt;Take stock of what a ForgeStack app can now be, end to end: Harbor serving the API and the WebSocket hub, Forge Auth guarding both, Forge Socket and Forge Query streaming server events into the cache, Synapse persisting client state, Bear rendering the chat with &lt;code&gt;MessageList&lt;/code&gt;, Grid Table flashing delta updates into a live dashboard, Forge AI powering document Q&amp;amp;A over pgvector, and Forge MCP exposing the whole thing to AI agents. Every package is MIT licensed, TypeScript-first, and deliberately small.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @forgedevstack/forge-socket @forgedevstack/forge-auth @forgedevstack/forge-ai @forgedevstack/forge-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docs and live examples are on the portal at &lt;a href="https://forgedevstack.com" rel="noopener noreferrer"&gt;forgedevstack.com&lt;/a&gt;, and every repo lives under &lt;a href="https://github.com/yaghobieh" rel="noopener noreferrer"&gt;github.com/yaghobieh&lt;/a&gt;. If you build something with the new pillars — a chat app, a live grid, a RAG feature — we would genuinely like to see it.&lt;/p&gt;

</description>
      <category>react</category>
      <category>ai</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I'm Preventing Most of the Bugs Before They Ship — Bear UI 1.2.4</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Sun, 14 Jun 2026 15:58:57 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/how-im-preventing-most-of-the-bugs-before-they-ship-bear-ui-124-1l44</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/how-im-preventing-most-of-the-bugs-before-they-ship-bear-ui-124-1l44</guid>
      <description>&lt;p&gt;Repository: &lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/bear&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most bugs in a component library don't come from bad logic. They come from a component page crashing silently, a dark-mode toggle being forgotten on one surface, or a refactor that quietly broke &lt;code&gt;onChange&lt;/code&gt; wiring three files away.&lt;/p&gt;

&lt;p&gt;Bear UI 1.2.4 ships a full automated sanity layer that catches those before a single line of source code is committed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem with "it worked on my machine"
&lt;/h2&gt;

&lt;p&gt;Bear has over 100 components and a full documentation portal. Every release I was manually clicking through pages, toggling dark mode, and checking the console — the same ritual every time, for every component.&lt;/p&gt;

&lt;p&gt;It was slow, inconsistent, and easy to forget. So I automated it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the sanity layer does
&lt;/h2&gt;

&lt;p&gt;Every &lt;code&gt;git commit&lt;/code&gt; now triggers a 4-step gate before the commit is allowed through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1 — ESLint  (code review gates G1–G10)
Step 2 — TypeScript  (tsc --noEmit)
Step 3 — Vitest  (unit tests)
Step 4 — Playwright  (275 e2e tests)
→ Generates: Sanity/sanity-release-1.2.4.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any step fails, the commit is blocked with a clear summary and the report is updated.&lt;/p&gt;




&lt;h2&gt;
  
  
  The three Playwright suites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Render sanity (135 tests)
&lt;/h3&gt;

&lt;p&gt;Every page in the portal — from &lt;code&gt;/&lt;/code&gt; to &lt;code&gt;/components/watermark&lt;/code&gt; — is visited headlessly. The test asserts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page returns a non-400 response&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;body&lt;/code&gt; is visible&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.doc-preview&lt;/code&gt; playground exists on component pages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PropsTable&lt;/code&gt; headers are present on component pages&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero console errors&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last check is the most valuable. It catches React prop warnings, missing &lt;code&gt;onChange&lt;/code&gt; handlers, broken imports — things that render visually but scream in the DevTools console.&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="nx"&gt;page&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;console&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="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&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;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;consoleErrors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="c1"&gt;// after page load:&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;consoleErrors&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveLength&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Interaction checks (119 tests)
&lt;/h3&gt;

&lt;p&gt;Every component page gets clicked. Each test finds the first interactive Bear element inside the demo preview and clicks it. For key components, a specific interaction map defines the exact selector and expected state:&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/components/switch&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="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.doc-preview__stage .Bear-Switch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/components/select&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="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.Bear-Select__trigger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;expectVisible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.Bear-Select__dropdown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The test only asserts that no JavaScript error is thrown after interaction. No crash = pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dark mode (21 tests)
&lt;/h3&gt;

&lt;p&gt;A sample of 10 representative routes are tested in both modes:&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;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bear-portal-theme&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="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reload&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;dark&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&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="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&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="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An extra test verifies the theme persists across navigation — not just within a single page reload.&lt;/p&gt;




&lt;h2&gt;
  
  
  The code review gates
&lt;/h2&gt;

&lt;p&gt;The ESLint step enforces 10 structural gates defined in the Bear code review skill:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gate&lt;/th&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;G1&lt;/td&gt;
&lt;td&gt;No magic strings or numbers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G3&lt;/td&gt;
&lt;td&gt;No HTML comments in JSX&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G4&lt;/td&gt;
&lt;td&gt;No bare &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; for layout&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G7&lt;/td&gt;
&lt;td&gt;One component per &lt;code&gt;.tsx&lt;/code&gt; file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;G10&lt;/td&gt;
&lt;td&gt;1 const + 1 types file per folder&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Gates that can't be automated yet (G2, G5, G6, G8, G9) are flagged as &lt;code&gt;🔍 Manual&lt;/code&gt; in the report and stay in the structured code review checklist.&lt;/p&gt;




&lt;h2&gt;
  
  
  The sanity report
&lt;/h2&gt;

&lt;p&gt;Every run generates a markdown file at &lt;code&gt;Sanity/sanity-release-{version}.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Bear Portal Sanity Report — release/1.2.4&lt;/span&gt;

&lt;span class="gs"&gt;**Overall Status:**&lt;/span&gt; ✅ PASSED

&lt;span class="gu"&gt;## Code Review Gates&lt;/span&gt;
| Gate | Rule          | Status |
|------|---------------|--------|
| G1   | No magic strings | ✅  |
| G3   | No HTML comments | ✅  |

&lt;span class="gu"&gt;## Playwright Sanity Results&lt;/span&gt;
| Suite        | Passed | Failed | Total |
|--------------|--------|--------|-------|
| Page Render  |   135  |    0   |  135  |
| Interactions |   119  |    0   |  119  |
| Dark Mode    |    21  |    0   |   21  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The file is committed alongside source changes so every release has a traceable record of what passed.&lt;/p&gt;




&lt;h2&gt;
  
  
  It already found a real bug
&lt;/h2&gt;

&lt;p&gt;On the first run, all 275 tests failed — the Playwright suite caught a &lt;code&gt;console.error&lt;/code&gt; from React on every page:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Warning: You provided a value prop to a form field without an onChange handler...&lt;/code&gt;&lt;br&gt;
at &lt;code&gt;Sidebar.tsx:331&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;Sidebar&lt;/code&gt; component had a &lt;code&gt;&amp;lt;select value={...}&amp;gt;&lt;/code&gt; with no &lt;code&gt;onChange&lt;/code&gt;. It rendered fine visually. Zero user-facing symptoms. But the hook was in the global layout, so React logged the error on every single page.&lt;/p&gt;

&lt;p&gt;The suite caught it before the branch was merged.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting it up
&lt;/h2&gt;

&lt;p&gt;The full setup uses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Husky&lt;/strong&gt; for the pre-commit hook&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@playwright/test&lt;/strong&gt; for e2e (runs Chromium headlessly)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Playwright webServer&lt;/strong&gt; option to auto-start/stop the portal dev server during tests&lt;/li&gt;
&lt;li&gt;A Node.js report generator script (&lt;code&gt;generate-report.mjs&lt;/code&gt;) that reads the Playwright JSON output and combines it with ESLint and TypeScript results
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run sanity   &lt;span class="c"&gt;# run the full check at any time without committing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Playwright config uses a &lt;code&gt;.cjs&lt;/code&gt; extension to work around the &lt;code&gt;"type": "module"&lt;/code&gt; in the project's &lt;code&gt;package.json&lt;/code&gt;, with a separate &lt;code&gt;e2e/package.json&lt;/code&gt; setting &lt;code&gt;"type": "commonjs"&lt;/code&gt; so TypeScript spec files are loaded correctly on Node 18.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;The remaining manual gates (G2, G5, G8, G9) are good candidates for custom ESLint rules in &lt;a href="https://www.npmjs.com/package/@forgedevstack/lintforge" rel="noopener noreferrer"&gt;LintForge&lt;/a&gt;. Once those are automated, the entire Bear code review can run without a human in the loop.&lt;/p&gt;




&lt;p&gt;Bear UI 1.2.4 is available now:&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; @forgedevstack/bear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repo and full code: &lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/bear&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>aerocraft</category>
      <category>css</category>
    </item>
    <item>
      <title>Bear UI 1.2.3: Goodbye Tailwind, Hello AeroCraft</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Wed, 20 May 2026 21:01:58 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-123-goodbye-tailwind-hello-aerocraft-258i</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-123-goodbye-tailwind-hello-aerocraft-258i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;github.com/yaghobieh/bear&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Docs:&lt;/strong&gt; &lt;a href="https://bearui.com" rel="noopener noreferrer"&gt;bearui.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;code&gt;@forgedevstack/bear@1.2.3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Bear UI &lt;code&gt;1.2.3&lt;/code&gt; is a foundation release. The headline change is not another component — it is how the library is styled and built. We migrated the entire CSS pipeline from Tailwind CSS to &lt;a href="https://github.com/yaghobieh/aero-craft" rel="noopener noreferrer"&gt;&lt;strong&gt;AeroCraft&lt;/strong&gt;&lt;/a&gt; (&lt;code&gt;@forgedevstack/aerocraft&lt;/code&gt;), the utility engine we ship across ForgeStack.&lt;/p&gt;

&lt;p&gt;If you only install Bear and import &lt;code&gt;styles.css&lt;/code&gt;, your app keeps working the same way. If you maintain Bear or customize themes, this release is worth reading end to end.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why we moved off Tailwind
&lt;/h2&gt;

&lt;p&gt;Bear grew on Tailwind for years. It worked, but three problems kept showing up as the library and ForgeStack ecosystem scaled:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stack alignment&lt;/strong&gt; — AeroCraft, AeroCraft Portal, Grid Table, and other ForgeStack libs share one styling model. Keeping Bear on Tailwind meant two utility dialects, two configs, and duplicated mental overhead for contributors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Class noise at scale&lt;/strong&gt; — Hundreds of components with long &lt;code&gt;bear-*&lt;/code&gt; utility chains are hard to review and easy to drift. AeroCraft gives us config-driven shortcuts, component recipes, and the same &lt;code&gt;bear-&lt;/code&gt; prefix without Tailwind as a middle layer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build ownership&lt;/strong&gt; — We wanted a PostCSS pipeline we control end to end: theme tokens, dark mode selectors, responsive groups, and future VS Code tooling (the AeroCraft plugin) tied to the same config Bear ships.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We did not move because Tailwind is bad. We moved because &lt;strong&gt;one CSS engine for the whole stack&lt;/strong&gt; is simpler for maintainers and more predictable for consumers.&lt;/p&gt;
&lt;h2&gt;
  
  
  What AeroCraft changes under the hood
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Before (Tailwind)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@tailwind&lt;/span&gt; &lt;span class="n"&gt;utilities&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Build: &lt;code&gt;tailwindcss&lt;/code&gt; CLI + &lt;code&gt;tailwind.config.js&lt;/code&gt; + &lt;code&gt;autoprefixer&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  After (AeroCraft)
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@aerocraft&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Build: &lt;code&gt;postcss-cli&lt;/code&gt; + &lt;code&gt;@forgedevstack/aerocraft/postcss&lt;/code&gt; + &lt;code&gt;aerocraft.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bear keeps the same class prefix consumers already know:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// aerocraft.config.js (simplified)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bear&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;separator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standalone&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;responsive&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="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/**/*.{ts,tsx}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bear&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* pink scale */&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;zinc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PostCSS wires AeroCraft with Bear’s dark-mode convention:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;aerocraftPlugin&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;@forgedevstack/aerocraft/postcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;config&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;./aerocraft.config.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;postcssImport&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nf"&gt;aerocraftPlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;darkSelector&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, .bear-dark&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;_base.css&lt;/code&gt; now ships full semantic scales (secondary, success, warning, danger, info, neutral) as CSS variables, so theming stays consistent in light and dark mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for your app
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You are…&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Using Bear via npm and &lt;code&gt;import '@forgedevstack/bear/styles.css'&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No change required.&lt;/strong&gt; Styles are pre-built in &lt;code&gt;dist/styles.css&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Customizing Bear colors via &lt;code&gt;BearProvider&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;No change required.&lt;/strong&gt; CSS variables still drive variants.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forking Bear or running &lt;code&gt;npm run build&lt;/code&gt; in the repo&lt;/td&gt;
&lt;td&gt;Install &lt;code&gt;@forgedevstack/aerocraft&lt;/code&gt; as a devDependency; Tailwind is removed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Want your own utility layer on top&lt;/td&gt;
&lt;td&gt;Optional: add &lt;code&gt;aerocraft.config.js&lt;/code&gt; + PostCSS plugin (see portal Installation page).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Publishing &lt;code&gt;@forgedevstack/bear@1.2.3&lt;/code&gt; to npm does &lt;strong&gt;not&lt;/strong&gt; force you to install AeroCraft in your app unless you build Bear from source.&lt;/p&gt;

&lt;h2&gt;
  
  
  Component updates in 1.2.3
&lt;/h2&gt;

&lt;p&gt;The CSS migration shipped alongside practical API improvements on high-traffic primitives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Button
&lt;/h3&gt;

&lt;p&gt;New props for dense, branded, and interactive UIs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;radius&lt;/code&gt; — &lt;code&gt;default&lt;/code&gt; | &lt;code&gt;pill&lt;/code&gt; | &lt;code&gt;square&lt;/code&gt; | &lt;code&gt;none&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ripple&lt;/code&gt; — Material-style click ripple&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gradient&lt;/code&gt; + &lt;code&gt;gradientDirection&lt;/code&gt; — two-color backgrounds&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compact&lt;/code&gt; — tighter padding for toolbars&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;prefix&lt;/code&gt; / &lt;code&gt;suffix&lt;/code&gt; — badges, shortcuts, status dots&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tooltip&lt;/code&gt; — shorthand hover hint&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;
  &lt;span class="na"&gt;gradient&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ec4899&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;#8b5cf6&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="na"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pill"&lt;/span&gt;
  &lt;span class="na"&gt;ripple&lt;/span&gt;
  &lt;span class="na"&gt;spotlight&lt;/span&gt;
  &lt;span class="na"&gt;leftIcon&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearIcons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;RocketIcon&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Launch"&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Launch
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Input
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;prefix&lt;/code&gt; / &lt;code&gt;suffix&lt;/code&gt; — inline static text (&lt;code&gt;$&lt;/code&gt;, &lt;code&gt;https://&lt;/code&gt;, units)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;loading&lt;/code&gt; — spinner inside the field&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;copyable&lt;/code&gt; + &lt;code&gt;onCopy&lt;/code&gt; — one-click copy&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;floatingLabel&lt;/code&gt; + &lt;code&gt;required&lt;/code&gt; — denser form layouts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;variant&lt;/code&gt; / &lt;code&gt;radius&lt;/code&gt; — aligned with other Bear inputs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dropdown
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;searchable&lt;/code&gt; + &lt;code&gt;searchPlaceholder&lt;/code&gt; + &lt;code&gt;filterFn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;multiSelect&lt;/code&gt; + &lt;code&gt;selectedKeys&lt;/code&gt; + &lt;code&gt;onSelectionChange&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;loading&lt;/code&gt; / &lt;code&gt;loadingText&lt;/code&gt; / &lt;code&gt;emptyText&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;header&lt;/code&gt; / &lt;code&gt;footer&lt;/code&gt; — composition slots&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;renderItem&lt;/code&gt; — custom row rendering&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;virtualized&lt;/code&gt; — large lists&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Drawer
&lt;/h3&gt;

&lt;p&gt;Internal refactor: size/position/transform maps moved to &lt;code&gt;Drawer.const.ts&lt;/code&gt;, scroll locking to &lt;code&gt;Drawer.utils.ts&lt;/code&gt; — no intentional breaking API changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ecosystem context (1.2.2 → 1.2.3)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;1.2.2&lt;/code&gt; added a large batch of display components (GlowCard, Heatmap, TagCloud, MediaPlayer, AnimatedCounter, CurrencyInput, TimelineChart, ImageAnnotation, and more). &lt;code&gt;1.2.3&lt;/code&gt; stabilizes how they are styled going forward on AeroCraft.&lt;/p&gt;

&lt;p&gt;The portal also teases &lt;strong&gt;Torch&lt;/strong&gt; (&lt;code&gt;@forgedevstack/player&lt;/code&gt;) — playlists, subtitles, PiP, and streaming built to pair with Bear layouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upgrade
&lt;/h2&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; @forgedevstack/bear@1.2.3
&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="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@forgedevstack/bear/styles.css&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;BearProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dropdown&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;@forgedevstack/bear&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;Explore live docs: &lt;a href="https://bearui.com" rel="noopener noreferrer"&gt;bearui.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bear: &lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;github.com/yaghobieh/bear&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AeroCraft: &lt;a href="https://github.com/yaghobieh/aerocraft" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/aero-craft&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm Bear: &lt;a href="https://www.npmjs.com/package/@forgedevstack/bear" rel="noopener noreferrer"&gt;npmjs.com/package/@forgedevstack/bear&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm AeroCraft: &lt;a href="https://www.npmjs.com/package/@forgedevstack/aerocraft" rel="noopener noreferrer"&gt;npmjs.com/package/@forgedevstack/aerocraft&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tailwindcss</category>
      <category>forgestack</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>AeroCraft: Less CSS, Faster UI Delivery</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Sat, 25 Apr 2026 11:09:56 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/aerocraft-less-css-faster-ui-delivery-3043</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/aerocraft-less-css-faster-ui-delivery-3043</guid>
      <description>&lt;p&gt;Repo: &lt;a href="https://github.com/yaghobieh/aerocraft" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/aerocraft&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Package: &lt;a href="https://www.npmjs.com/package/@forgedevstack/aerocraft" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@forgedevstack/aerocraft&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AeroCraft is a utility and shortcut CSS engine for teams that want the speed of utility classes with better readability and stronger design consistency.&lt;/p&gt;

&lt;p&gt;Instead of repeating 8-12 classes for every button, card, and shell, you compose higher-level shortcuts (and component recipes) from your config, then reuse them everywhere.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why AeroCraft?
&lt;/h2&gt;

&lt;p&gt;Most teams hit the same pain points with CSS utility workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long class strings are hard to scan in code reviews&lt;/li&gt;
&lt;li&gt;Repeated patterns drift across pages&lt;/li&gt;
&lt;li&gt;Design tokens live in one place, but UI classes don’t&lt;/li&gt;
&lt;li&gt;Migration between projects/frameworks gets noisy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AeroCraft addresses this by generating reusable shortcuts from config, with optional responsive variants and typed design tokens.&lt;/p&gt;
&lt;h2&gt;
  
  
  Advantages vs Typical Utility-First Setup
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1) Shorter, clearer class names
&lt;/h3&gt;

&lt;p&gt;You can collapse repeated utility combinations into one semantic shortcut.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-row-center gap-2 px-5 py-3 rounded-lg font-semibold cursor-pointer w-full transition-fast color-white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Buy now
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can define recipe classes and use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button-core button-touch-48 button-primary-rounded"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Buy now
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Config-driven design system
&lt;/h3&gt;

&lt;p&gt;Your styles are generated from a single source of truth:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;theme&lt;/code&gt; for colors, spacing, fonts, radii, shadows&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;customShortcuts&lt;/code&gt; for reusable layout/semantic helpers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;componentRecipes&lt;/code&gt; for real component-like classes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3) Framework-agnostic output
&lt;/h3&gt;

&lt;p&gt;AeroCraft emits plain CSS. Use it with React, Vue, Angular, Svelte, or vanilla HTML without runtime lock-in.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Responsive-ready utilities
&lt;/h3&gt;

&lt;p&gt;Enable &lt;code&gt;responsive: true&lt;/code&gt; and get breakpoint variants from your config breakpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  5) Better scaling for teams
&lt;/h3&gt;

&lt;p&gt;Teams get consistent naming and less copy-paste CSS noise in JSX/HTML.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @forgedevstack/aerocraft postcss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;postcss.config.js&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&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;aerocraftPlugin&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;@forgedevstack/aerocraft/postcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;config&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;./aerocraft.config.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;aerocraftPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;src/styles/aerocraft.css&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@aerocraft&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;src/main.tsx&lt;/code&gt; (or equivalent entry)
&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./styles/aerocraft.css&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;h2&gt;
  
  
  Real Config Example
&lt;/h2&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;defineConfig&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;@forgedevstack/aerocraft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;responsive&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="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#2563eb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#3b82f6&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#1d4ed8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff8a3c&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="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Plus Jakarta Sans&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;ui-sans-serif&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;system-ui&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;sans-serif&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="na"&gt;screens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;sm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;640px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;md&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;768px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1024px&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="na"&gt;customShortcuts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background-brand-gradient&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="na"&gt;group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;css&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;background-image&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;linear-gradient(90deg,#3b82f6,#6366f1)&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="na"&gt;componentRecipes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-core&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="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;inline-flex&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;align-items&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;center&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;justify-content&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;center&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0.5rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&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;font-weight&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;600&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pointer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all 180ms ease&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-touch-48&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;min-height&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;48px&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;0.75rem 1.25rem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button-primary-rounded&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="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;#ffffff&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;border-radius&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;0.75rem&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;background-image&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;linear-gradient(90deg,#3b82f6,#6366f1)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A) Utility composition
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-col gap-4 p-4 rounded-xl"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h2&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"font-bold"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Utility composition&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"color-brand-500"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Readable and fast.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  B) Component-style composition
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"button-core button-touch-48 button-primary-rounded"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Continue
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C) Responsive usage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex-col md:flex-row gap-3"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;aside&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full md:w-[280px]"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Filters&lt;span class="nt"&gt;&amp;lt;/aside&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;main&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w-full"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Results&lt;span class="nt"&gt;&amp;lt;/main&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When AeroCraft Fits Best
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You want utility-class speed without unreadable markup&lt;/li&gt;
&lt;li&gt;You need a config-driven bridge between design tokens and classes&lt;/li&gt;
&lt;li&gt;You ship across multiple frameworks and want one CSS strategy&lt;/li&gt;
&lt;li&gt;You want to define once and reuse patterns (&lt;code&gt;componentRecipes&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;AeroCraft keeps the productivity of utility CSS, but adds structure where teams need it most: naming, reuse, and config-driven consistency.&lt;/p&gt;

&lt;p&gt;If your class strings are getting repetitive, AeroCraft gives you a clean path to shorter markup and scalable styling.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/yaghobieh/aerocraft" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/aerocraft&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>forgestack</category>
      <category>typescript</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>Rail: We’re Proud to Open-Source the Motion Layer We Always Wanted for React</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Thu, 09 Apr 2026 20:27:21 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/rail-were-proud-to-open-source-the-motion-layer-we-always-wanted-for-react-5f49</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/rail-were-proud-to-open-source-the-motion-layer-we-always-wanted-for-react-5f49</guid>
      <description>&lt;p&gt;There is a peculiar pride in shipping something you &lt;em&gt;felt&lt;/em&gt; before you could &lt;em&gt;name&lt;/em&gt; it: the conviction that carousels in real products deserve better than brittle hacks, copy-pasted snippets, and “good enough” sliders that break the moment you need accessibility, touch, or a second row of thumbnails.&lt;/p&gt;

&lt;p&gt;Today we’re &lt;strong&gt;proud to open-source Rail&lt;/strong&gt; — a &lt;strong&gt;modular carousel engine for React&lt;/strong&gt; — and to place it squarely in the &lt;strong&gt;ForgeStack&lt;/strong&gt; ecosystem alongside &lt;strong&gt;Bear&lt;/strong&gt;, our UI kit, and the rest of the tools we actually build with.&lt;/p&gt;

&lt;p&gt;This is not a humble brag. It’s an invitation: &lt;strong&gt;the code is yours&lt;/strong&gt;, the docs are live, and the playground is waiting.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Rail exists (the short, loud version)
&lt;/h2&gt;

&lt;p&gt;Modern interfaces &lt;em&gt;move&lt;/em&gt;. Hero strips, onboarding tours, story-style sequences, image galleries, and data-heavy carousels are not edge cases — they are the spine of how users scan and decide. Yet the developer experience around “a slider that doesn’t embarrass you in production” has lagged behind the rest of the React stack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rail exists because we refused to accept that trade-off.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We wanted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Physics that feel intentional&lt;/strong&gt; — snap, momentum, loop, and responsive breakpoints without sacrificing control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modularity that scales&lt;/strong&gt; — navigation, pagination, autoplay, keyboard, thumbs, virtual slides, and dozens of other concerns as &lt;strong&gt;opt-in modules&lt;/strong&gt;, not a monolithic bundle you fight in tree-shaking purgatory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effects that belong in product UI&lt;/strong&gt; — fade, cube, coverflow, Story Mode, and more, when marketing and product actually ask for them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility as a first-class module&lt;/strong&gt;, not a footnote.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rail is our answer: &lt;strong&gt;opinionated where it matters, composable everywhere else&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part of ForgeStack — and built to sit next to Bear
&lt;/h2&gt;

&lt;p&gt;Rail is &lt;strong&gt;not an island&lt;/strong&gt;. It is the &lt;strong&gt;motion layer&lt;/strong&gt; in the same story as &lt;strong&gt;Bear&lt;/strong&gt; — our React component library for interfaces that need to look and behave like serious software.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bear&lt;/strong&gt; gives you structure: buttons, cards, typography, layout, inputs, overlays — the vocabulary of the UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rail&lt;/strong&gt; gives that UI &lt;strong&gt;motion and narrative&lt;/strong&gt;: the carousel in the hero, the gallery beside the form, the story strip above the fold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use the same design discipline: &lt;strong&gt;TypeScript-first&lt;/strong&gt;, &lt;strong&gt;explicit APIs&lt;/strong&gt;, and a path from “demo pretty” to “production boring” (in the best sense — boring because it &lt;em&gt;works&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;If you already reach for Bear when you start a ForgeStack-flavored app, Rail is the natural companion when the design says &lt;em&gt;swipe&lt;/em&gt;, &lt;em&gt;slide&lt;/em&gt;, or &lt;em&gt;tell a sequence&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bear:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;github.com/yaghobieh/bear&lt;/a&gt; · &lt;a href="https://bearui.com" rel="noopener noreferrer"&gt;bearui.com&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ForgeStack hub:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/ForgeStack" rel="noopener noreferrer"&gt;github.com/yaghobieh/ForgeStack&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The portal, the API surface, and Rail Studio
&lt;/h2&gt;

&lt;p&gt;We didn’t stop at the package. The &lt;strong&gt;Rail Portal&lt;/strong&gt; is the public home for narrative, examples, and deep reference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Site:&lt;/strong&gt; &lt;a href="https://railjs.com" rel="noopener noreferrer"&gt;railjs.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portal source (fork, deploy, theme):&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/rail-portal" rel="noopener noreferrer"&gt;github.com/yaghobieh/rail-portal&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside the portal, &lt;strong&gt;Rail Studio&lt;/strong&gt; is where pride meets play: tweak presets, spacing, effects, and navigation, then &lt;strong&gt;copy production-ready JSX&lt;/strong&gt;. No ceremony — just a tight loop between imagination and code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open Studio directly:&lt;/strong&gt; &lt;a href="https://railjs.com/studio" rel="noopener noreferrer"&gt;railjs.com/studio&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A taste of the API
&lt;/h2&gt;

&lt;p&gt;Install:&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; @forgedevstack/rail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Minimal usage (modules are explicit — you only pay for what you import):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Rail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Navigation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Pagination&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;@forgedevstack/rail&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@forgedevstack/rail/styles.css&lt;/span&gt;&lt;span class="dl"&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;HeroCarousel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Rail&lt;/span&gt;
      &lt;span class="na"&gt;slidesPerView&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;spaceBetween&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;navigation&lt;/span&gt;
      &lt;span class="na"&gt;pagination&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;clickable&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="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;modules&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="nx"&gt;Navigation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Pagination&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Slide 1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Slide 2&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Slide 3&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RailSlide&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Rail&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;The real story is in the &lt;strong&gt;module matrix&lt;/strong&gt; — virtual slides for huge lists, thumbs for galleries, autoplay with sane pause rules, and effects when the brand demands drama. That’s all documented on &lt;a href="https://railjs.com" rel="noopener noreferrer"&gt;railjs.com&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we’re asking of you
&lt;/h2&gt;

&lt;p&gt;If Rail solves even &lt;strong&gt;one&lt;/strong&gt; carousel you were dreading, we’ve earned the star. If it doesn’t yet, &lt;strong&gt;open an issue&lt;/strong&gt; — we ship in the open because the next great default behavior probably has your name on the report.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Star the repo:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/rail" rel="noopener noreferrer"&gt;github.com/yaghobieh/rail&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Try the Studio:&lt;/strong&gt; &lt;a href="https://railjs.com/studio" rel="noopener noreferrer"&gt;railjs.com/studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Read the docs:&lt;/strong&gt; &lt;a href="https://railjs.com" rel="noopener noreferrer"&gt;railjs.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Link sheet (copy for anywhere)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Rail (library)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/yaghobieh/rail" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/rail&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rail Portal (docs + demos)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://railjs.com" rel="noopener noreferrer"&gt;https://railjs.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rail Studio&lt;/td&gt;
&lt;td&gt;&lt;a href="https://railjs.com/studio" rel="noopener noreferrer"&gt;https://railjs.com/studio&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm package&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@forgedevstack/rail" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@forgedevstack/rail&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rail Portal (source)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/yaghobieh/rail-portal" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/rail-portal&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bear (UI kit)&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/yaghobieh/bear" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/bear&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bear site&lt;/td&gt;
&lt;td&gt;&lt;a href="https://bearui.com" rel="noopener noreferrer"&gt;https://bearui.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ForgeStack&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/yaghobieh/ForgeStack" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/ForgeStack&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  dev.to publishing checklist
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Title: use the H1 above or shorten for feed (e.g. &lt;em&gt;“Rail: an open-source carousel engine for React — ForgeStack + Bear”&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cover image:&lt;/strong&gt; upload a wide hero in the dev.to editor (recommended over a small SVG for social cards).&lt;/li&gt;
&lt;li&gt;Tags: &lt;code&gt;react&lt;/code&gt;, &lt;code&gt;typescript&lt;/code&gt;, &lt;code&gt;opensource&lt;/code&gt;, &lt;code&gt;carousel&lt;/code&gt;, &lt;code&gt;ui&lt;/code&gt;, &lt;code&gt;webdev&lt;/code&gt;, &lt;code&gt;forgestack&lt;/code&gt; (add &lt;code&gt;bear&lt;/code&gt; if allowed).&lt;/li&gt;
&lt;li&gt;Canonical: point to dev.to or cross-post from your blog with &lt;code&gt;canonical_url&lt;/code&gt; in front matter if you use it.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  LinkedIn companion (paste below the fold or as a short article)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Hook (first line — make them click “see more”):&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
We just open-sourced &lt;strong&gt;Rail&lt;/strong&gt; — the React carousel engine we built so we’d never again ship a “temporary” slider that became permanent technical debt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Body (short):&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Rail is modular (25+ opt-in modules), touch-ready, accessibility-aware, and packed with effects from fade to Story Mode. It sits next to &lt;strong&gt;Bear&lt;/strong&gt; in the &lt;strong&gt;ForgeStack&lt;/strong&gt; ecosystem: Bear is your UI vocabulary; Rail is motion and narrative. Docs and live demos live at &lt;strong&gt;railjs.com&lt;/strong&gt;, and &lt;strong&gt;railjs.com/studio&lt;/strong&gt; lets you configure a carousel and copy JSX in seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Library → &lt;a href="https://github.com/yaghobieh/rail" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/rail&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Docs → &lt;a href="https://railjs.com" rel="noopener noreferrer"&gt;https://railjs.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Studio → &lt;a href="https://railjs.com/studio" rel="noopener noreferrer"&gt;https://railjs.com/studio&lt;/a&gt;&lt;br&gt;&lt;br&gt;
npm → &lt;a href="https://www.npmjs.com/package/@forgedevstack/rail" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@forgedevstack/rail&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Bear → &lt;a href="https://bearui.com" rel="noopener noreferrer"&gt;https://bearui.com&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hashtags (optional, end of post):&lt;/strong&gt;  &lt;/p&gt;

&lt;h1&gt;
  
  
  OpenSource #React #TypeScript #WebDev #UI #ForgeStack #JavaScript #FrontEnd
&lt;/h1&gt;




&lt;p&gt;&lt;em&gt;Rail is MIT licensed. Built with conviction, documented with care, released with pride.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>ui</category>
    </item>
    <item>
      <title>Grid Table v1.0.8: Mobile Layout Control + Server Pagination</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Tue, 07 Apr 2026 06:37:02 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/grid-table-v108-mobile-layout-control-server-pagination-32o2</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/grid-table-v108-mobile-layout-control-server-pagination-32o2</guid>
      <description>&lt;p&gt;&lt;code&gt;@forgedevstack/grid-table&lt;/code&gt; just shipped &lt;code&gt;v1.0.8&lt;/code&gt;, and this release is all about production workflows.&lt;/p&gt;

&lt;p&gt;Instead of adding random surface area, we focused on what usually breaks first in real products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mobile table behavior&lt;/li&gt;
&lt;li&gt;server-driven data paging&lt;/li&gt;
&lt;li&gt;UX polish for high-density grids&lt;/li&gt;
&lt;li&gt;docs/demos that are actually implementation-ready&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Highlights
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1) New &lt;code&gt;mobileLayout&lt;/code&gt; prop
&lt;/h2&gt;

&lt;p&gt;You can now choose mobile behavior explicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"scroll"&lt;/code&gt; (default): keep full table semantics with horizontal scroll&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"stacked"&lt;/code&gt;: card-like row layout for narrow viewports
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GridTable&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;columns&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;mobileBreakpoint&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tablet"&lt;/span&gt;
  &lt;span class="na"&gt;mobileLayout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"stacked"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives product teams control instead of forcing one “mobile table” opinion.&lt;/p&gt;

&lt;h2&gt;
  
  
  2) Manual pagination for API slices
&lt;/h2&gt;

&lt;p&gt;Server paging is now first-class:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;paginationConfig.manualPagination&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;paginationConfig.totalRowCount&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GridTable&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;rowsFromApi&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;columns&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paginationConfig&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;manualPagination&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="na"&gt;totalRowCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;totalFromApi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;initialPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;initialPageSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;onPageChange&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="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageSize&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;refetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You keep client UX, while pagination math reflects backend totals correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) UX + stability improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;hover effect toned down for cleaner scanability&lt;/li&gt;
&lt;li&gt;toolbar icon size tuned for touch layouts&lt;/li&gt;
&lt;li&gt;computed totals aligned with manual paging&lt;/li&gt;
&lt;li&gt;hook-order loading fix in &lt;code&gt;GridTableContent&lt;/code&gt; (no more render mismatch edge case)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4) Portal got much better
&lt;/h2&gt;

&lt;p&gt;The portal now includes practical demos for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;accessibility&lt;/li&gt;
&lt;li&gt;master-detail rows&lt;/li&gt;
&lt;li&gt;persisted pagination&lt;/li&gt;
&lt;li&gt;server-driven pagination&lt;/li&gt;
&lt;li&gt;column grouping band&lt;/li&gt;
&lt;li&gt;lazy/large lists&lt;/li&gt;
&lt;li&gt;theme + playground hub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus copy-ready demo snippets, so adoption is much faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Most grid demos look fine with static arrays and desktop-only assumptions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;v1.0.8&lt;/code&gt; is about teams shipping real apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complex states&lt;/li&gt;
&lt;li&gt;backend pagination&lt;/li&gt;
&lt;li&gt;mobile decisions&lt;/li&gt;
&lt;li&gt;high-interaction UX&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ecosystem fit
&lt;/h2&gt;

&lt;p&gt;Grid Table is part of Forge Dev Stack and pairs naturally with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bear UI&lt;/li&gt;
&lt;li&gt;Forge Compass&lt;/li&gt;
&lt;li&gt;Synapse&lt;/li&gt;
&lt;li&gt;Harbor&lt;/li&gt;
&lt;li&gt;Forge CLI&lt;/li&gt;
&lt;/ul&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @forgedevstack/grid-table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Wedsite: &lt;a href="https://grid-table.com" rel="noopener noreferrer"&gt;https://grid-table.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/yaghobieh/grid-table" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/grid-table&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Changelog: &lt;a href="https://github.com/yaghobieh/grid-table/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;https://github.com/yaghobieh/grid-table/blob/main/CHANGELOG.md&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want, I can share a follow-up post with concrete patterns for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API paging + optimistic edits&lt;/li&gt;
&lt;li&gt;stacked mobile cards for operations apps&lt;/li&gt;
&lt;li&gt;tree data + master-detail hybrid views&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>serverless</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Bear UI v1.1.5: PropsPlayground, PageNav, Button Refactor, and a Polished Portal</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Sun, 15 Mar 2026 20:06:53 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-v115-propsplayground-pagenav-button-refactor-and-a-polished-portal-1822</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-v115-propsplayground-pagenav-button-refactor-and-a-polished-portal-1822</guid>
      <description>&lt;p&gt;&lt;strong&gt;@forgedevstack/bear&lt;/strong&gt; is a Tailwind-powered React UI library — TypeScript-first, zero config, dark/light theming out of the box. Version &lt;strong&gt;1.1.5&lt;/strong&gt; brings two new components, a new hook, bear-themed icons, a major Button refactor, controlled Tabs, and a set of portal improvements that make browsing the docs faster.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Explore all components at &lt;a href="https://bearui.com/" rel="noopener noreferrer"&gt;Bear UI Portal&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What's in 1.1.5?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New components
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PropsPlayground&lt;/strong&gt; — An interactive prop editor panel you can embed in any documentation page. Define a &lt;code&gt;config&lt;/code&gt; object with boolean, select, number, or string controls, pass a &lt;code&gt;render&lt;/code&gt; function, and you get a collapsible control panel above a live preview. Supports a reset button, configurable column count, and three sizes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PropsPlayground&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&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;@forgedevstack/bear&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PropsPlayground&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Outline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;outline&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="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ghost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ghost&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="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Click me&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="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;render&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="nx"&gt;props&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;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PageNav&lt;/strong&gt; — Previous/next navigation links for documentation or multi-page flows. Three variants (default, outlined, filled), five sizes, and optional icons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PageNav&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;@forgedevstack/bear&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PageNav&lt;/span&gt;
  &lt;span class="na"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/components/button&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="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tabs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/components/tabs&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="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"outlined"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  New hook: useResizeObserver
&lt;/h3&gt;

&lt;p&gt;A lightweight wrapper around the browser's &lt;code&gt;ResizeObserver&lt;/code&gt;. Pass a ref, get &lt;code&gt;width&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and the full &lt;code&gt;contentRect&lt;/code&gt; back. Useful for responsive component logic without media queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&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;useResizeObserver&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;@forgedevstack/bear&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;ResponsiveBox&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;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useResizeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; x &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Bear-themed icons
&lt;/h3&gt;

&lt;p&gt;Eight new SVG icons with a nature/bear theme: &lt;strong&gt;HoneycombIcon&lt;/strong&gt;, &lt;strong&gt;ClawIcon&lt;/strong&gt;, &lt;strong&gt;ForestIcon&lt;/strong&gt;, &lt;strong&gt;DenIcon&lt;/strong&gt;, &lt;strong&gt;SalmonIcon&lt;/strong&gt;, &lt;strong&gt;CampfireIcon&lt;/strong&gt;, &lt;strong&gt;PineTreeIcon&lt;/strong&gt;, &lt;strong&gt;MountainIcon&lt;/strong&gt;. Use them like any other Bear icon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BearIcons&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;@forgedevstack/bear&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearIcons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ForestIcon&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearIcons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CampfireIcon&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Button refactor
&lt;/h3&gt;

&lt;p&gt;The Button component got a significant cleanup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Spotlight logic extracted&lt;/strong&gt; into a reusable &lt;code&gt;useSpotlight&lt;/code&gt; hook — the same mouse-follow glow effect is now available for other components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;iconOnly&lt;/code&gt; prop&lt;/strong&gt; — Renders a square button sized for icons, without needing to manually adjust padding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller file&lt;/strong&gt; — Helper functions and variant checks moved to &lt;code&gt;Button.utils.ts&lt;/code&gt; and &lt;code&gt;Button.constants.ts&lt;/code&gt;. The main component file dropped by ~40 lines with no API changes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;iconOnly&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ghost"&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"sm"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearIcons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SearchIcon&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Tabs: controlled mode
&lt;/h3&gt;

&lt;p&gt;Tabs now accept an optional &lt;code&gt;value&lt;/code&gt; prop for controlled mode. When &lt;code&gt;value&lt;/code&gt; is provided, the component is fully controlled from outside; when omitted, it falls back to the existing &lt;code&gt;defaultTab&lt;/code&gt; uncontrolled behavior.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;activeTab&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setActiveTab&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;overview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tabs&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;activeTab&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;defaultTab&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"overview"&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setActiveTab&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TabList&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"overview"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Overview&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"api"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;API&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TabList&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* panels */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Tabs&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Portal improvements
&lt;/h3&gt;

&lt;p&gt;The documentation portal got four additions that improve day-to-day use:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sidebar Search&lt;/strong&gt; — Live filter in the sidebar. Type to instantly find any component, hook, or guide. Auto-expands matching groups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy Import&lt;/strong&gt; — A one-click button on every component page that copies &lt;code&gt;import { ComponentName } from '@forgedevstack/bear'&lt;/code&gt; to your clipboard.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Breadcrumbs&lt;/strong&gt; — Navigation breadcrumbs on component and doc pages so you always know where you are.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Doc Page Navigation&lt;/strong&gt; — Previous/next links at the bottom of every page (using the new PageNav component internally).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility Docs&lt;/strong&gt; — A new guide covering focus management, ARIA attributes, keyboard navigation, and color contrast.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  CSS and code quality
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain CSS for base utilities&lt;/strong&gt; — &lt;code&gt;.bear-focus-ring&lt;/code&gt; and &lt;code&gt;.bear-transition&lt;/code&gt; now use plain CSS instead of Tailwind &lt;code&gt;@apply&lt;/code&gt; directives, improving compatibility with non-Tailwind setups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Utility extraction&lt;/strong&gt; — Anchor, Autocomplete, ContextMenu, CountdownTimer, Dock, FileTree, MentionsInput, Skeleton, SliderRange, and Spotlight all had logic moved into &lt;code&gt;.utils.ts&lt;/code&gt; files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;New docs&lt;/strong&gt; — A &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; guide covers branch workflow, how to add components, and coding rules. The README now includes a comparison table vs MUI, Ant Design, and Chakra UI.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick start
&lt;/h2&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; @forgedevstack/bear
&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="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@forgedevstack/bear/styles.css&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;BearProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PropsPlayground&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PageNav&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;@forgedevstack/bear&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;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearProvider&lt;/span&gt; &lt;span class="na"&gt;defaultMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"light"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"primary"&lt;/span&gt; &lt;span class="na"&gt;spotlight&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Try Bear
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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="nc"&gt;BearProvider&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;h2&gt;
  
  
  Where to go from here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Portal:&lt;/strong&gt; &lt;a href="https://bearui.com/" rel="noopener noreferrer"&gt;bearui.com&lt;/a&gt; — all components, live examples, and API docs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/@forgedevstack/bear" rel="noopener noreferrer"&gt;@forgedevstack/bear&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Changelog:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/bear/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;GitHub CHANGELOG.md&lt;/a&gt; for the full diff.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bear UI v1.1.5 focuses on developer experience — a playground for testing props, better portal navigation, a cleaner Button, and controlled Tabs. The library now exports 100+ components with the same Tailwind-powered, zero-config approach.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part of &lt;a href="https://forgedevstack.com/" rel="noopener noreferrer"&gt;ForgeStack&lt;/a&gt; — React, Compass, Synapse, Harbor, Grid Table, Lingo, and more.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>tailwindcss</category>
      <category>javascript</category>
      <category>npm</category>
    </item>
    <item>
      <title>Bear UI v1.1.4: 22+ New Components, LOC Badges, and a Better Docs Experience</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Wed, 11 Mar 2026 21:19:50 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-v114-22-new-components-loc-badges-and-a-better-docs-experience-2545</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-v114-22-new-components-loc-badges-and-a-better-docs-experience-2545</guid>
      <description>&lt;p&gt;&lt;strong&gt;@forgedevstack/bear&lt;/strong&gt; is a React UI library built with Tailwind CSS — zero config, TypeScript-first, and part of the ForgeStack ecosystem. Version &lt;strong&gt;1.1.4&lt;/strong&gt; adds over 22 new components, improves docs with lines-of-code badges, and keeps dark/light theming and customization front and center.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Explore all components at &lt;a href="https://bearui.com/" rel="noopener noreferrer"&gt;Bear UI Portal&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s in 1.1.4?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New components (high level)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Feedback &amp;amp; overlays:&lt;/strong&gt; Popconfirm, Result (success/error/404/403/500), LoadingOverlay
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data &amp;amp; layout:&lt;/strong&gt; Descriptions (key-value), Anchor (scroll-spy TOC), Affix (sticky), RingProgress, Spoiler
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Form &amp;amp; selection:&lt;/strong&gt; CheckboxCard, RadioCard, Fieldset
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI primitives:&lt;/strong&gt; Blockquote, Indicator (badge/dot), ActionIcon (icon-only button)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Already in 1.1.3:&lt;/strong&gt; DateRangePicker, TreeSelect, ImageGallery/Lightbox, ContextMenu, NumberFormatter, InfiniteScroll, ColorSwatch, SplitButton
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these support &lt;strong&gt;BearProvider&lt;/strong&gt; (dark/light, custom colors/variants) and use &lt;strong&gt;Typography&lt;/strong&gt; for text so you can control appearance via props.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docs: lines-of-code badges
&lt;/h3&gt;

&lt;p&gt;Component docs now show a small &lt;strong&gt;lines-of-code (LOC) badge&lt;/strong&gt; next to each component name — same idea as the HoverCard screenshot below. Green = smaller footprint; the badge helps you see at a glance how much code each piece adds.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Component pages use the same LOC badge pattern across the portal.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick start
&lt;/h2&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; @forgedevstack/bear
&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;// App or main entry&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@forgedevstack/bear/styles.css&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;Button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CardHeader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CardBody&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Popconfirm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Result&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;@forgedevstack/bear&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;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Card&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CardHeader&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CardHeader&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CardBody&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Popconfirm&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Delete this?"&lt;/span&gt; &lt;span class="na"&gt;onConfirm&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Deleted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"outline"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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="nc"&gt;Popconfirm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;CardBody&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Card&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;h2&gt;
  
  
  New components in action
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Popconfirm — inline confirmation
&lt;/h3&gt;

&lt;p&gt;Use instead of a heavy modal for simple “Are you sure?” flows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Popconfirm&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Delete this item?"&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"This cannot be undone."&lt;/span&gt;
  &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"danger"&lt;/span&gt;
  &lt;span class="na"&gt;onConfirm&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleDelete&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"outline"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Remove&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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="nc"&gt;Popconfirm&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result — full-page feedback
&lt;/h3&gt;

&lt;p&gt;Ideal for success, error, 404, 403, or 500 pages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Result&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"404"&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Page Not Found"&lt;/span&gt;
  &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"The page you're looking for doesn't exist."&lt;/span&gt;
  &lt;span class="na"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;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;goHome&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Go Home&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Anchor — scroll-spy navigation
&lt;/h3&gt;

&lt;p&gt;Table-of-contents style nav that highlights the active section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Anchor&lt;/span&gt;
  &lt;span class="na"&gt;links&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;overview&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Overview&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;props&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Props&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Events&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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CheckboxCard &amp;amp; RadioCard
&lt;/h3&gt;

&lt;p&gt;Cards that act as checkboxes or radios — great for plans, options, or multi/single selection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RadioCardGroup&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setPlan&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RadioCard&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"free"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Free"&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"$0/mo"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RadioCard&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"pro"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Pro"&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"$19/mo"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RadioCard&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"enterprise"&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Enterprise"&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Custom"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;RadioCardGroup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  RingProgress, Spoiler, Blockquote, and more
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RingProgress&lt;/strong&gt; — SVG ring with one or more segments and optional center label.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spoiler&lt;/strong&gt; — “Show more / Show less” with a configurable max height.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blockquote&lt;/strong&gt; — Styled quote with left border and color variants.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ActionIcon&lt;/strong&gt; — Icon-only button with variants and loading state.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fieldset&lt;/strong&gt; — Semantic grouping with legend and description.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indicator&lt;/strong&gt; — Small dot/badge on any element (e.g. status, count).
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Theming (dark/light + custom)
&lt;/h2&gt;

&lt;p&gt;Wrap your app in &lt;strong&gt;BearProvider&lt;/strong&gt; to get dark/light mode and optional custom colors/variants:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BearProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Button&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;@forgedevstack/bear&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearProvider&lt;/span&gt;
  &lt;span class="na"&gt;defaultMode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt;
  &lt;span class="na"&gt;customVariants&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6366f1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#fff&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hoverBg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#4f46e5&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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Button&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"brand"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Custom variant&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&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="nc"&gt;BearProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Modular CSS with @BearInclude
&lt;/h2&gt;

&lt;p&gt;If you don’t want the full bundle, use the PostCSS plugin and import only what you need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@BearIncludeAll&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* or */&lt;/span&gt;
&lt;span class="k"&gt;@BearInclude&lt;/span&gt; &lt;span class="s2"&gt;'base'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@BearInclude&lt;/span&gt; &lt;span class="s2"&gt;'buttons'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;@BearInclude&lt;/span&gt; &lt;span class="s2"&gt;'alerts'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the &lt;a href="https://bearui.com/installation" rel="noopener noreferrer"&gt;portal Installation page&lt;/a&gt; for setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where to go from here
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Portal:&lt;/strong&gt; &lt;a href="https://bearui.com/" rel="noopener noreferrer"&gt;bearui.com&lt;/a&gt; — all components, live examples, and API.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/@forgedevstack/bear" rel="noopener noreferrer"&gt;@forgedevstack/bear&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Changelog:&lt;/strong&gt; &lt;a href="https://github.com/yaghobieh/bear/blob/main/CHANGELOG.md" rel="noopener noreferrer"&gt;GitHub CHANGELOG.md&lt;/a&gt; for the full 1.1.4 list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bear UI v1.1.4 keeps the same “strong, reliable, Tailwind-powered” approach while adding a lot of new building blocks and a clearer docs experience with LOC badges. If you’re building a React app and want a single design system with dark mode and room to customize, Bear is worth a look.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Part of &lt;a href="https://forgedevstack.com/" rel="noopener noreferrer"&gt;ForgeStack&lt;/a&gt; — React, Compass, Synapse, Grid Table, and more.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>tailwindcss</category>
      <category>ui</category>
    </item>
    <item>
      <title>Modernizing Web Applications with React 19+ Internals</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Mon, 09 Mar 2026 12:34:05 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/modernizing-web-applications-with-react-19-internals-a29</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/modernizing-web-applications-with-react-19-internals-a29</guid>
      <description>&lt;h4&gt;
  
  
  1. &lt;strong&gt;Concurrent Rendering &amp;amp; &lt;code&gt;@use&lt;/code&gt; (Data Fetching &amp;amp; Suspension)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;We are replacing all imperative &lt;code&gt;useEffect&lt;/code&gt; based fetching and manually managed loading states with declarative &lt;code&gt;@use(Promise)&lt;/code&gt;. This moves the complexity of data orchestration from user code directly into the Fiber Reconciler.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How &lt;code&gt;@use&lt;/code&gt; works under the hood (The Suspense Mechanism):&lt;/strong&gt;
When the Fiber Reconciler processes a component that reads a Promise via &lt;code&gt;@use&lt;/code&gt; (e.g., &lt;code&gt;&amp;lt;UserProfile /&amp;gt;&lt;/code&gt;), it checks if the Promise is already resolved. If &lt;strong&gt;not&lt;/strong&gt;, the Fiber Node representing &lt;code&gt;&amp;lt;UserProfile /&amp;gt;&lt;/code&gt; is marked as &lt;code&gt;Suspended&lt;/code&gt; and the Reconciler "throws" the Promise up the tree to be caught by the nearest &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; boundary. A &lt;code&gt;Fallback Fiber Node&lt;/code&gt; is then committed to the visual DOM to show a loading skeleton. When the promise is resolved, the Reconciler is notified and it automatically schedules an &lt;code&gt;Update Fiber Update&lt;/code&gt; to re-render the &lt;code&gt;&amp;lt;UserProfile /&amp;gt;&lt;/code&gt; with the resolved data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Expanded Real Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Suspense&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="c1"&gt;// Unified Harbor API wrapper returning a stable Promise&lt;/span&gt;
&lt;span class="c1"&gt;// @use is integrated into our data fetching layer&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;fetchUserProfile&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;./api&lt;/span&gt;&lt;span class="dl"&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;UserProfile&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;id&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Declarative, suspended resource reading&lt;/span&gt;
  &lt;span class="c1"&gt;// Throws if pending, catching nearby Suspense boundary&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fetchUserProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user-profile"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Welcome, &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Email: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&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="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* (Other profile components can also use "@use" concurrently) */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Parent implementation (standard Forge Stack pattern)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"app-container"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearHeader&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* 2. Catch suspended children with non-blocking fallback */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearUserProfileSkeleton&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; 
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserProfile&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"user_123"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&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;h4&gt;
  
  
  2. &lt;strong&gt;Actions &amp;amp; &lt;code&gt;useActionState&lt;/code&gt; (Native Form Interception &amp;amp; Lifecycle)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;We are moving away from manual &lt;code&gt;isSubmitting&lt;/code&gt; tracking and validation error propagation. By integrating with React 19's &lt;code&gt;useActionState&lt;/code&gt;, we let React's Fiber Reconciler handle the entire form submission lifecycle natively.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How &lt;code&gt;useActionState&lt;/code&gt; works under the hood (Interception and Lifecycle):&lt;/strong&gt;
When we use a &lt;code&gt;&amp;lt;form action={dispatch}&amp;gt;&lt;/code&gt; connected to &lt;code&gt;useActionState&lt;/code&gt;, React &lt;em&gt;intercepts&lt;/em&gt; the native form submission event (preventing the default full-page reload). It then extracts the &lt;code&gt;FormData&lt;/code&gt; from the event target and &lt;em&gt;dispatches&lt;/em&gt; an internal &lt;code&gt;Action Fiber Update&lt;/code&gt;. This update is marked with specific priorities in the Fiber Lanes.
React then initiates the &lt;strong&gt;Action Lifecycle&lt;/strong&gt;, providing three key states &lt;em&gt;natively&lt;/em&gt;:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pending&lt;/strong&gt;: The initial, synchronous response, setting &lt;code&gt;isPending&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; while the server action promise is running. The Reconciler knows this update is linked to the form element and updates only the relevant Fiber Node.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Success&lt;/strong&gt;: When the server promise resolves, the Reconciler commits the &lt;code&gt;Action State Update&lt;/code&gt; with the successful result (or a clean form state).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error&lt;/strong&gt;: If the promise fails, the Reconciler captures the failure and commits the &lt;code&gt;Action State Update&lt;/code&gt; with the error details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Expanded Real Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useActionState&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="c1"&gt;// Synchronous and asynchronous server action wrapper (Harbor backend integration)&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;signUpServerAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ActionState&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;./actions&lt;/span&gt;&lt;span class="dl"&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;BearSignUpForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// useActionState returns [currentState, dispatch, isPending]&lt;/span&gt;
  &lt;span class="c1"&gt;// prevState is automatically propagated for form resets or corrections&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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dispatchAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPending&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useActionState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ActionState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;FormData&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;signUpServerAction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;success&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="c1"&gt;// Initial state&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;form&lt;/span&gt; 
      &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"bear-form"&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;dispatchAction&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Connect directly to native action&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form-group"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearInput&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearInput&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Password"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt; &lt;span class="na"&gt;required&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="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* useActionState handles error and success propagation natively */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&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;error&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form-error"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&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="si"&gt;}&lt;/span&gt;
      &lt;span class="si"&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;success&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form-success"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Successfully registered!&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="si"&gt;}&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* 3. Automatic "isPending" state tracking (no manual useState required) */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearButton&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;disabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isPending&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isPending&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Forging Account...&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;Sign Up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BearButton&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;form&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;h4&gt;
  
  
  3. &lt;strong&gt;Optimistic Updates &amp;amp; &lt;code&gt;useOptimistic&lt;/code&gt; (Zero-Lag UI &amp;amp; Rollback Mechanics)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;We are implementing &lt;code&gt;useOptimistic&lt;/code&gt; to provide zero-lag user feedback for critical interactions like chat, liking posts, or adding to carts, without waiting for the server roundtrip.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How &lt;code&gt;useOptimistic&lt;/code&gt; works under the hood (Predicted vs. Real Commitments):&lt;/strong&gt;
When &lt;code&gt;useOptimistic&lt;/code&gt; is called (e.g., &lt;code&gt;addOptimisticMessage('hello')&lt;/code&gt;), React instantly creates a &lt;strong&gt;Predicted Fiber Update&lt;/strong&gt; on a highly prioritized, concurrent Fiber Lane. This update is committed &lt;em&gt;immediately&lt;/em&gt;, updating only the relevant UI part to show the "temporary" message.
In parallel, the &lt;em&gt;real&lt;/em&gt; asynchronous server action (Harbor API call) is dispatched as a separate concurrent Fiber Update on a &lt;em&gt;later&lt;/em&gt; lane. This is effectively a Race Condition where React manages the prediction vs. the reality.
&lt;strong&gt;The Magic of automatic Rollback:&lt;/strong&gt;
If the server action fails, the Reconciler simply &lt;strong&gt;discards&lt;/strong&gt; the &lt;code&gt;Predicted Lane Commitment&lt;/code&gt;. Since the Predicted Update was never the &lt;em&gt;real&lt;/em&gt;, final committed state (pre-optimistic), discarding it automatically reverts the Fiber Tree to its last known real committed state (pre-optimistic), removing the optimistic message from the user's view with zero lag or manual state reset logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Expanded Real Code Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useOptimistic&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="c1"&gt;// Native Harbor async message action (Server Action)&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;sendMessageAction&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;./actions&lt;/span&gt;&lt;span class="dl"&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;BearChatInput&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;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="c1"&gt;// Defines temporary optimistic state to be shown before server confirmation&lt;/span&gt;
  &lt;span class="c1"&gt;// useOptimistic(state, updateFn)&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;optimisticMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addOptimisticMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useOptimistic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;messages&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="nx"&gt;newMessageText&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="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;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="c1"&gt;// Predicting success and showing bubble instantly&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;newMessageText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;pending&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;temp-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FormData&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;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. URGENT: Show optimistic message instantly (Zero-Lag UI)&lt;/span&gt;
    &lt;span class="nf"&gt;addOptimisticMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

    &lt;span class="c1"&gt;// 5. Async Server call (Harbor backend integration)&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// (This promise is slow)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;confirmedMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sendMessageAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

      &lt;span class="c1"&gt;// 6a. Update 'real' state on success. Optimistic value removed.&lt;/span&gt;
      &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;confirmedMessage&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; 
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// 6b. Automatic rollback on failure. Optimistic value discarded.&lt;/span&gt;
      &lt;span class="c1"&gt;// (We can show a toast here to inform the user)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"chat-container"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* BearList renders 'optimisticMessages' concurrently */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearMessageList&lt;/span&gt; &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;optimisticMessages&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;form&lt;/span&gt; 
        &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"chat-input"&lt;/span&gt;
        &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Standard async action handler&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;input&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt; &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Type a message..."&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;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Send&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;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;






&lt;h3&gt;
  
  
  Ecosystem Validation Visuals
&lt;/h3&gt;

&lt;p&gt;This detailed visual presentation summarizes the comprehensive integration across all Forge Stack foundational components. The light-mode infographic clearly labels the interconnected pathways where &lt;strong&gt;startTransition (Urgent vs. Non-Urgent Lanes)&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;@use&lt;/code&gt; Suspension and Rehydration&lt;/strong&gt;, &lt;strong&gt;useActionState Lifecycle&lt;/strong&gt;, and &lt;strong&gt;useOptimistic predicted vs. committed state&lt;/strong&gt; synchronize data flow.&lt;/p&gt;

&lt;p&gt;We have included additional detailed diagrams within each section to show how the &lt;strong&gt;React Scheduler and Fiber Reconciler&lt;/strong&gt; operate under the hood to manage these complex scenarios, ensuring per-default non-blocking perceived performance.&lt;/p&gt;

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

</description>
      <category>react</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>web3</category>
    </item>
    <item>
      <title>State Management is Dead. Long Live the Neural Layer: Introducing Synapse 1.1.0</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Sun, 08 Mar 2026 11:18:14 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/state-management-is-dead-long-live-the-neural-layer-introducing-synapse-110-3fc4</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/state-management-is-dead-long-live-the-neural-layer-introducing-synapse-110-3fc4</guid>
      <description>&lt;p&gt;State Management is Dead. Long Live the Neural Layer: Introducing Synapse 1.1.0&lt;/p&gt;

&lt;p&gt;The "State Management Wars" are over, and the developers won. Over the last decade, we've swung from the highly structured (but brutal boilerplate) world of Redux to the beautiful (but sometimes dangerously simple) world of Zustand. Now, we are entering a new era.&lt;/p&gt;

&lt;p&gt;State management is no longer just about where you put your data; it's about how your components &lt;strong&gt;perceive&lt;/strong&gt; that data, instantly and efficiently.&lt;/p&gt;

&lt;p&gt;Introducing &lt;strong&gt;@forgedevstack/synapse&lt;/strong&gt;, the definitive Neural State Layer—specifically designed to bridge the gap between structured scalability and lightning-fast developer experience.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why Synapse? Our Motivation
&lt;/h3&gt;

&lt;p&gt;The motivation behind Synapse wasn't to build &lt;em&gt;yet another&lt;/em&gt; state manager. It was to build a state &lt;em&gt;perception&lt;/em&gt; system that harmonizes performance with developer experience.&lt;/p&gt;

&lt;p&gt;We were fatigued by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Selector optimization trap&lt;/strong&gt;: Having to manually write selectors to prevent massive re-renders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "Loose" State Problem&lt;/strong&gt;: Simple state solutions often leave complex state logic scattered and unmanaged as the app scales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boilerplate Burnout&lt;/strong&gt;: Redux taught us great patterns, but the sheer cost of wiring a new feature is unsustainable.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Synapse vs. The Giants
&lt;/h3&gt;

&lt;p&gt;Synapse is built on a &lt;strong&gt;Structured Signal System&lt;/strong&gt;. We take the rigid, predictable architecture concepts of Redux and the lightweight, minimal-API philosophy of Zustand, then add the performance of &lt;strong&gt;Signals&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Redux&lt;/th&gt;
&lt;th&gt;Zustand&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Synapse&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Boilerplate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Zero&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Steep&lt;/td&gt;
&lt;td&gt;Shallow&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Instant&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reactivity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual (Selectors)&lt;/td&gt;
&lt;td&gt;Selectors&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Automatic (Signals)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Imposed (Single Tree)&lt;/td&gt;
&lt;td&gt;Loose (Multiple Stores)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Flexible (Nuclei)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Generic&lt;/td&gt;
&lt;td&gt;Generic&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ForgeStack Native&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The Synapse Edge:&lt;/strong&gt; We don't use selectors to prevent re-renders. Synapse uses &lt;strong&gt;Nuclei&lt;/strong&gt;. Components become "Observers" of a specific Nucleus. When that Nucleus changes, &lt;strong&gt;only that component&lt;/strong&gt; updates. It’s automatic, optimized, and invisible.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Visualizing the Complexity Gap&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Here is a side-by-side comparison. Left (Redux): A cluttered, industrial, steam-punk dashboard of buttons, levers, and tangled code. Right (Synapse): A clean, sleek, minimalist panel with a few glowing touch-interfaces. Minimal, elegant code examples are embedded in the screen interfaces.&lt;/p&gt;

&lt;p&gt;[invalid URL removed]&lt;/p&gt;




&lt;h3&gt;
  
  
  Technical Deep Dive: The Synapse Quick Start
&lt;/h3&gt;

&lt;p&gt;You don't need actions, reducers, or creators. You just need a Nucleus.&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;createNucleus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useNucleus&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;@forgedevstack/synapse&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 1. Create your Structured Nucleus (state)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counterNucleus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNucleus&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="c1"&gt;// 2. Observer Component&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="c1"&gt;//useNucleus turns this component into a direct observer of counterNucleus&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;setCounter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useNucleus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;counterNucleus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Directly mutation-free updates. &lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;increment&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;setCounter&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="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;prev&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="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;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increment&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="k"&gt;is&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&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;h3&gt;
  
  
  What’s New in Version 1.1.0?
&lt;/h3&gt;

&lt;p&gt;The latest release makes Synapse the smartest connection in the Forge ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Time-Travel Debugging 2.0 (Native DevTools)&lt;/strong&gt;&lt;br&gt;
Our professional-grade DevTools are now native and can be dropped into your app. This UI features a video-player-like "scrubber" that lets you move back and forth through your entire state history with zero overhead.&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;Slide 2: Time-Travel Debugging in Action&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A modern dark-mode interface dashboard of the Synapse Native DevTools. A prominent Time-Travel video scrubber is active at the bottom, with small state-snapshot icons along the timeline. The main view displays a hierarchical state tree.&lt;/p&gt;

&lt;p&gt;[invalid URL removed]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Atomic Persistence&lt;/strong&gt;&lt;br&gt;
You can now mark specific Nuclei to be stored and rehydrated automatically. Synapse handles the synchronization to &lt;code&gt;localStorage&lt;/code&gt; or &lt;code&gt;sessionStorage&lt;/code&gt; in the background.&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;// Persists automatically to localStorage under key 'theme_state'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;themeNucleus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNucleus&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localStorage&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;&lt;strong&gt;3. Computed Nuclei (Derived State)&lt;/strong&gt;&lt;br&gt;
Define state that depends on other Nuclei. Computed values update only when their source dependencies change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Forge-Compass Sync&lt;/strong&gt;&lt;br&gt;
Directly sync your Synapse state with your URL. Perfect for filtering, sorting, or pagination where the state must live in the URL but react like an in-memory Signal.&lt;/p&gt;


&lt;h3&gt;
  
  
  Redux to Synapse Migration Guide
&lt;/h3&gt;

&lt;p&gt;If you are fatigued by boilerplate, migrating to Synapse is straightforward. We use the same conceptual mental model—predictable state flow—but remove the manual wiring.&lt;/p&gt;
&lt;h4&gt;
  
  
  Step 1: Replace the Redux Store
&lt;/h4&gt;

&lt;p&gt;Instead of a single store, you create independent Nuclei based on your domains.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From Redux:&lt;/strong&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;// redux/store.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;configureStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userReducer&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;type&lt;/span&gt; &lt;span class="nx"&gt;RootState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&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;getState&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;type&lt;/span&gt; &lt;span class="nx"&gt;AppDispatch&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;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// redux/userSlice.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSlice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createSlice&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;reducers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;setProfile&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="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;To Synapse:&lt;/strong&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;// synapse/nuclei.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;createNucleus&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;@forgedevstack/synapse&lt;/span&gt;&lt;span class="dl"&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;userNucleus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createNucleus&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Updates are performed mutation-free in-place&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;setProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;userNucleus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Connect the UI
&lt;/h4&gt;

&lt;p&gt;Replace selectors and dispatch with &lt;code&gt;useNucleus&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From Redux:&lt;/strong&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserProfile&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;dispatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useDispatch&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// Selector prevents re-renders (manually optimized)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSelector&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RootState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetchProfile&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;setProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&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&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="k"&gt;return&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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&amp;gt;&lt;/span&gt;&lt;span class="err"&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;To Synapse:&lt;/strong&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Directly observing the userNucleus (automatically optimized)&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;profile&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useNucleus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userNucleus&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// We perform the set externally, no dispatch needed&lt;/span&gt;
  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;fetchProfile&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setProfile&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Loading&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&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;  &lt;span class="k"&gt;return&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;By removing the slice, actions, reducers, and dispatch wiring, we reduced the complexity of this feature by &lt;strong&gt;~70%&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Forge Ecosystem: Why It Matters
&lt;/h3&gt;

&lt;p&gt;Synapse isn't a generic library; it is the &lt;strong&gt;Connective Neural Tissue&lt;/strong&gt; of the &lt;strong&gt;Forge Stack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The Forge ecosystem is a "harmony" of specialized tools. &lt;strong&gt;Bear UI&lt;/strong&gt; defines the visual layer, &lt;strong&gt;Harbor&lt;/strong&gt; handles the database and API pipeline, and &lt;strong&gt;Synapse&lt;/strong&gt; is the state brain that connects them.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Visualizing the Synapse Neural Ecosystem&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;An architectural overview map. A glowing digital human brain (Synapse) acts as a central neural network hub. Glowing neon cyan and teal network lines connect outwards to distinct glowing icons representing: Bear UI, Grid Table, Harbor Server, and Lingo Portal. The entire ecosystem is alive, flowing with data.&lt;/p&gt;

&lt;p&gt;[invalid URL removed]&lt;/p&gt;

&lt;p&gt;When used with &lt;strong&gt;Forge Studio&lt;/strong&gt;, this integration goes to the next level. The &lt;strong&gt;Forge Agent&lt;/strong&gt; (our dedicated AI assistant) can take your database schema from Harbor and &lt;strong&gt;automatically forge your entire Synapse state layer&lt;/strong&gt;, including persistence and type-safety, in seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop managing state. Start Forging it.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Learn More &amp;amp; Get Started:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Documentation&lt;/strong&gt;: &lt;a href="https://www.google.com/search?q=https://forgedevstack.com/synapse" rel="noopener noreferrer"&gt;forgedevstack.com/synapse&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Social Media Posts (Adapting the Article)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Reddit Post (e.g., r/ReactJS, r/WebDev)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Title&lt;/strong&gt;: State Management Wars are Dead. Meet Synapse: The boilerplate-free Neural Layer with Native DevTools.&lt;/p&gt;

&lt;p&gt;Hey r/ReactJS,&lt;/p&gt;

&lt;p&gt;State management Fatigue is real. We’ve all felt it: the Redux boilerplate slowdown, or the Zustand scaling anxiety. I felt it too, which is why I built &lt;strong&gt;Synapse&lt;/strong&gt;, and it just hit v1.1.0.&lt;/p&gt;

&lt;p&gt;Synapse is a &lt;strong&gt;Structured Signal System&lt;/strong&gt;. It’s not just about where data lives; it’s about how your components &lt;em&gt;perceive&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Synapse Key Selling Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OBSERVER SYSTEM&lt;/strong&gt;: We don't use selectors. Components become automatically optimized 'observers' of a 'Nucleus'. When that specific Nucleus changes, &lt;strong&gt;only that component updates&lt;/strong&gt;. Period. Zero manual optimization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TIME-TRAVEL DEBUGGING 2.0&lt;/strong&gt;: The DevTools are &lt;em&gt;native&lt;/em&gt; and look like a video player. You can just drop the UI in and start scrubbing history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ATOMIC PERSISTENCE&lt;/strong&gt;: mark a Nucleus for persistence (localStorage/sessionStorage) in one line. Synapse handles rehydration and sync in the background.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ZERO BOILERPLATE&lt;/strong&gt;: No slices, no creators, no reducers. Create state in one line, use it in one line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What the Migration Looks Like:&lt;/strong&gt;&lt;br&gt;
(Redux: ~70 lines of boilerplate vs. Synapse: ~10 lines of clean code.)&lt;/p&gt;

&lt;p&gt;I built this specifically to integrate with our larger ForgeStack ecosystem, but Synapse is framework-agnostic (React adapter included). We are looking for performance, feedback, and optimization critiques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://www.google.com/search?q=https://github.com/forgedevstack/forge-synapse" rel="noopener noreferrer"&gt;https://github.com/forgedevstack/forge-synapse&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;NPM&lt;/strong&gt;: &lt;code&gt;npm install @forgedevstack/synapse&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Give it a try and tell me why I’m right (or wrong) about the end of the boilerplate era.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop managing state. Start Forging it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Get Started&lt;/strong&gt;: &lt;a href="https://www.google.com/search?q=https://forgedevstack.com/synapse" rel="noopener noreferrer"&gt;https://forgedevstack.com/synapse&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  WebPerformance #EnterpriseScale #ForgeStack #DevDX #SynapseState
&lt;/h1&gt;

</description>
      <category>redux</category>
      <category>react</category>
      <category>zustand</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Grid Table — 1.0.7</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Thu, 05 Mar 2026 19:51:29 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/grid-table-107-2ic6</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/grid-table-107-2ic6</guid>
      <description>&lt;p&gt;&lt;strong&gt;@forgedevstack/grid-table&lt;/strong&gt; is a powerful, feature-rich React data grid with 30+ features: cell editing, multi-format export, keyboard navigation, context menu, tree data, row reordering, frozen rows, undo/redo, and print mode. Zero-config SCSS styling. Part of &lt;a href="https://forgedevstack.com" rel="noopener noreferrer"&gt;ForgeStack&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live site:&lt;/strong&gt; &lt;a href="https://grid-table.com/" rel="noopener noreferrer"&gt;grid-table.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;code&gt;@forgedevstack/grid-table&lt;/code&gt; · &lt;strong&gt;Version:&lt;/strong&gt; 1.0.7&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License:&lt;/strong&gt; MIT&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ol&gt;
&lt;li&gt;What We Have&lt;/li&gt;
&lt;li&gt;New in 1.0.7&lt;/li&gt;
&lt;li&gt;Benefits&lt;/li&gt;
&lt;li&gt;Screenshots from grid-table.com&lt;/li&gt;
&lt;li&gt;Quick Start&lt;/li&gt;
&lt;li&gt;Links &amp;amp; Resources&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What We Have
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core Features
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cell editing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Inline edit with validation (text, number, select, date, boolean). Double-click to edit, Enter to save, Escape to cancel.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dark / light theme&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Built-in theme support with customizable colors.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Filtering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Column-level and global filtering with multiple operators (equals, contains, startsWith, etc.).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sorting&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single and multi-column sorting with custom sort functions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Drag &amp;amp; drop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reorder columns by dragging headers.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Column resize&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Adjust column widths by dragging the resize handle.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pagination&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Built-in pagination with configurable page sizes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Row selection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Single and multi-select with select-all / deselect-all.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Row expansion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Expandable rows with custom content (&lt;code&gt;renderRowExpansion&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Responsive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Mobile-first design; optional mobile drawer for filters/sorting.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Display &amp;amp; UX
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Table effects&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sort animations, row entry effects, hover highlights via &lt;code&gt;tableEffects&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lazy load&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Infinite scroll with configurable batch size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Skeleton loading&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Loading states that match table structure.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overflow tooltip&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full cell content on hover when truncated.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Expandable sub-cell&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Extra content per cell (double-click or arrow).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Studio panel&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dev/prototyping panel for inspecting data and props.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Context API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No prop drilling; access state via &lt;code&gt;useTable&lt;/code&gt; and context.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Full type safety and generics for row data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ARIA attributes and keyboard navigation.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  v1.0.7 Feature Set (see New in 1.0.7)
&lt;/h3&gt;

&lt;p&gt;Keyboard navigation, context menu, tree data, status bar, row reordering, Excel/PDF/CSV/JSON export, copy to clipboard, undo/redo, column pinning, column auto-fit, frozen rows, print mode.&lt;/p&gt;




&lt;h2&gt;
  
  
  New in 1.0.7
&lt;/h2&gt;

&lt;p&gt;Release: &lt;strong&gt;2026-02-24&lt;/strong&gt;. Highlights:&lt;/p&gt;

&lt;h3&gt;
  
  
  Added
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard navigation&lt;/strong&gt; — Arrow keys to move between cells, Enter to edit, Escape to cancel, Tab, Home/End, PageUp/PageDown. Configure via &lt;code&gt;keyboardNavigation&lt;/code&gt; prop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context menu&lt;/strong&gt; — Right-click any cell for copy, filter by value, pin column, hide column. Custom actions via &lt;code&gt;contextMenu.actions&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tree data&lt;/strong&gt; — Hierarchical rows with expand/collapse, indent, and toggle arrows. &lt;code&gt;treeData&lt;/code&gt; with &lt;code&gt;childrenField&lt;/code&gt;, &lt;code&gt;expandAll&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status bar&lt;/strong&gt; — Footer with row count, filtered/selected count, and column aggregations (sum, avg, min, max, count). Configure via &lt;code&gt;statusBar&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row reordering&lt;/strong&gt; — Drag-and-drop rows with visual handle. &lt;code&gt;rowReorder&lt;/code&gt; and &lt;code&gt;onRowReorder&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excel export&lt;/strong&gt; — SpreadsheetML XML (&lt;code&gt;.xls&lt;/code&gt;) via &lt;code&gt;exportToExcel()&lt;/code&gt;. No extra dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF export&lt;/strong&gt; — PDF via print dialog with &lt;code&gt;exportToPDF()&lt;/code&gt;. Styled HTML table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy to clipboard&lt;/strong&gt; — Tab-separated copy with &lt;code&gt;copyToClipboard()&lt;/code&gt; and &lt;code&gt;enableCopy&lt;/code&gt; toolbar button.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Undo/redo&lt;/strong&gt; — Edit history for cell edits (Ctrl+Z / Ctrl+Y). &lt;code&gt;undoRedo&lt;/code&gt;, &lt;code&gt;onUndo&lt;/code&gt;/&lt;code&gt;onRedo&lt;/code&gt;, configurable max history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Column pinning&lt;/strong&gt; — Runtime pin/unpin columns (left/right) via context menu or context action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Column auto-fit&lt;/strong&gt; — Double-click column edge to auto-fit; optional global auto-fit via &lt;code&gt;autoFit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frozen rows&lt;/strong&gt; — Pin rows to top or bottom via &lt;code&gt;frozenRows&lt;/code&gt; (e.g. totals). Stay visible while scrolling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Print mode&lt;/strong&gt; — &lt;code&gt;printConfig&lt;/code&gt; adds print button; styled printable view with title and date.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  New types, hooks, components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Types:&lt;/strong&gt; &lt;code&gt;ContextMenuConfig&lt;/code&gt;, &lt;code&gt;StatusBarConfig&lt;/code&gt;, &lt;code&gt;FrozenRowsConfig&lt;/code&gt;, &lt;code&gt;TreeConfig&lt;/code&gt;, &lt;code&gt;KeyboardNavConfig&lt;/code&gt;, &lt;code&gt;RowReorderConfig&lt;/code&gt;, &lt;code&gt;UndoRedoConfig&lt;/code&gt;, &lt;code&gt;PrintConfig&lt;/code&gt;, &lt;code&gt;AutoFitConfig&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hooks:&lt;/strong&gt; &lt;code&gt;useKeyboardNavigation&lt;/code&gt;, &lt;code&gt;useRowReorder&lt;/code&gt;, &lt;code&gt;useUndoRedo&lt;/code&gt;, &lt;code&gt;useTreeData&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Components:&lt;/strong&gt; &lt;code&gt;ContextMenu&lt;/code&gt;, &lt;code&gt;StatusBar&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One dependency&lt;/strong&gt; — React 16.8+ and optional Bear UI for controls. No heavy grid framework.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-config styling&lt;/strong&gt; — SCSS compiled to CSS; import one CSS file. Works with or without Bear.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fully typed&lt;/strong&gt; — TypeScript generics for rows and columns; full IntelliSense.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Composable&lt;/strong&gt; — Use &lt;code&gt;TableProvider&lt;/code&gt; + hooks for custom layouts and toolbars.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Export out of the box&lt;/strong&gt; — CSV, JSON, Excel, PDF, copy, and print without extra libs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessible&lt;/strong&gt; — ARIA and keyboard support for better a11y.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portal &amp;amp; docs&lt;/strong&gt; — Live demos, playground, theme builder, and docs at &lt;a href="https://grid-table.com/" rel="noopener noreferrer"&gt;grid-table.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ForgeStack ecosystem&lt;/strong&gt; — Fits with Bear UI, Forge Compass, and other ForgeStack packages.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Screenshots from grid-table.com
&lt;/h2&gt;

&lt;p&gt;Screenshots below are from the live demos at &lt;a href="https://grid-table.com/" rel="noopener noreferrer"&gt;https://grid-table.com/&lt;/a&gt;.-&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Basic Demo — full-featured table
&lt;/h3&gt;

&lt;p&gt;Full table with pagination, filters, export, context menu, status bar, frozen row, and loading test.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="https://grid-table.com/demos/basic" rel="noopener noreferrer"&gt;https://grid-table.com/demos/basic&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Features Demo — v1.0.7 highlights
&lt;/h3&gt;

&lt;p&gt;Four sections: Context Menu + Status Bar + Export; Row Reorder + Undo/Redo + Keyboard Nav; Tree Data; Frozen Rows + Print.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="https://grid-table.com/demos/features" rel="noopener noreferrer"&gt;https://grid-table.com/demos/features&lt;/a&gt;
context menu and status bar

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;docs/screenshots/features-row-reorder.png&lt;/code&gt; — Task table with row reorder and status bar&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/screenshots/features-tree.png&lt;/code&gt; — Tree data (hierarchical employees)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;docs/screenshots/features-frozen-print.png&lt;/code&gt; — Frozen rows and print&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Finance Demo — live data
&lt;/h3&gt;

&lt;p&gt;Live-updating table with sparklines (if applicable).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="https://grid-table.com/demos/finance" rel="noopener noreferrer"&gt;https://grid-table.com/demos/finance&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. HR Demo — tree view
&lt;/h3&gt;

&lt;p&gt;Hierarchical HR tree with expand/collapse.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="https://grid-table.com/demos/hr" rel="noopener noreferrer"&gt;https://grid-table.com/demos/hr&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Theme Builder
&lt;/h3&gt;

&lt;p&gt;Interactive theme customization and code export.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="https://grid-table.com/theme-builder" rel="noopener noreferrer"&gt;https://grid-table.com/theme-builder&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Playground
&lt;/h3&gt;

&lt;p&gt;Toggle props live and see generated code.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL:&lt;/strong&gt; &lt;a href="https://grid-table.com/playground" rel="noopener noreferrer"&gt;https://grid-table.com/playground&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @forgedevstack/grid-table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Import CSS (required)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@forgedevstack/grid-table/grid-table.css&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;
  
  
  Minimal example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GridTable&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;@forgedevstack/grid-table&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="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ColumnDefinition&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;@forgedevstack/grid-table&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@forgedevstack/grid-table/grid-table.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&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="nl"&gt;email&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="nl"&gt;role&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="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;unknown&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;columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ColumnDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&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;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sortable&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="na"&gt;filterable&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sortable&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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Role&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;filterType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;select&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;filterOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Admin&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="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jane Smith&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jane@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;GridTable&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;columns&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;columns&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;enableRowSelection&lt;/span&gt;
      &lt;span class="na"&gt;showPagination&lt;/span&gt;
      &lt;span class="na"&gt;showFilter&lt;/span&gt;
      &lt;span class="na"&gt;enableExport&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;csv&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;json&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;excel&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;pdf&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="na"&gt;tableEffects&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hover&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="na"&gt;sort&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="na"&gt;row&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="si"&gt;}&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;h2&gt;
  
  
  Links &amp;amp; Resources
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Resource&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Live portal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/" rel="noopener noreferrer"&gt;grid-table.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Basic demo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/demos/basic" rel="noopener noreferrer"&gt;grid-table.com/demos/basic&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Features demo (1.0.7)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/demos/features" rel="noopener noreferrer"&gt;grid-table.com/demos/features&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Finance demo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/demos/finance" rel="noopener noreferrer"&gt;grid-table.com/demos/finance&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HR demo&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/demos/hr" rel="noopener noreferrer"&gt;grid-table.com/demos/hr&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Theme builder&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/theme-builder" rel="noopener noreferrer"&gt;grid-table.com/theme-builder&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Playground&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://grid-table.com/playground" rel="noopener noreferrer"&gt;grid-table.com/playground&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;npm&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@forgedevstack/grid-table" rel="noopener noreferrer"&gt;npmjs.com/package/@forgedevstack/grid-table&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/yaghobieh/grid-table" rel="noopener noreferrer"&gt;github.com/yaghobieh/grid-table&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ForgeStack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://forgedevstack.com" rel="noopener noreferrer"&gt;forgedevstack.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;p&gt;&lt;em&gt;Grid Table v1.0.7 — part of the ForgeStack ecosystem.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>tailwindcss</category>
      <category>angular</category>
    </item>
    <item>
      <title>Bear UI 1.1.2 + ForgeStack Ecosystem Update (Kiln, Crucible, CLI)</title>
      <dc:creator>John Yaghobieh</dc:creator>
      <pubDate>Fri, 27 Feb 2026 21:59:25 +0000</pubDate>
      <link>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-112-forgestack-ecosystem-update-kiln-crucible-cli-4l4p</link>
      <guid>https://dev.to/john_yaghobieh_8f294091f6/bear-ui-112-forgestack-ecosystem-update-kiln-crucible-cli-4l4p</guid>
      <description>&lt;p&gt;The ForgeStack ecosystem just got a major quality pass, and &lt;strong&gt;Bear UI 1.1.2&lt;/strong&gt; is the center of it.&lt;/p&gt;

&lt;p&gt;This update is not only about new components — it also improves docs, theming control, release flow, and the developer experience across tools like &lt;strong&gt;Kiln&lt;/strong&gt;, &lt;strong&gt;Crucible&lt;/strong&gt;, and the ForgeStack &lt;strong&gt;CLI&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s New in Bear UI 1.1.2
&lt;/h2&gt;

&lt;h3&gt;
  
  
  New components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FormField&lt;/strong&gt; (TextField-style behavior)

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;outlined&lt;/code&gt;, &lt;code&gt;filled&lt;/code&gt;, and &lt;code&gt;standard&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;label starts inside, floats on focus/value&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;AspectRatio&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;clean media/layout ratio container&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;PasswordInput&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;visibility toggle&lt;/li&gt;
&lt;li&gt;shift/caps indicator option&lt;/li&gt;
&lt;li&gt;custom icon props&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;AlertDialog&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;confirmation flows with a11y defaults&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;InputGroup&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;grouped field labels, helper/error structure&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Existing component upgrades
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;clearable&lt;/code&gt;, &lt;code&gt;onClear&lt;/code&gt;, &lt;code&gt;success&lt;/code&gt;, &lt;code&gt;aria-invalid&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;character counter support&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Button&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;loadingText&lt;/code&gt;, &lt;code&gt;aria-busy&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;icon size consistency fixes&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;ResizableTextarea / RichEditor&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;improved counter/label/error behavior&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Theming Improvements (Big One)
&lt;/h2&gt;

&lt;p&gt;A key goal was making components truly themeable through &lt;code&gt;BearProvider&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now you can centrally override styles (like border, color, font size) for more field-level components, including &lt;code&gt;FormField&lt;/code&gt; and &lt;code&gt;Input&lt;/code&gt;, instead of styling each usage manually.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;BearProvider&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ec4899&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;15px&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&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;#ec4899&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;outlined&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f472b6&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="na"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;borderColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ec4899&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&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;#ec4899&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="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;BearProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Portal Updates (bearui.com)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Reworked nav structure&lt;/li&gt;
&lt;li&gt;New &lt;strong&gt;Theming &amp;amp; Customization&lt;/strong&gt; documentation sections&lt;/li&gt;
&lt;li&gt;Better &lt;strong&gt;Store&lt;/strong&gt; presentation (MUI-inspired structure, no payment flow)&lt;/li&gt;
&lt;li&gt;Improved topbar UX:

&lt;ul&gt;
&lt;li&gt;command-palette style search trigger (&lt;code&gt;⌘K&lt;/code&gt; / &lt;code&gt;Ctrl+K&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;release/notification updates&lt;/li&gt;
&lt;li&gt;settings and cookie preferences&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Added Spanish-ready UI strings foundation for key sections&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  ForgeStack Ecosystem News
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Kiln
&lt;/h3&gt;

&lt;p&gt;Kiln direction is being refined around publishing workflow and better integration patterns with the broader stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Crucible
&lt;/h3&gt;

&lt;p&gt;Crucible continues to evolve as part of the ecosystem roadmap, with focus on practical developer workflows and interoperability.&lt;/p&gt;

&lt;h3&gt;
  
  
  ForgeStack CLI
&lt;/h3&gt;

&lt;p&gt;Template flow is expanding and becoming more visible in the portal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-forge my-app &lt;span class="nt"&gt;--template&lt;/span&gt; react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the fastest way to bootstrap with Bear + ForgeStack conventions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this release matters
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;1.1.2&lt;/code&gt; is a “developer quality” release:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better component behavior parity with familiar UI patterns&lt;/li&gt;
&lt;li&gt;cleaner theming system&lt;/li&gt;
&lt;li&gt;stronger docs and discoverability&lt;/li&gt;
&lt;li&gt;tighter ecosystem story (Bear + CLI + tools)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you already use Bear, this release removes friction.&lt;br&gt;&lt;br&gt;
If you are new, it makes the first-run experience much smoother.&lt;/p&gt;




&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Bear UI docs: &lt;a href="https://bearui.com" rel="noopener noreferrer"&gt;https://bearui.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bear npm: &lt;a href="https://www.npmjs.com/package/@forgedevstack/bear" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@forgedevstack/bear&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>ui</category>
      <category>tailwindcss</category>
    </item>
  </channel>
</rss>
