<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Alex</title>
    <description>The latest articles on Forem by Alex (@asmyshlyaev177).</description>
    <link>https://forem.com/asmyshlyaev177</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F186893%2F2f9e908a-4e24-4761-a5c5-4c39003c4c8a.gif</url>
      <title>Forem: Alex</title>
      <link>https://forem.com/asmyshlyaev177</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/asmyshlyaev177"/>
    <language>en</language>
    <item>
      <title>How I Built state-in-url: My Journey Turning the URL Bar into Real React State</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 13 Apr 2026 13:39:54 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/how-i-built-state-in-url-my-journey-turning-the-url-bar-into-real-react-state-a67</link>
      <guid>https://forem.com/asmyshlyaev177/how-i-built-state-in-url-my-journey-turning-the-url-bar-into-real-react-state-a67</guid>
      <description>&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%2F24etxlwjhdvzujmmb2yb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F24etxlwjhdvzujmmb2yb.gif" alt="state-in-url demo gif" width="600" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm the developer behind &lt;strong&gt;state-in-url&lt;/strong&gt;. The library lets you put real JavaScript values - numbers, Date objects, nested arrays, objects - directly into browser query parameters. It keeps full TypeScript support throughout. The hook behaves exactly like useState, but the state lives in the URL. It survives reloads. You can share the link and nothing gets lost.&lt;/p&gt;

&lt;p&gt;Try the live demo at &lt;a href="https://state-in-url.dev" rel="noopener noreferrer"&gt;https://state-in-url.dev&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Type in the form. Watch the URL change instantly. Refresh the page. The data stays exactly as you left it. The example sits right in the repo too.&lt;/p&gt;

&lt;p&gt;This project grew from a frustration I hit again and again while working on dashboards and larger forms. State ended up split across local variables, a store, and the URL for sharing. Other libraries came close, yet they always added too much setup or turned everything into strings and dropped my types. I decided to build the version I actually wanted to use every day.&lt;/p&gt;

&lt;p&gt;The repo now sits at 400+ stars on GitHub. Version 6.1.2 shipped a few weeks ago. It still surprises me that people use it. Here is the full story - the frustrations, the choices that worked, the testing struggles, and what stayed with me afterward.&lt;/p&gt;

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

&lt;p&gt;You have probably faced this situation. A page holds filters or a detailed form. State lives in three places at once. Local component values. Maybe a store. Plus the URL so users can bookmark or share their exact view. Syncing it all felt like constant extra work.&lt;/p&gt;

&lt;p&gt;I wanted the hook to stay dead simple. Return state and a setter, just like useState, but with TypeScript awareness of the exact shape. Real data types that survive the URL round trip. Clean support for Next.js App Router with SSR, plus React Router and Remix. No interference with other query parameters. And keep the whole thing tiny - zero runtime dependencies, under 2 KB gzipped.&lt;br&gt;
That became my starting point in spare time.&lt;/p&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;The choice I remain happiest about is straightforward. I used one plain JavaScript object for both default values and the type definition. Without separate schema or heavy generics. You write code like this&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formState&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;agree_to_terms&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;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;as&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;value&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="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&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;as&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FormState&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;formState&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass that object to the hook and everything flows. Types and defaults work out of the box.&lt;br&gt;
For shared state with useSharedState, I relied on a single JavaScript object. Components subscribe to changes, without React Context. It handled cases where unrelated parts of the app needed the same data without added complexity.&lt;br&gt;
The encoder and decoder required some tuning. The goal was a readable URL that still preserved real types. Encoding a larger object takes roughly a millisecond on my machine.&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the Library and the Framework Challenges
&lt;/h2&gt;

&lt;p&gt;I structured the project as a pnpm monorepo. TypeScript dominates the codebase. Core logic lives in one package. Thin adapters cover Next.js, React Router, and Remix. Rollup manages the build. Nothing overly complicated.&lt;br&gt;
Next.js App Router created the biggest difficulties. The way searchParams moves between server and client components caused repeated issues. I added a small header workaround to carry data through on the server side. Hydration stayed intact. Remix and React Router presented fewer obstacles, yet I still needed to handle history modes, push versus replace, and debounce settings so the URL stayed calm during typing.&lt;/p&gt;

&lt;p&gt;Here is a real section from the Next.js 15 demo that runs live at state-in-url.dev&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;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useUrlState&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;state-in-url/next&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;formState&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;./formState&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;Form&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;urlState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUrlState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formState&lt;/span&gt;&lt;span class="p"&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="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;input&lt;/span&gt;
       &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;urlState&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="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;curr&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="err"&gt;…&lt;/span&gt;&lt;span class="nx"&gt;curr&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;}))}&lt;/span&gt;
       &lt;span class="nx"&gt;onBlur&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;setUrl&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt; &lt;span class="c1"&gt;// update URL on blur for smoother typing&lt;/span&gt;
     &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* tags, dates, checkboxes - all typed correctly */&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;The code stays simple. It is just state that happens to live in the URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing was hard but important
&lt;/h2&gt;

&lt;p&gt;I needed the library to feel reliable across frameworks and browsers. Real example apps for Next.js 14+, React Router v6+, and Remix live in the repo. Vitest covers the encoder and decoder basics. More real world tests cases covered with Playwright running full end-to-end tests in Chrome, Firefox, and Safari.&lt;/p&gt;

&lt;p&gt;A fix in one place often broke something elsewhere. The commit message "Tests finally passing on Next.js 15" appeared more times than I care to count. It took quite few attempts adjusting Playwright configurations and the CI matrix.&lt;br&gt;
GitHub Actions now runs linting, building, unit tests, and the complete browser suite on every push and PR. Semantic-release automates version bumps, changelog updates, GitHub releases, and npm publishing. Husky keeps commits tidy. Once the pipeline ran smoothly, maintaining the library stopped feeling like a burden.&lt;/p&gt;
&lt;h2&gt;
  
  
  Launching
&lt;/h2&gt;

&lt;p&gt;I published to npm. The README received every recipe I could gather - debounced updates, resetting to defaults, multiple independent state objects on one page. I linked the live demo and waited.&lt;br&gt;
The first stars arrived and felt surprisingly satisfying. Issues opened, mostly kind ones. Solid CI let me ship fixes quickly. I wrote the honest limits in a separate Limits.md file. URLs hold only so much - around 12 KB stays practical. Readers seemed to value the directness.&lt;/p&gt;
&lt;h2&gt;
  
  
  Lessons
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Making the API match useState exactly shaped every other decision and made the library pleasant to use.&lt;/li&gt;
&lt;li&gt;That single object for shape and defaults removed a lot of complexity.&lt;/li&gt;
&lt;li&gt;Testing inside real frameworks felt painful yet essential - skipping it would have limited adoption.&lt;/li&gt;
&lt;li&gt;Automating releases and chores with semantic-release and GitHub Actions turned maintenance into something manageable.&lt;/li&gt;
&lt;li&gt;Keeping the bundle tiny happened on purpose. I watched the size and avoided dependencies deliberately.
Would I change anything today? I might add Svelte or Astro support earlier. Hash routing could be interesting. The roadmap still has room to grow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this sound interesting give it a try&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add state-in-url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The demo lives at &lt;a href="https://state-in-url.dev" rel="noopener noreferrer"&gt;state-in-url.dev&lt;/a&gt;. The repository sits &lt;a href="https://github.com/asmyshlyaev177/state-in-url" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Star it if the approach fits your work.&lt;/p&gt;

&lt;p&gt;I would enjoy hearing about the URL-state problems you encounter. Leave a comment. Open an issue. Send a pull request. Sharing the process publicly became one of the most rewarding aspects.&lt;br&gt;
Happy coding, MIT license, of course. Build something useful with it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>statemanagement</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>New portfolio website</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 15 Sep 2025 15:24:22 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/new-portfolio-website-4o5i</link>
      <guid>https://forem.com/asmyshlyaev177/new-portfolio-website-4o5i</guid>
      <description>&lt;p&gt;Tried few new things this time.&lt;/p&gt;

&lt;p&gt;Created an initial design with V0, had to refactor a lot, and change many details.&lt;/p&gt;

&lt;p&gt;Chose an Astro framework for a minimal footprint on bundle size, and the best performance.&lt;/p&gt;

&lt;p&gt;It's quite simple, but hopefully worth it. Will appreciate any feedback.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://asmyshlyaev177.dev/" rel="noopener noreferrer"&gt;Portfolio link&lt;/a&gt;&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React rendering quiz</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 08 May 2025 09:55:24 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/react-rendering-quiz-443k</link>
      <guid>https://forem.com/asmyshlyaev177/react-rendering-quiz-443k</guid>
      <description>&lt;p&gt;A simple quiz to illustrate how React rendering works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Parent&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;Parent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      Parent component
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;br&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;Child&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Child&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4&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="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Child component&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;



&lt;p&gt;Try to guess what will be printed to console.&lt;/p&gt;

&lt;p&gt;Answer&lt;br&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%2Fzcarx620tb7bru42a5jw.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%2Fzcarx620tb7bru42a5jw.png" alt="Answer" width="241" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some explanation:&lt;br&gt;
⇾ First &lt;code&gt;Parent&lt;/code&gt; is parsed and rendered, without &lt;code&gt;useEffect&lt;/code&gt;,&lt;br&gt;
⇾ after that &lt;code&gt;Child&lt;/code&gt;, when there is no more nested components is turn of async hooks&lt;br&gt;
⇾ React will run &lt;code&gt;useEffect&lt;/code&gt; from children to parents.&lt;/p&gt;

&lt;p&gt;Few more logs, probably related to dev mode.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Breakpoints variables with pure CSS</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 01 May 2025 10:28:18 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/breakpoints-variables-with-pure-css-18ln</link>
      <guid>https://forem.com/asmyshlyaev177/breakpoints-variables-with-pure-css-18ln</guid>
      <description>&lt;p&gt;In CSS can use variables most of the time.&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="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-main&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&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;But, can't use variables in &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@media" rel="noopener noreferrer"&gt;@media&lt;/a&gt; queries.&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;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--br-md&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c"&gt;/* will never work */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unexpected solution is to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@container" rel="noopener noreferrer"&gt;@container&lt;/a&gt; queries:&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="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--is-tablet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;@media&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;--is-tablet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--is-tablet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="s2"&gt;'header aside'&lt;/span&gt;
      &lt;span class="s2"&gt;'feed   aside'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7.16rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;17.6rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7.16rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max-content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--feed-columns&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;Only downside is Firefox lacks support of it, but it doesn't do so well on many things.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next.js usage
&lt;/h2&gt;

&lt;p&gt;In Next.js can use &lt;a href="https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media" rel="noopener noreferrer"&gt;postcss-custom-media&lt;/a&gt; plugin to achieve same outcome, for all browsers and with css modules.&lt;/p&gt;

&lt;p&gt;How it looks like&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;@custom-media&lt;/span&gt; &lt;span class="n"&gt;--is-desktop&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--is-desktop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-areas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="s2"&gt;'header aside'&lt;/span&gt;
      &lt;span class="s2"&gt;'feed   aside'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7.16rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;17.6rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7.16rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max-content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--feed-columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&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;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/docs/pages/guides/post-css" rel="noopener noreferrer"&gt;Official&lt;/a&gt; docs&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install all dependencies:&lt;br&gt;
&lt;code&gt;npm install --save-dev postcss autoprefixer postcss-flexbugs-fixes @csstools/postcss-global-data postcss-custom-media postcss-preset-env&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add PostCSS config to &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nl"&gt;"postcss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"postcss-flexbugs-fixes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"@csstools/postcss-global-data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;need&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;global&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;variables&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;here&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="s2"&gt;"core/styles/vars.css"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"postcss-custom-media"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"postcss-preset-env"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"autoprefixer"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"flexbox"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"no-2009"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"stage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"features"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"custom-properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>webdev</category>
      <category>css</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Minification bugs</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Fri, 04 Apr 2025 11:37:21 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/minification-bugs-2p9m</link>
      <guid>https://forem.com/asmyshlyaev177/minification-bugs-2p9m</guid>
      <description>&lt;p&gt;Today I learned that minification in JS is a double-edged sword.&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%2Fwhknespllmamj0mkhjjc.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%2Fwhknespllmamj0mkhjjc.png" alt="Esbuild docs" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was a weird bug, took me quite some time to figure out that problem in minification.&lt;br&gt;
Stopped using &lt;code&gt;terser&lt;/code&gt; for the same reasons.&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%2Fyup1lsqr57tut71tv75e.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%2Fyup1lsqr57tut71tv75e.png" alt="esbuild issue" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Next.js at refactor or extinct situation.</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Fri, 13 Dec 2024 08:21:03 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/nextjs-at-refactor-or-extinct-situation-27mi</link>
      <guid>https://forem.com/asmyshlyaev177/nextjs-at-refactor-or-extinct-situation-27mi</guid>
      <description>&lt;p&gt;Next.js become a hype of the day (or year), but it's slowly suffocating under the weight of technical debt.&lt;/p&gt;

&lt;p&gt;There are many big enough pain points with Next.js:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Slow and painful dev mode, if you changed something and need to check more than 1 route, you need to wait till route compiled. Next.js server also uses few gigabytes of RAM. Turbopack complaining about perfectly working TS code, and struggle to understand &lt;code&gt;:global&lt;/code&gt; in CSS modules, still not production ready.&lt;/li&gt;
&lt;li&gt;Whole workflow is intended to be used mostly with server components, but in real world applications big chunks of applications use client side JS, because it's way faster and more responsive.&lt;/li&gt;
&lt;li&gt;Routing is a mess, pages router was good enough, but App Router it's just a wrapper around it, that lead to more bugs and complexity.&lt;/li&gt;
&lt;li&gt;Vercel service is good, but if popularity of your project going parabolic, costs will follow - &lt;a href="https://news.ycombinator.com/item?id=40618220" rel="noopener noreferrer"&gt;96k bill&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just stumbled upon a bug when &lt;code&gt;useParams&lt;/code&gt; hook periodically returning dead wrong values.&lt;/p&gt;

&lt;p&gt;Searched for existing issues, didn't find any, tried to open issue on their GitHub, can't do than without providing reproducible example. Repository is private, I can't share all of it. And I can't pinpoint the exact condition for a bug to appear in a big enough codebase.&lt;/p&gt;

&lt;p&gt;Similar situation was with &lt;code&gt;Cypress&lt;/code&gt; testing framework. For years people opened issues about flaky tests and memory leaks, all of them were closed, because can't properly reproduce them. Easy to make something works in a TODO app, real challenge is a big and complex application. Usually, people work under NDA and can't just share the whole repository.&lt;br&gt;
After some time Playwright came and Cypress isn't relevant any more.&lt;/p&gt;

&lt;p&gt;Let's see approximate quality ratio, by calculating stars to bugs for Cypress.&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%2Ft3ygqalkolclgbro763r.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%2Ft3ygqalkolclgbro763r.png" alt="Cypress github stats" width="800" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;47600 stars / 14600 bugs = &lt;strong&gt;34 quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cypress&lt;/code&gt;'s successor - &lt;code&gt;Playwright&lt;/code&gt;&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%2Fmueqcjz1w9aal975t1v0.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%2Fmueqcjz1w9aal975t1v0.png" alt="Playwright github stats" width="800" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;67_700 stars / 692 issue = &lt;strong&gt;97 quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm aware that many bugs issues it's just misunderstanding or duplicates, still, if something confusing in a documentation/example, it is a con of software.&lt;/p&gt;

&lt;p&gt;Let's see about &lt;code&gt;Next.js&lt;/code&gt;&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%2Fm1mysu3v1goa6yughj4z.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%2Fm1mysu3v1goa6yughj4z.png" alt="Next.js github stats" width="800" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;128_000 stars / 3000 bugs = &lt;strong&gt;42 quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's see &lt;code&gt;React.js&lt;/code&gt; repo for context&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%2F597zqm0gu4y2s4o0rmhr.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%2F597zqm0gu4y2s4o0rmhr.png" alt="React.js github stats" width="800" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;230_000 stars / 754 bugs = &lt;strong&gt;305 quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And &lt;code&gt;Remix.js&lt;/code&gt; repo (SSR framework from &lt;code&gt;react-router&lt;/code&gt; team)&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%2F9g5x88ve929x7892po87.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%2F9g5x88ve929x7892po87.png" alt="Remix.js github stats" width="800" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;30_300 stars / 295 bugs = &lt;strong&gt;102 quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;All of this just my opinions, but it's backed by years of experience with different frameworks/libraries and observations.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Beyond console.log</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Sun, 24 Nov 2024 09:49:53 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/beyond-consolelog-1h40</link>
      <guid>https://forem.com/asmyshlyaev177/beyond-consolelog-1h40</guid>
      <description>&lt;h2&gt;
  
  
  intro
&lt;/h2&gt;

&lt;p&gt;As much as I hope that things will always work from first try, better to be prepared to debug it. &lt;code&gt;console.log&lt;/code&gt; remains the main tool to do it, because it is the simplest and fastest.&lt;/p&gt;

&lt;p&gt;Few console methods are known to everybody, &lt;code&gt;log&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt; and &lt;code&gt;error&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Going deeper
&lt;/h2&gt;

&lt;p&gt;There are more tricks to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;count&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;For example, if you need to count how many times component re-render can use &lt;code&gt;console.count&lt;/code&gt;, e.g. &lt;code&gt;console.count('comp1')&lt;/code&gt;&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%2Furymtdynzh46ldlb96ga.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%2Furymtdynzh46ldlb96ga.png" alt="console.count" width="663" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;group&lt;/code&gt; and &lt;code&gt;groupCollapsed&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Can log some info in a collapsed group with &lt;code&gt;console.groupCollapsed&lt;/code&gt;, great in case of many error messages, when they printed collapsed it's less distracting, but Node.js/Sentry probably will print all expanded.&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%2Fjeclio3a0crk4gl59oby.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%2Fjeclio3a0crk4gl59oby.png" alt="console.groupCollapsed" width="675" height="218"&gt;&lt;/a&gt;&lt;br&gt;
After click &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%2Fu1dig323rwr0pmg998xh.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%2Fu1dig323rwr0pmg998xh.png" alt="console.groupCollapsed expanded" width="675" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  styling
&lt;/h3&gt;

&lt;p&gt;Can use some CSS&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%2Fv19au70e4gi4lpuyn9mt.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%2Fv19au70e4gi4lpuyn9mt.png" alt="console.log with CSS styles" width="675" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;dir&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Can log properties of an object with &lt;code&gt;console.dir&lt;/code&gt;&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%2Famahwwee45em2018xmuv.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%2Famahwwee45em2018xmuv.png" alt="console.dir" width="408" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  objects
&lt;/h3&gt;

&lt;p&gt;Can log few objects with curly braces like &lt;code&gt;console.log({ obj1, obj2 })&lt;/code&gt;, instead of &lt;code&gt;console.log('Ojb1', obj1)&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;assert&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Can assert things with &lt;code&gt;console.assert&lt;/code&gt; &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%2F4390c1ubs0a4yezgf501.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%2F4390c1ubs0a4yezgf501.png" alt="console.assert" width="675" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;time&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Can measure how long some operation takes with &lt;code&gt;console.time&lt;/code&gt;&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%2Fuhzjqa4estugyguph38r.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%2Fuhzjqa4estugyguph38r.png" alt="console.time" width="656" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;trace&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Print a stack trace with &lt;code&gt;console.trace()&lt;/code&gt;&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%2Fvq1o0nkxsawrssgb4mpy.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%2Fvq1o0nkxsawrssgb4mpy.png" alt="console.trace" width="644" height="207"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;clear&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Clear things up with &lt;code&gt;console.clear()&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Related
&lt;/h2&gt;

&lt;p&gt;Check out great old post - &lt;a href="https://dev.to/lissy93/fun-with-consolelog-3i59"&gt;https://dev.to/lissy93/fun-with-consolelog-3i59&lt;/a&gt; &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>First really useful AI tool - AI code review</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Thu, 14 Nov 2024 20:42:30 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/first-really-useful-ai-tool-ai-code-review-1an4</link>
      <guid>https://forem.com/asmyshlyaev177/first-really-useful-ai-tool-ai-code-review-1an4</guid>
      <description>&lt;p&gt;Finally, I found at least 1 really useful AI service.&lt;/p&gt;

&lt;h2&gt;
  
  
  The service
&lt;/h2&gt;

&lt;p&gt;It's called &lt;a href="https://www.coderabbit.ai/" rel="noopener noreferrer"&gt;&lt;strong&gt;CodeRabbit&lt;/strong&gt;&lt;/a&gt;, the idea behind it is pretty simple, AI review code changes and give you recommendations how to fix it with explanation.&lt;/p&gt;

&lt;p&gt;AI is working as pattern recognition, so, it's perfectly suitable for recognizing antipatterns in pull requests.&lt;/p&gt;

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

&lt;p&gt;After PR created, GitHub action run and analyze changes. It's post summary like this:&lt;/p&gt;

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

&lt;p&gt;The second comment contains recommendations:&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%2Fos86sp9ccna5faqpbj43.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%2Fos86sp9ccna5faqpbj43.png" alt="PR review 1" width="800" height="449"&gt;&lt;/a&gt;&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%2Fl2pt8qk7jwuvtxayim08.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%2Fl2pt8qk7jwuvtxayim08.png" alt="PR review 2" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This service already found few minor mistakes that I missed. Definitely worth trying.&lt;/p&gt;

&lt;p&gt;Reviewing PRs is a very tedious task, AI can actually help with it.&lt;/p&gt;

&lt;p&gt;Of course there are probably 3 useful comments out of 10, but it is very similar with human reviewers, e.g. they're either nitpicking the every line or blindly approve huge PR.&lt;/p&gt;

&lt;p&gt;Treat such comments as possibly useful recommendation, not like obligation to fix everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Price
&lt;/h2&gt;

&lt;p&gt;Currently, you can use it for free with basic functionality, and 12$/month for Pro version.&lt;br&gt;
Probably, this promotion-like pricing will change in the future, but again, worth giving it a try.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>codereview</category>
    </item>
    <item>
      <title>Solving slow compilation in dev mode for Next.js</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Fri, 08 Nov 2024 12:04:05 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/solving-slow-compilation-in-dev-mode-for-nextjs-3ilb</link>
      <guid>https://forem.com/asmyshlyaev177/solving-slow-compilation-in-dev-mode-for-nextjs-3ilb</guid>
      <description>&lt;p&gt;Noticed that &lt;code&gt;Next.js&lt;/code&gt; dev server is really slow, annoying that it can't precompile pages in the background.&lt;br&gt;
There is a &lt;a href="https://github.com/vercel/next.js/issues/48748" rel="noopener noreferrer"&gt;discussion about it.&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Ways to make it faster
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Turbopack
&lt;/h3&gt;

&lt;p&gt;Can use turbopack, can run it with &lt;code&gt;next dev --turbo&lt;/code&gt;, downsides that  if you use some fine tweaks for Webpack, not everything works correctly with turbopack (at least for v14).&lt;/p&gt;
&lt;h3&gt;
  
  
  Upgrade to Next.js v15
&lt;/h3&gt;

&lt;p&gt;v15 is faster by default, some common issues were solved. There is a &lt;a href="https://nextjs.org/docs/app/building-your-application/upgrading/version-15" rel="noopener noreferrer"&gt;codemod&lt;/a&gt; that will do most of the things for you in a few seconds.&lt;br&gt;
Still, requires some effort.&lt;/p&gt;
&lt;h3&gt;
  
  
  Config tweaks
&lt;/h3&gt;

&lt;p&gt;There is &lt;a href="https://nextjs.org/docs/app/api-reference/next-config-js/onDemandEntries" rel="noopener noreferrer"&gt;&lt;code&gt;onDemandEntries&lt;/code&gt;&lt;/a&gt; option for &lt;code&gt;next.config.js&lt;/code&gt;, can use it to force dev server to store more compiled pages in memory, so you will see fewer &lt;code&gt;compiling /page ...&lt;/code&gt; lines.&lt;br&gt;
For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nextConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;onDemandEntries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// period (in ms) where the server will keep pages in the buffer&lt;/span&gt;
    &lt;span class="na"&gt;maxInactiveAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 15 minutes&lt;/span&gt;
    &lt;span class="c1"&gt;// number of pages that should be kept simultaneously without being disposed&lt;/span&gt;
    &lt;span class="na"&gt;pagesBufferLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&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;Tnx for reading.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Dark side of Next.js - App Router</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 06 Nov 2024 19:57:49 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/dark-side-of-nextjs-app-router-15l</link>
      <guid>https://forem.com/asmyshlyaev177/dark-side-of-nextjs-app-router-15l</guid>
      <description>&lt;p&gt;Today, I want to share the disappointing issue with Next.js - &lt;strong&gt;App router.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About SSR
&lt;/h2&gt;

&lt;p&gt;I assume that you're aware of what SSR is and vaguely understand how it works.&lt;br&gt;
E.g. server return HTML page with markup, while JS and CSS bundles downloading, user see the page instantly and parsing JS code taking some time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;_rsc&lt;/code&gt; problem
&lt;/h2&gt;

&lt;p&gt;Every time you switch route in Next.js, it's requesting some meta info from server first, you can see such requests as &lt;code&gt;{smt}_rsc&lt;/code&gt;, stand for _ReactServerComponent as I can guess.&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%2Fm4enkgp37dnkee29cfzi.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%2Fm4enkgp37dnkee29cfzi.png" alt="_rsc requests" width="639" height="68"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Server responds with something like this&lt;/p&gt;

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

&lt;p&gt;Problem that Next.js router make those requests even if you need to update searchParams, e.g. &lt;code&gt;/url?param=value&lt;/code&gt;, &lt;strong&gt;it isn't a new page, all purely client side, but there is still a _rsc request.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another example, when have list with cards, every card has an edit button with &lt;code&gt;Next/Link&lt;/code&gt; component, and separate edit page like &lt;code&gt;/card/{some_id}/edit&lt;/code&gt;.&lt;br&gt;
Next.js trying to optimize things and prefetching those &lt;code&gt;_rsc&lt;/code&gt; requests ahead of time. In result, there will be a request for every card, but user possibly won't ever click an edit button.&lt;/p&gt;

&lt;p&gt;Even if you have very fast server and internet connection, network requests making UI slower, and put more stress on a server.&lt;/p&gt;

&lt;p&gt;While SSR is great for an initial page load, navigation after app loaded happens way more often.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discussions
&lt;/h2&gt;

&lt;p&gt;There are few discussions about this problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/vercel/next.js/discussions/59167" rel="noopener noreferrer"&gt;https://github.com/vercel/next.js/discussions/59167&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/nextjs/comments/1ds5nl4/what_are_all_these_rsc_network_requests/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/nextjs/comments/1ds5nl4/what_are_all_these_rsc_network_requests/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/reactjs/comments/13vkgl0/nextjs_app_router_is_complete_failure_what/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/reactjs/comments/13vkgl0/nextjs_app_router_is_complete_failure_what/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to solve it
&lt;/h2&gt;

&lt;p&gt;Switching to something like &lt;code&gt;Remix&lt;/code&gt; will be too hard for existing project.&lt;/p&gt;

&lt;p&gt;Can use plain old &lt;code&gt;window.history&lt;/code&gt; interface with pushState/replaceState instead of App router, when you sure it purely client side.&lt;/p&gt;

&lt;p&gt;For &lt;code&gt;queryParams&lt;/code&gt;/&lt;code&gt;searchParams&lt;/code&gt; can use a library to simplify those things - &lt;a href="https://github.com/asmyshlyaev177/state-in-url" rel="noopener noreferrer"&gt;state-in-url&lt;/a&gt; , it's using &lt;code&gt;history&lt;/code&gt; by default and has an option to use App router. Also, it's way simpler than NUQS, parsing with proper type just work out of the box.&lt;/p&gt;

&lt;p&gt;Tnx for reading, consider giving it a like and maybe share.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>ssr</category>
    </item>
    <item>
      <title>Surprising benefit of GraphQL for long-term maintainability</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Wed, 30 Oct 2024 17:03:18 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/surprising-benefit-of-graphql-for-long-term-maintainability-5c2p</link>
      <guid>https://forem.com/asmyshlyaev177/surprising-benefit-of-graphql-for-long-term-maintainability-5c2p</guid>
      <description>&lt;p&gt;When it comes to Frontend-Backend communication, there are few options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST&lt;/li&gt;
&lt;li&gt;OpenAPI&lt;/li&gt;
&lt;li&gt;GraphQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the first glance, GraphQL seems like overkill that slowing down the whole team.&lt;/p&gt;

&lt;p&gt;But as the project grows, complexity grows as well. Eventually you will come to a situation when seemingly simple change can break something in the other part of the application, something you couldn't possibly think of.&lt;/p&gt;

&lt;p&gt;The obvious solution to it is tests, with Cypress or Playwright. In unit tests, many of the browser APIs are unavailable or behave differently, and most of the bugs hide in how a dozen of simple components glued together.&lt;/p&gt;

&lt;p&gt;With REST there is no schema to describe API endpoints, OpenAPI has the schema, but validating against it is very tricky. Only GraphQL option left.&lt;/p&gt;

&lt;p&gt;There are 2 ways to frontend testing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Record API requests/responses and replay them during tests.&lt;/li&gt;
&lt;li&gt;Set up the whole backend and populate proper test data for every test case.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using live backend for tests requires huge amount of effort, need to populate data before test, run the test and clean up at the end. It will take too much time to go this way.&lt;/p&gt;

&lt;p&gt;So, we end up with recording API communications. But what happen if API definition changes?&lt;/p&gt;

&lt;p&gt;And here GraphQL really shines, at least Apollo GraphQL.&lt;br&gt;
Any inconsistency on the schema between backend and frontend will fail the test.&lt;br&gt;
It's mean that any code change that affect API contract will be caught in time.&lt;/p&gt;

&lt;p&gt;So, any complex enough application will be way more maintainable with  GraphQL.&lt;/p&gt;

&lt;p&gt;Tnx for reading, share your thoughts in comments, like and subscribe, you know the drill.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>graphql</category>
      <category>testing</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Why I don't specify pronouns</title>
      <dc:creator>Alex</dc:creator>
      <pubDate>Mon, 30 Sep 2024 09:48:42 +0000</pubDate>
      <link>https://forem.com/asmyshlyaev177/why-i-dont-specify-pronouns-4chj</link>
      <guid>https://forem.com/asmyshlyaev177/why-i-dont-specify-pronouns-4chj</guid>
      <description>&lt;p&gt;Can see preferred pronouns on some GitHub profiles.&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%2Fejwivm0p8gkgy4v1larb.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%2Fejwivm0p8gkgy4v1larb.png" alt="GitHub profile screenshot" width="250" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to discuss why I don't do it, why I don't think anybody should, and why it isn't a good thing.&lt;/p&gt;

&lt;p&gt;A recent example - &lt;a href="https://thatparkplace.com/report-concord-developer-demanded-co-workers-refer-to-her-as-professor-pushed-extreme-politics-and-demanded-her-unvaccinated-colleagues-be-fired/" rel="noopener noreferrer"&gt;‘Concord’ Developer Demanded Co-Workers Refer To Her As “Professor,” Pushed “Extreme Politics,” And Demanded Her Unvaccinated Colleagues Be Fired&lt;/a&gt;. This come to light because of epic failure of Concord game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arguments for
&lt;/h2&gt;

&lt;p&gt;Respecting rules and agreements of group/society/company is a nice social treat. That it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arguments against
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Need to remember pronouns for everybody, add it to struggle to remember names of people in a company. Inconvenient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Some of the pronouns contradict English grammar and common sense. It could be a big deal for neurodivergent people, so it's exclude them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's impose a set of ideology on everybody, how you will feel if somebody will demand to remove all globes from everywhere because some believe that earth is flat? Or putting a flat globe near every spherical one?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Person is falling for every trend and hype, better to use common sense approach. There are countless hypes in SE industry, css-in-js, microservices, and more. All of them has downsides and price to pay.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  5. And most interesting topic, follow me.
&lt;/h3&gt;

&lt;p&gt;There are some psychological treats that undesirable in a work place, even a red flag if we're talking about management. &lt;strong&gt;Narcissism&lt;/strong&gt; is one of them.&lt;/p&gt;

&lt;p&gt;Looking on definition of narcissism&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;selfishness, involving a sense of entitlement, a lack of empathy, and a need for admiration, as characterizing a personality type&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And some description&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Believe they are superior to others and can only spend time with or be understood by equally special people. Be critical of and look down on people they feel are not important. Expect special favors and expect other people to do what they want without questioning them. Take advantage of others to get what they want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So why this is a bad thing for a company?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There tends to be a &lt;strong&gt;higher level of stress&lt;/strong&gt; with people who work with or interact with a narcissist. While there are a variety of reasons for this to be the case, an important one is &lt;strong&gt;the relationship between narcissism and aggression&lt;/strong&gt;. Aggression is believed to moderate the relationship between narcissism and counterproductive work behaviors. According to Penney and Spector, &lt;strong&gt;narcissism is positively related to counterproductive workplace behaviors, such as interpersonal aggression, sabotaging the work of others, finding excuses to waste other peoples' time and resources, and spreading rumors&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are discussions about this,&lt;a href="https://www.thetimes.com/comment/columnists/article/declaring-your-pronouns-is-pure-narcissism-7rffv2mrz" rel="noopener noreferrer"&gt;New York Times article&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Some tactics used by narcissists:
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Gaslighting&lt;/li&gt;
&lt;li&gt;Playing the Victim&lt;/li&gt;
&lt;li&gt;Projection&lt;/li&gt;
&lt;li&gt;Hoovering&lt;/li&gt;
&lt;li&gt;Smear Campaign&lt;/li&gt;
&lt;li&gt;Revenge Seeking&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hope that you google this topic and think about it. All of it seems like some modern politics is justification of narcissism.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about hiring?
&lt;/h3&gt;

&lt;p&gt;Quote from wiki:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Narcissists typically perform well at job interviews; &lt;strong&gt;they receive more favorable hiring ratings from interviewers than individuals who are not narcissists.&lt;/strong&gt; Typically, because they can make favorable first impressions, though that may not translate to better job performance once hired.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What you can do if you work with one?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Playing along
&lt;/h4&gt;

&lt;p&gt;There is temptation to just appease such person, but it will make it worse in a long term. Such people (and other not so pleasant ones) desire power over others, if you go along with their games 1 time, they will expect it again tomorrow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fighting
&lt;/h4&gt;

&lt;p&gt;Fighting and conflict isn't any better, narcissists develop many defense mechanisms to avoid dealing with their own shortcomings, they have ready to use proved tactics to win in such situation.&lt;br&gt;
They will use manipulations and tricks, often dirty ones, playing a victim, lying, rumors and false accusation are expected.&lt;/p&gt;

&lt;h4&gt;
  
  
  "Solution"
&lt;/h4&gt;

&lt;p&gt;Maintain your boundaries, preserve your right to chose your own beliefs, don't start confrontation intentionally, be professional and careful. I recommend to search for some YouTube videos on this topic, like "&lt;strong&gt;Surviving Narcissism&lt;/strong&gt;".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is your experience and opinion about this? Post it in comments.&lt;/strong&gt;&lt;br&gt;
Also, like and share this if you think it's interesting.&lt;/p&gt;

</description>
      <category>hehim</category>
      <category>mentalhealth</category>
      <category>management</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
