<?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: Anton Korzunov</title>
    <description>The latest articles on DEV Community by Anton Korzunov (@thekashey).</description>
    <link>https://dev.to/thekashey</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%2F113306%2F18ae0122-205c-4952-8f73-240175b4ae1d.png</url>
      <title>DEV Community: Anton Korzunov</title>
      <link>https://dev.to/thekashey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thekashey"/>
    <language>en</language>
    <item>
      <title>Weak memoization in Javascript</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Tue, 11 Jun 2024 07:56:40 +0000</pubDate>
      <link>https://dev.to/thekashey/weak-memoization-in-javascript-4po6</link>
      <guid>https://dev.to/thekashey/weak-memoization-in-javascript-4po6</guid>
      <description>&lt;p&gt;I decided to write this article to explain how a few things work as I felt a lack of understanding. Things somehow connected to state management and &lt;em&gt;memoization&lt;/em&gt;. &lt;br&gt;
We need to talk about something very foundational, as well as about abstractions we can build on top.&lt;/p&gt;

&lt;p&gt;This time nothing will be left uncovered. This time you will master worry-free memoization in javascript 😎&lt;/p&gt;




&lt;p&gt;Memoization is such a common thing in JS world nowadays, common and very important. With the recent &lt;a href="https://github.com/reduxjs/reselect/releases/tag/v5.0.1" rel="noopener noreferrer"&gt;release of Reselect 5.0&lt;/a&gt;  it also became a little easier than before. Easier not to break fragile selectors without the need to understand all nuances.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reselect 5 was released in Dec 2023, but the idea behind the &lt;em&gt;breakthrough solution&lt;/em&gt; was boiling for quite a while, &lt;a href="https://github.com/reduxjs/reselect/discussions/491" rel="noopener noreferrer"&gt;for a few years&lt;/a&gt; at least. &lt;br&gt;
The first "modern" implementation I was able to find - &lt;a href="https://github.com/timkendrick/memoize-weak/tree/master" rel="noopener noreferrer"&gt;weak-memoize&lt;/a&gt; - was created around &lt;strong&gt;8 years&lt;/strong&gt; ago.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have reason to believe that the &lt;em&gt;extended adoption&lt;/em&gt; time was influenced by my less-than-stellar communication skills and the challenge of conveying the principles behind "Weak Memoization," which I originally shared five years ago in &lt;a href="https://dev.to/thekashey/memoization-forget-me-bomb-34kh"&gt;Memoization Forget-Me&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Let's give it another shot.&lt;br&gt;
Let’s walk the &lt;strong&gt;full journey&lt;/strong&gt; from something 💁‍♂️ simple to something quite 👨‍🔬 extreme.&lt;br&gt;
This time I'll make you believe.&lt;/p&gt;




&lt;h2&gt;
  
  
  Level 1 - make it work
&lt;/h2&gt;

&lt;p&gt;Let's write a few lines related to performing an operation “once”. &lt;br&gt;
What would the &lt;strong&gt;simplest memoization&lt;/strong&gt; be?&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// some place to store results&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;storedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;storedArgument&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;memoizedCalculation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// is the arg equal to the known one?&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;arg&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;storedArgument&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;storedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// if not - let's calculate new value&lt;/span&gt;
  &lt;span class="nx"&gt;storedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;functionToMemoize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;storedArgument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arg&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;storedValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// usage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memoizedCalculation&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memoizedCalculation&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valueN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memoizedCalculation&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="c1"&gt;// will be memoized&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Looks familiar - I reckon a lot of projects have code like this in a few places.&lt;/p&gt;

&lt;p&gt;The only real problem - this code is not reusable and… 🤮 global variables that are so hard to control, especially in tests. I reckon the obvious next step is to make it a little more robust and introduce a &lt;code&gt;level 2&lt;/code&gt; solution&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 2 - put it in a box
&lt;/h2&gt;

&lt;p&gt;Handling global variables is a complex job, so would making them local improve the situation?&lt;br&gt;
How we can make this code more "local" and more reusable? &lt;/p&gt;

&lt;p&gt;The answer is "factories"&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;// reusable function you can "apply" to any other function
&lt;span class="gi"&gt;+function memoizeCalculation(functionToMemoize) {
&lt;/span&gt;   let storedValue;
   let storedArgument;
   return function memoizedCalculation(arg) {
       // is the arg equal to the known one?
       if(arg === storedArgument) {
         return storedValue;
       }
&lt;span class="err"&gt;
&lt;/span&gt;       // if not - let's calculate new value
       storedValue = functionToMemoize();
       storedArgument = arg;
       return storedValue;
   }
&lt;span class="gi"&gt;+}
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;// fist create a memoized function
&lt;span class="gi"&gt;+const memoizedCalculation = memoizeCalculation(functionToMemoize);
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;// usage
&lt;span class="p"&gt;const value1 = memoizedCalculation(1);
const value2 = memoizedCalculation(2);
const valueN = memoizedCalculation(2); // will be memoized
&lt;/span&gt;&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;Interesting parts - &lt;strong&gt;nothing really changed&lt;/strong&gt; from the usage point of view and nothing really changed from the function implementation - 99% of the code has been preserved, we just put another function around.&lt;/p&gt;

&lt;p&gt;While this implementation is screaming "I am simple" - this is exactly how &lt;a href="https://github.com/alexreardon/memoize-one/blob/master/src/memoize-one.ts#L31" rel="noopener noreferrer"&gt;memoize-one is written&lt;/a&gt;, so it is “simple enough” to handle any production use case 🚀&lt;/p&gt;

&lt;p&gt;This is a solution you actually can use. May be add &lt;code&gt;.clear&lt;/code&gt; method to make ease testing, but that's all.&lt;/p&gt;

&lt;p&gt;More importantly - "the original reselect" was also working this way, and that is "not the best way". Nobody was happy.&lt;/p&gt;

&lt;p&gt;Something drastically changed in reselect &lt;strong&gt;5&lt;/strong&gt;, so let’s move forward and try to &lt;strong&gt;find that precious change&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Boss fight - there could be only one
&lt;/h2&gt;

&lt;p&gt;The problem with &lt;code&gt;reselect&lt;/code&gt; as well as &lt;code&gt;memoize-one&lt;/code&gt; is that &lt;em&gt;“one”&lt;/em&gt; - a &lt;strong&gt;single local variable&lt;/strong&gt; used to store the results of the last invocation. In no circumstances it could be more than one, it just made this way.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why its "one"? Everything is connected to the "pattern" being used and one's ability to cleanup the results of previous memoization.&lt;br&gt;
That is the difference between "caching"(with cache-key, storage limits and time-to-life) and memoization free of any "complications". &lt;br&gt;
&lt;a href="https://dev.to/thekashey/memoization-forget-me-bomb-34kh"&gt;Memoization Forget-Me&lt;/a&gt; explains these moments in detail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🤔 How we can improve this? Maybe it's not "how" or "what". May be it's "where"?&lt;br&gt;
🤨 Let me ask you - &lt;strong&gt;where&lt;/strong&gt; this local variable is stored?&lt;/p&gt;

&lt;p&gt;The correct answer for JavaScript is: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💁‍♂️ "it’s stored in a function closure”, without defining what is a “closure”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A more helpful answer is &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🧐 "the variable is stored in a function &lt;a href="https://en.wikipedia.org/wiki/Call_stack" rel="noopener noreferrer"&gt;stack&lt;/a&gt;”. The very one that can &lt;a href="https://en.wikipedia.org/wiki/Stack_overflow" rel="noopener noreferrer"&gt;overflow&lt;/a&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In technical terms &lt;code&gt;stack&lt;/code&gt; is an &lt;strong&gt;execution context&lt;/strong&gt; - it stores information about current function arguments, all its local variables and where the function should return execution once it is done. It's a section in a memory holding the real data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fln2ok5sv20hl76c27s7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fln2ok5sv20hl76c27s7n.png" alt="Call stack"&gt;&lt;/a&gt;&lt;br&gt;
In the simplest situation calling a function "extends" stack and exiting a function "shrinks" it. Here is why calling to many functions can cause the &lt;strong&gt;stack overflow&lt;/strong&gt; as it cannot grow endlessly.&lt;/p&gt;

&lt;p&gt;However, in the Javascript world it is not so easy, because we have &lt;em&gt;closures&lt;/em&gt; which can "see" variables from dead functions or in other words ➡️ &lt;em&gt;the lifetime of a closure is unbound from the lifetime of its parent context&lt;/em&gt;. As a result "call stack" in JS is more alike a "graph of boxes" with personal stacks of different functions pointing to each other.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fjcgou35ue8fasagcrlxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fjcgou35ue8fasagcrlxk.png" alt="v8 context"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💁‍♂️ So every function has a little box📦 with the data. Very neat.&lt;br&gt;
Here is &lt;a href="https://mrale.ph/blog/2012/09/23/grokking-v8-closures-for-fun.html" rel="noopener noreferrer"&gt;an article with a little deep dive&lt;/a&gt; to v8 execution context details.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every time you call a function it is executed using a different stack, a different context, a different "box". Exactly like &lt;strong&gt;React hooks&lt;/strong&gt; being statically defined in a Function are magically getting values from React Fiber, which is an &lt;code&gt;execution context&lt;/code&gt; for a &lt;strong&gt;particular&lt;/strong&gt; component. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;just ask yourself - where &lt;code&gt;useState&lt;/code&gt; holds value. There should be a special place for it. There is always a special place for something, even in Hell...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👏👏 execution context gives an ability to run the &lt;strong&gt;same&lt;/strong&gt; function with &lt;strong&gt;different&lt;/strong&gt; variables 👏👏&lt;/p&gt;

&lt;p&gt;You know - that sounds like &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this" rel="noopener noreferrer"&gt;this&lt;/a&gt;, which works almost the same way in JavaScript - providing context. And keep in mind - the &lt;em&gt;keyword we no longer use&lt;/em&gt; is not only about &lt;em&gt;classes&lt;/em&gt; - &lt;code&gt;this&lt;/code&gt; works for every operation around.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

 &lt;span class="nx"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;What if we use js context (&lt;code&gt;this&lt;/code&gt;) instead of CPU context (&lt;code&gt;stack&lt;/code&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  Loading level 2 - somewhere else
&lt;/h2&gt;

&lt;p&gt;First of all, I need to point at one &lt;a href="https://github.com/alexreardon/memoize-one/blob/master/src/memoize-one.ts#L31" rel="noopener noreferrer"&gt;implementation detail of memoize-one&lt;/a&gt; which considers a potential side effect of a hidden function argument(&lt;code&gt;this&lt;/code&gt;) potentially leading to different outcomes&lt;/p&gt;

&lt;p&gt;Consider the following code&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;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;render&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;div&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClick&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;p&gt;You might forgotten how it works, but in short - it does not 🤣 as we are losing &lt;code&gt;this&lt;/code&gt; by reading a &lt;em&gt;shared&lt;/em&gt; value from it. To correct implementation one need to &lt;em&gt;inline&lt;/em&gt; callback&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;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="p"&gt;{&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;event&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this case, every &lt;code&gt;this.onClick&lt;/code&gt; would be a very unique and very own &lt;code&gt;onClick&lt;/code&gt;. For me, it sounds like a memoization.&lt;/p&gt;

&lt;p&gt;Wondering how this operation of &lt;em&gt;assigning&lt;/em&gt; "class members" works 🤨? &lt;a href="https://www.typescriptlang.org/play/?#code/MYGwhgzhAECyCeBhcVoG8BQ1oHsB2yAlsANbQC80AFAKYBuNeALgJQUB86W22ATjUwCuvPNCYALQhAB0AB145gNKLQbMANGMkyITMExotuAXwzGgA" rel="noopener noreferrer"&gt;Typescript playground&lt;/a&gt; to the rescue. But to save a click...&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;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// just stores stuff in "this".&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&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;event&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;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="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;Looking back at the original &lt;code&gt;render&lt;/code&gt; method reading &lt;code&gt;this.onClick&lt;/code&gt; you might notice that a value of &lt;code&gt;this&lt;/code&gt; matters.&lt;/p&gt;




&lt;p&gt;So, let's imagine that &lt;code&gt;this&lt;/code&gt; is always present. What about updating our memoization function a little bit?&lt;br&gt;
What if we store our memoization results variable &lt;strong&gt;inside context&lt;/strong&gt;, so we could have as many memoized results as we need?&lt;br&gt;
Let’s do something very straightforward (and quite similar to the legacy React Context)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="p"&gt;function memoizeCalculation(functionToMemoize) {
&lt;/span&gt;&lt;span class="gd"&gt;-   let storedValue;
-   let storedArgument;
&lt;/span&gt;   return function memoizedCalculation(arg) {
       // is the arg equal to the known one?
&lt;span class="gi"&gt;+      // let's store data not in the "function context"
+      // but the "execution context". 🤷‍♂️ why not? 
+       if(arg === this.storedArgument) {
+         return this.storedValue;
&lt;/span&gt;       }
&lt;span class="err"&gt;
&lt;/span&gt;       // if not - let's calculate new value
&lt;span class="gi"&gt;+       this.storedValue = functionToMemoize();
+       this.storedArgument = arg;
+       return this.storedValue;
&lt;/span&gt;   }
}
&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;Now we have the ability to store &lt;strong&gt;more than one&lt;/strong&gt; result because we store it in &lt;strong&gt;different contexts&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="nx"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will memoize&lt;/span&gt;
&lt;span class="nx"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will memoize SEPARATELY&lt;/span&gt;
&lt;span class="nx"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will reuse memoization&lt;/span&gt;
&lt;span class="nx"&gt;myFunction&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;storedValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;return this&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;storedArgument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;args1&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;arg1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will BYPASS 🙀 memoization&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That would work, but would also create the same problem Legacy context had - naming conflicts. We used it at the last line above, it's cool, but please dont do that in the real code.&lt;br&gt;
Can we do better? Well absolutely! One line will do the magic!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="p"&gt;function memoizeCalculation(functionToMemoize) {
&lt;/span&gt;&lt;span class="gi"&gt;+   // a magic place for our data
+   const storeSymbol = Symbol();
&lt;/span&gt;   return function memoizedCalculation(arg) {
       // is the arg equal to the known one?
&lt;span class="gi"&gt;+       if(arg === this[storeSymbol]?.storedArgument) {
+         return this[storeSymbol]?.storedValue;
&lt;/span&gt;       }
&lt;span class="err"&gt;
&lt;/span&gt;       // if not - let's calculate new value
&lt;span class="gi"&gt;+       this[storeSymbol] = {   
+         storedValue: functionToMemoize(),
+         storedArgument arg,
+        }
+       return this[storeSymbol]?.storedValue;
&lt;/span&gt;   }
}
&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;That looks great - we created a "magic key" to safely and securely store our data. Many solutions out there use a similar approach.&lt;br&gt;
However, I am still not satisfied because &lt;strong&gt;we penetrate object boundaries&lt;/strong&gt; and store information where we should not.&lt;/p&gt;

&lt;p&gt;Could we do better?&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 3 - The Better Place
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🎉 this is the chapter where &lt;strong&gt;weak memoization&lt;/strong&gt; starts!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the example above we were using &lt;code&gt;this&lt;/code&gt; to store &lt;code&gt;information&lt;/code&gt;. We were storing this information directly inside &lt;code&gt;this&lt;/code&gt;, but the task was always about &lt;strong&gt;tracking relations&lt;/strong&gt;, nothing else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;information&lt;/code&gt; is related to &lt;code&gt;this&lt;/code&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;this[key]=information&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;this[information]="related&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every time you encounter such a situation ask yourself - is there a better primitive to handle the job? In database terms, it could be a separate table storing relations, not another field on the &lt;code&gt;thisTable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And indeed there is one primitive we could use here - &lt;code&gt;Map&lt;/code&gt;, or to match our use case a &lt;code&gt;WeakMap&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;WeakMap&lt;/code&gt; will hold information about &lt;code&gt;A-&amp;gt;B&lt;/code&gt; and automatically remove the record when A ceases to exist. &lt;br&gt;
Semantically &lt;code&gt;map.set(A,B)&lt;/code&gt; is equal to &lt;code&gt;A[B]=true&lt;/code&gt;, but without &lt;em&gt;hurting&lt;/em&gt; A&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is how our updates memoization will look like&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="p"&gt;function memoizeCalculation(functionToMemoize) {
&lt;/span&gt;&lt;span class="gi"&gt;+   // a magic store
+   const store = new WeakMap();
&lt;/span&gt;   return function memoizedCalculation(arg) {
       // is the arg equal to the known one?
&lt;span class="gi"&gt;+      const {storedArgument, storedValue} = store.get(this);
+       if(arg === storedArgument) {
+         return storedValue;
&lt;/span&gt;       }
&lt;span class="err"&gt;
&lt;/span&gt;       // if not - let's calculate new value
&lt;span class="gi"&gt;+      const storedValue = functionToMemoize();
+      // we do not "write into this", we "associate" data
+      store.set(this, {   
+         storedValue: functionToMemoize(),
+         storedArgument arg,
+        });
+       return storedValue;
&lt;/span&gt;   }
}
&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;Now we store information related to &lt;code&gt;this&lt;/code&gt; and &lt;code&gt;functionToMemoize&lt;/code&gt; in &lt;em&gt;some other place&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;But the presence of &lt;code&gt;context&lt;/code&gt; was an assumption, in reality is usually absent.&lt;br&gt;
How we can change this approach to get at least some benefits from the given approach without relaying on &lt;code&gt;this&lt;/code&gt; presence?&lt;/p&gt;

&lt;p&gt;🤷‍♂️ Easy, just introduce another variable.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;// "master default"
&lt;span class="gi"&gt;+ let GLOBAL_CONTEXT = {};
&lt;/span&gt;&lt;span class="p"&gt;function memoizeCalculation(functionToMemoize) {
&lt;/span&gt;   // a magic store
   const store = new WeakMap();
   return function memoizedCalculation(arg) {
&lt;span class="gi"&gt;+      const context = this || GLOBAL_CONTEXT;
&lt;/span&gt;       // is the arg equal to the known one?
&lt;span class="gi"&gt;+      const {storedArgument, storedValue} = store.get(context);
&lt;/span&gt;&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;And we can do another another step forward&lt;br&gt;
What about automatic cleanup for all functions to ease testing (and help catching memory leaks). &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;let&lt;/span&gt; &lt;span class="nx"&gt;GLOBAL_CONTEXT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="c1"&gt;// instantly invalidates all caches&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;RESET_ALL_CACHES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;GLOBAL_CONTEXT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="o"&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;GET_CONTEXT&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;userDefinedWay&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;memoizedCalculation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GET_CONTEXT&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;So now we actually got this &lt;em&gt;omnipresent&lt;/em&gt; &lt;code&gt;context&lt;/code&gt; and more importantly - we can control the &lt;em&gt;version&lt;/em&gt; of store exposed to the memoization by controlling this &lt;code&gt;GLOBAL_CONTEXT&lt;/code&gt;.&lt;br&gt;
Here we can even start using &lt;a href="https://nodejs.org/api/async_context.html" rel="noopener noreferrer"&gt;Asynchronous context tracking&lt;/a&gt; to have per-tread or per-test memoization separation out of the box.&lt;/p&gt;

&lt;p&gt;And you know... I would only keep it and remove &lt;code&gt;this&lt;/code&gt; we do not really use anymore 😎&lt;/p&gt;

&lt;p&gt;🤑 BONUS: Just update &lt;code&gt;GLOBAL_CONTEXT&lt;/code&gt; - all cache would be invalidated with all previous values garbage collected. Magic 🪄!&lt;/p&gt;

&lt;p&gt;Cool, the code above is actually useful, but &lt;strong&gt;we are still quite far&lt;/strong&gt; from anything useful and anything as good as &lt;code&gt;reselect v5&lt;/code&gt;. Let’s follow to the next level!&lt;/p&gt;

&lt;h2&gt;
  
  
  Level 4 - cascading
&lt;/h2&gt;

&lt;p&gt;Let’s make a little detour here. Reselect5 was not developed from the scratch, it was inspired by &lt;code&gt;React.cache&lt;/code&gt; function, which is not deeply documented and not many developers really understand how it works.&lt;/p&gt;

&lt;p&gt;So let’s check the code! Here is a &lt;a href="https://github.com/facebook/react/blob/f5af92d2c47d1e1f455faf912b1d3221d1038c37/packages/react/src/ReactCacheImpl.js#L57-L65" rel="noopener noreferrer"&gt;link&lt;/a&gt;. And here is the first section of the code&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;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// try to read some "shared" variable, like `GET_CONTEXT` in the above&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dispatcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ReactSharedInternals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;A&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;dispatcher&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// If there is no dispatcher, then we treat this as not being cached.&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;apply&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="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// and get some "fnMap", so alike to our "store"&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fnMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dispatcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCacheForType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createCacheRoot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;And it actually looks very close to the code we just written &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some "omni present" variable - &lt;code&gt;ReactSharedInternals.A&lt;/code&gt; gives us a pointer to the cache store&lt;/li&gt;
&lt;li&gt;and we will "read" and "write" to it&lt;/li&gt;
&lt;li&gt;there could be &lt;strong&gt;more than one&lt;/strong&gt; such context at the same point of time, which is quite valuable for SSR being executed in a parallel&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;React.cache&lt;/code&gt; just stores result in different places for different renders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But there is another important moment in React's implementation related to a "single result" being stored. &lt;code&gt;React.cache&lt;/code&gt; uses &lt;strong&gt;cascade&lt;/strong&gt;. And &lt;a href="https://github.com/reduxjs/reselect/blob/master/src/weakMapMemoize.ts#L192" rel="noopener noreferrer"&gt;Reselect v5&lt;/a&gt; does exactly the same, and &lt;a href="https://github.com/timkendrick/memoize-weak/blob/master/lib/memoize.js#L52" rel="noopener noreferrer"&gt;memoize-weak&lt;/a&gt; does the same and &lt;a href="https://github.com/theKashey/kashe/blob/master/src/weakStorage.ts#L34" rel="noopener noreferrer"&gt;kashe&lt;/a&gt; does the same&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;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;l&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&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="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;arg&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Objects go into a WeakMap&lt;/span&gt;
          &lt;span class="nx"&gt;cacheNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objectCache&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;WeakMap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;objectCache&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;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cacheNode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Primitives go into a regular Map&lt;/span&gt;
          &lt;span class="nx"&gt;cacheNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;primitiveCache&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;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="nx"&gt;primitiveCache&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;arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cacheNode&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;blockquote&gt;
&lt;p&gt;In some implementation &lt;code&gt;null&lt;/code&gt; is rerouted to a &lt;code&gt;const NULL={}&lt;/code&gt; object in order to allow WeakMap usage.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It creates a 🌳Tree-Like structure with nodes being WeakMap or Map, depending on the argument type.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2F2btpow21l1674qni90iu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F2btpow21l1674qni90iu.gif" alt="Red-Black tree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think about the RedBlack tree from above, with black nodes being &lt;code&gt;Map&lt;/code&gt; and red nodes being &lt;code&gt;WeakMap&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One important downside of this approach could be found at &lt;a href="https://github.com/facebook/react/pull/25506" rel="noopener noreferrer"&gt;the original issue&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I use a WeakMap so that objects that can't be reached again get their cache entries garbage collected. Expandos aren't appropriate here because we also can GC the cache itself&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There are unfortunate cases like &lt;code&gt;cachedFn('a', 'b', 'c', 'd', {})&lt;/code&gt; will get its value GC:ed but not the path of maps to it. A smarter implementation could put the weakmaps on the outer side but it has to be more clever to ensure that argument index is preserved. I added some tests to preserve this in case we try this.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the given example first arguments are not weak-mappable, so the &lt;code&gt;cascade&lt;/code&gt; will be &lt;strong&gt;not garbage collected&lt;/strong&gt;, but the values returned by a cached function - will. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unless there is no &lt;em&gt;weakmappable&lt;/em&gt; objects at all&lt;/li&gt;
&lt;li&gt;But everything will be cleaned up once the current rendering ends and the "main symbol" get's removed.&lt;/li&gt;
&lt;li&gt;so that's not an issue&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;🏆 The &lt;code&gt;Cascade&lt;/code&gt; is what made Reselect 5 superior to all previous versions. Now it can store more than one value, because it's not a single local variable, its a tree 🏆 &lt;/p&gt;




&lt;h2&gt;
  
  
  Level up - an extra ability
&lt;/h2&gt;

&lt;p&gt;As long as we are using React as an example - there is one more feature connecting the dots between something we talked about - &lt;a href="https://react.dev/reference/react/experimental_taintObjectReference" rel="noopener noreferrer"&gt;Taint API&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;taintObjectReference lets you prevent a specific object instance from being passed to a Client Component like a user object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;How does it work? Exactly like the "relations" from above (&lt;a href="https://github.com/facebook/react/pull/27445/files#diff-ee5a976890ff41ff3143b55970e3b5543815a0d18dbc99c2ff053c5480479a06R17" rel="noopener noreferrer"&gt;link to sources&lt;/a&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TaintRegistryObjects&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;WeakMap&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;taintObjectReference&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;object&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="c1"&gt;// here it goes&lt;/span&gt;
  &lt;span class="nx"&gt;TaintRegistryObjects&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;object&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;/// ...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tainted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TaintRegistryObjects&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="nx"&gt;value&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;tainted&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;throwTaintViolation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tainted&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;WeakMaps establishing relations and is helping with so many things.&lt;/p&gt;




&lt;h2&gt;
  
  
  So here it is
&lt;/h2&gt;

&lt;p&gt;I hope you enjoyed this journey, and this &lt;em&gt;evolution&lt;/em&gt; of concepts helped you better understand how things are connected and how different primitives can help you.&lt;/p&gt;

&lt;p&gt;Go use this new knowledge!&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick recap
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;every program need to store variables &lt;em&gt;somewhere&lt;/em&gt;. Usually you don't control this moment, but sometimes you do&lt;/li&gt;
&lt;li&gt;by controlling where values are stored you can create many different things - from weak memoization to react hooks&lt;/li&gt;
&lt;li&gt;there are libraries our there, like the latest generation of reselect, that gives you superpowers to worry less about memoization&lt;/li&gt;
&lt;li&gt;there are still some edge cases where you might need to have a special logic, for example with React separating memoization between different render threads

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/theKashey/kashe" rel="noopener noreferrer"&gt;kashe&lt;/a&gt; provides a little more low level control over it, including supporting nodejs's &lt;a href="https://github.com/theKashey/kashe/blob/master/src/cache-models/async-node-cache.ts" rel="noopener noreferrer"&gt;AsyncLocalStorage for thread separation&lt;/a&gt;. Give it a try.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;PS: And as I've mentioned React, hooks, and stack - &lt;br&gt;
&lt;a href="https://interbolt.org/blog/react-use-selector-optimization" rel="noopener noreferrer"&gt;The future of React.use and React.useMemo&lt;/a&gt; points at the interesting discussion that could be totally understood differently once &lt;code&gt;hooks&lt;/code&gt; using &lt;code&gt;fiber&lt;/code&gt; as a "single stack" model will start using something more like closures, ie independent context.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>web</category>
      <category>state</category>
    </item>
    <item>
      <title>Partial: how NOT to mock the whole world</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Thu, 08 Feb 2024 03:31:12 +0000</pubDate>
      <link>https://dev.to/thekashey/partial-how-not-to-mock-the-whole-world-32pj</link>
      <guid>https://dev.to/thekashey/partial-how-not-to-mock-the-whole-world-32pj</guid>
      <description>&lt;p&gt;Mocking is a very controversial concept in testing - some thought leaders advocate it as something "bad"😤, while others have to use mocks🙃 one way or another.&lt;br&gt;
No matter what we think about it - mocks are around.&lt;/p&gt;

&lt;p&gt;However, mocks can be different &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;they could be &lt;code&gt;network mocks&lt;/code&gt; (use &lt;a href="https://mswjs.io/" rel="noopener noreferrer"&gt;msw&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;or they could be &lt;code&gt;state mock&lt;/code&gt; injected by &lt;code&gt;jest.mock&lt;/code&gt; or any other force (I would recommend &lt;a href="https://github.com/albertogasparin/react-magnetic-di/tree/master" rel="noopener noreferrer"&gt;magnetic-di&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But in all cases, there is &lt;strong&gt;a hill to die on&lt;/strong&gt; - are you going to &lt;strong&gt;mock the entire universe 🛸&lt;/strong&gt; or just &lt;strong&gt;a little&lt;/strong&gt; bit?&lt;/p&gt;

&lt;p&gt;Let's start with the 🪐 entire universe&lt;/p&gt;

&lt;h1&gt;
  
  
  Jest.mock
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;jest.mock&lt;/code&gt;(or &lt;code&gt;vi.mock&lt;/code&gt;) is a good example of "everything" - this helper mocks the entire module providing "empty stubs" for the original content.&lt;/p&gt;

&lt;p&gt;Imagine a use case&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// index.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;getConfiguration&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;./config&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;isAdmin&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;getConfiguration&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;isAdmin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// index.spec.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;getConfiguration&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;./config&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;isAdmin&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;./&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isAdmin&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ??? 🤷‍♂️&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isAdmin&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;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;To make this test run you need to specify the correct mock override for &lt;code&gt;getConfiguration&lt;/code&gt;. Can you do it?&lt;/p&gt;

&lt;p&gt;Let's try&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

  &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// 50 different fields&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
     &lt;span class="c1"&gt;// 20 other fields,&lt;/span&gt;
     &lt;span class="na"&gt;isAdmin&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So you can, but you have to specify the "whole world", or typescript will not be happy.&lt;/p&gt;

&lt;p&gt;You will not like it as well 🤮&lt;/p&gt;

&lt;h2&gt;
  
  
  What about defaults?
&lt;/h2&gt;

&lt;p&gt;A better way to manage mocks is by providing defaults one can "extend" from&lt;/p&gt;

&lt;p&gt;For example&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;defaultConfiguration&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;./configuration-test-utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="nx"&gt;defaultConfiguration&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="na"&gt;isAdmin&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That would greatly simplify life and establish an environment easier to maintain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;However it is still about mocking the whole world, while &lt;strong&gt;you need only one field&lt;/strong&gt; 😭&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Only one!
&lt;/h2&gt;

&lt;p&gt;In out case we dont need to mock everything, it's more about TypeScript being too type-safe. Let's stop this!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&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="na"&gt;isAdmin&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="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="cm"&gt;/* 😘 */&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// test passes ✅&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Well, &lt;code&gt;as any&lt;/code&gt; is not the best idea. Here is where &lt;code&gt;DeepPartial&lt;/code&gt; helps&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Partial&lt;/code&gt; is a TypeScript helper making keys of an object non-required. &lt;code&gt;DeepPartial&lt;/code&gt; is just a recursive helper for it. It has many implementations, &lt;a href="https://github.com/albertogasparin/react-magnetic-di/blob/master/types/index.d.ts#L10" rel="noopener noreferrer"&gt;here is one&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This gives us the ability to write code like&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&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="na"&gt;isAdmin&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="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;DeepPartial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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;getConfiguration&lt;/span&gt;&lt;span class="o"&gt;&amp;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;Yeah, the last line is 🤮 and one can improve it with utilities like &lt;a href="https://github.com/total-typescript/shoehorn" rel="noopener noreferrer"&gt;shoehorn&lt;/a&gt; hiding all complexity underneath.&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;fromPartial&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="s2"&gt;@total-typescript/shoehorn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fromPartial&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="na"&gt;isAdmin&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Better? Better!&lt;/p&gt;

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

&lt;p&gt;However, what would happen if &lt;strong&gt;we change our code&lt;/strong&gt;? You know - code always drifting somewhere...&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isAdmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;getConfiguration&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;isAdmin&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
  &lt;span class="nf"&gt;getConfiguration&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;isSuperAdmin&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;No tests will notice the difference, but our &lt;em&gt;partial&lt;/em&gt; mock is no longer the correct one for our use case.&lt;/p&gt;

&lt;p&gt;We need something better.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“actually better” is to &lt;strong&gt;refactor the code&lt;/strong&gt; in a way you dont need to mock everything, but we are trying to complete the task without changing the game rules as not everybody can afford refactoring and not everybody want to make their test more testable for the sake or abstract testability (aka &lt;em&gt;test induced design damage&lt;/em&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Something better
&lt;/h1&gt;

&lt;p&gt;Let's change our test a little bit&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// index.spec.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;partialMock&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;partial-mock&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&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;getConfiguration&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;./config&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;isAdmin&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;./&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;isAdmin&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ⬇️⬇️&lt;/span&gt;
  &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mocked&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;getConfiguration&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;mockReturnValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;partialMock&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="na"&gt;isAdmin&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isAdmin&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;span class="c1"&gt;// but instead it will throw &lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Here we used &lt;code&gt;partialMock&lt;/code&gt; utility to apply &lt;code&gt;DeepPartial&lt;/code&gt;(but &lt;code&gt;shoehorn&lt;/code&gt; can do it), but also &lt;strong&gt;break test&lt;/strong&gt; because the provided mock no longer represents the case.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reproducible example - &lt;a href="https://codesandbox.io/p/sandbox/partial-mock-example-8vr77s?file=%2Fsrc%2Findex.ts%3A21%2C20" rel="noopener noreferrer"&gt;https://codesandbox.io/p/sandbox/partial-mock-example-8vr77s?file=%2Fsrc%2Findex.ts%3A21%2C20&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fuf663j7i9f99ac4bs1io.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fuf663j7i9f99ac4bs1io.png" alt="Failure example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What about "over mocking"?
&lt;/h2&gt;

&lt;p&gt;Imagine the opposite situation - something complex becomes simpler, but your mocks are still &lt;em&gt;too much&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For example, imagine we do define &lt;code&gt;isSuperAdmin&lt;/code&gt; missing in the example above, but we will no longer use it&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="nx"&gt;mock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;partialMock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Data&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;isAdmin&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;isSuperAdmin&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="nf"&gt;expectNoUnusedKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Sandbox - &lt;a href="https://codesandbox.io/p/sandbox/overmocking-partial-mock-example-z8qd5w?file=%2Fsrc%2Findex.ts%3A22%2C1" rel="noopener noreferrer"&gt;https://codesandbox.io/p/sandbox/overmocking-partial-mock-example-z8qd5w?file=%2Fsrc%2Findex.ts%3A22%2C1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Frpwfu84yxgvv12vv5i1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Frpwfu84yxgvv12vv5i1x.png" alt="unused keys"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  That's it, folks
&lt;/h1&gt;

&lt;p&gt;That's it - &lt;a href="https://github.com/theKashey/partial-mock" rel="noopener noreferrer"&gt;partial mock&lt;/a&gt; helps with the &lt;em&gt;"over-mocking"&lt;/em&gt;, situations where you mock too much, and it also solves problems with the &lt;em&gt;"under-mocking"&lt;/em&gt; where you missing some important pieces.&lt;/p&gt;

&lt;p&gt;Pretty sure you never though about under-mocking. Until now.&lt;/p&gt;

&lt;p&gt;Link to follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/theKashey/partial-mock" rel="noopener noreferrer"&gt;https://github.com/theKashey/partial-mock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/total-typescript/shoehorn" rel="noopener noreferrer"&gt;https://github.com/total-typescript/shoehorn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/albertogasparin/react-magnetic-di" rel="noopener noreferrer"&gt;https://github.com/albertogasparin/react-magnetic-di&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>mocking</category>
      <category>testing</category>
    </item>
    <item>
      <title>🧶YarnLocking🔓 your dependencies</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Sun, 09 Oct 2022 04:13:02 +0000</pubDate>
      <link>https://dev.to/thekashey/yarnlocking-your-dependencies-59n0</link>
      <guid>https://dev.to/thekashey/yarnlocking-your-dependencies-59n0</guid>
      <description>&lt;p&gt;Hey mate 👋. Have you seen a &lt;code&gt;yarn.lock&lt;/code&gt; file? It can be &lt;code&gt;package-lock.json&lt;/code&gt;, &lt;code&gt;pnpm.lock&lt;/code&gt; or &lt;code&gt;npm-shrinkwrap&lt;/code&gt;, it does not matter that much. What matters - this file have a purpose.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;package-lock.json is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.&lt;br&gt;
 – &lt;a href="https://docs.npmjs.com/cli/v8/configuring-npm/package-lock-json" rel="noopener noreferrer"&gt;A manifestation of the manifest&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short - lock files represents and store information about dependencies other than your direct ones, and particular version of such indirect dependency to use.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1573750424581963776-129" src="https://platform.twitter.com/embed/Tweet.html?id=1573750424581963776"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1573750424581963776-129');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1573750424581963776&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;There is no time to explain everything in the details, let me show you the problem. &lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 1 - understanding the problem
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lets create an issue
&lt;/h3&gt;

&lt;p&gt;Many of us used lock files for years and used them without any troubles. Everything seems good, but there is one nuance we need to discover. A little feature we are going to reveal. Let's run an experiment. &lt;br&gt;
&lt;em&gt;I will use &lt;code&gt;yarn&lt;/code&gt; to demonstration purposes&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The experiment itself is for &lt;em&gt;demonstration purposes&lt;/em&gt; only. Just blindly follow the steps or magic might not happen&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;. Create empty repository. 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yarn init&lt;/code&gt; and "install" it - &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;you should get an empty &lt;code&gt;yarn.lock&lt;/code&gt; file and empty &lt;code&gt;node_modules&lt;/code&gt; folder&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;. Let's add first dependency. Let it be &lt;code&gt;tslib@2.0.3&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yarn add tslib@2.0.3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;that would create a record in &lt;code&gt;yarn.lock&lt;/code&gt; like
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tslib@2.0.3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;version "2.0.3"&lt;/span&gt;
  &lt;span class="s"&gt;resolved "https://something-something/tslib-2.0.3.tgz"&lt;/span&gt;
  &lt;span class="s"&gt;integrity sha512-long-and-ugly==&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;. Let's massage our environment and &lt;strong&gt;manually&lt;/strong&gt; amend &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;yarn.lock&lt;/code&gt; to use &lt;code&gt;tslib:^2.0.3&lt;/code&gt; 

&lt;ul&gt;
&lt;li&gt;in &lt;code&gt;package.json&lt;/code&gt;: &lt;code&gt;"tslib": "^2.0.3"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;in &lt;code&gt;yarn.lock&lt;/code&gt;: &lt;code&gt;tslib@^2.0.3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;then run &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;⚠️ it is important to have the following record in &lt;code&gt;yarn.lock&lt;/code&gt;, which means "&lt;a href="mailto:tslib@2.0.3"&gt;tslib@2.0.3&lt;/a&gt; used for tslib:^2.0.3" 

&lt;ul&gt;
&lt;li&gt;🤔 the same will happen if 2.0.3 is the latest version available. Well, it's not the latest &lt;em&gt;now&lt;/em&gt;, but was in the past&lt;/li&gt;
&lt;li&gt;💡 please &lt;strong&gt;remember&lt;/strong&gt; this moment as a &lt;code&gt;direct edit&lt;/code&gt; of the lock file
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tslib@^2.0.3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;version "2.0.3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 4&lt;/strong&gt;. Add another &lt;strong&gt;dependency depending&lt;/strong&gt; on &lt;code&gt;tslib&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yarn add focus-lock&lt;/code&gt; (v0.11.2). This package depends &lt;code&gt;tslib:^2.0.3&lt;/code&gt;😉. Perfect match.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  let's verify - our &lt;code&gt;yarn.lock&lt;/code&gt; should contain &lt;strong&gt;only two dependencies&lt;/strong&gt; - &lt;code&gt;focus-lock&lt;/code&gt; and &lt;code&gt;tslib&lt;/code&gt;
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;So &lt;strong&gt;that's it&lt;/strong&gt;. We have created a problem 😎. You don't see it? Yep, the real issue is that nobody sees this problem. But it's already here.&lt;/p&gt;

&lt;p&gt;The problem is - we have two dependencies "perfectly" matching each other.&lt;/p&gt;
&lt;h3&gt;
  
  
  Is it a problem?
&lt;/h3&gt;

&lt;p&gt;😉 Let's perform one more experiment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1&lt;/strong&gt;: remove &lt;code&gt;tslib&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;yarn remove tslib&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2&lt;/strong&gt;: check your &lt;code&gt;yarn.lock&lt;/code&gt;, and it will be &lt;strong&gt;unchanged&lt;/strong&gt;, as tslib is still used by &lt;code&gt;focus-lock&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3&lt;/strong&gt;: shrug 🤷‍♂️&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 4&lt;/strong&gt;: remove &lt;code&gt;yarn.lock&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;rm ./yarn.lock&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 5&lt;/strong&gt;: reinstall packages

&lt;ul&gt;
&lt;li&gt;run &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now check your lock file 😉. It will contain the same &lt;code&gt;tslib:^2.0.3&lt;/code&gt;, but this time it will be &lt;strong&gt;resolved to 2.4.0&lt;/strong&gt; (the last version available by the time of writing this article)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;tslib@^2.0.3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;version "2.4.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might not get the joke, let me rephrase it&lt;/p&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  😳 Existing dependencies and the order of their addition affects the shape of the end artefact 😬
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;In the first experiment focus-lock &lt;em&gt;reused&lt;/em&gt; preexisting &lt;code&gt;tslib&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the second one there will no such constrain and it used the "freshest" one.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read it another way - any &lt;em&gt;new&lt;/em&gt; dependency you will try reuse what you already have. Any dependency you update will try to reuse what you already have. Your's legacy, your's past, your's yesterday affects your tomorrow.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As an example - nextjs installed today and &lt;strong&gt;the same version&lt;/strong&gt; of nextjs installed tomorrow can have at least different version of &lt;code&gt;caniuse&lt;/code&gt;, as it released on a daily schedule.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But that is just a half of the problem. The real one - you can still have &lt;em&gt;unexpectedly obsolete&lt;/em&gt; packages and hear me out - &lt;code&gt;focus-lock&lt;/code&gt; by itself is using and is being tested with &lt;code&gt;tslib 2.3.1&lt;/code&gt;, declaring a version below as a dependency because "it does not need any newer". Or needs, but have no idea about it, because cannot test itself agains other versions of own dependencies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yep, this is exactly how I broke someone one's project - &lt;a href="https://github.com/theKashey/react-remove-scroll/pull/70" rel="noopener noreferrer"&gt;import error: '__spreadArray' is not exported from 'tslib'&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Another example maybe?
&lt;/h3&gt;

&lt;p&gt;The example above was a little synthetic. Ok, VERY synthetic.  Frankly speaking it took a while for me to find a way of reproducing such behaviour in a short and sound way, as &lt;em&gt;usually&lt;/em&gt; everything was working well. Without &lt;code&gt;direct edit&lt;/code&gt; hack, the one I've asked you to remember, issue will be not created.&lt;br&gt;
But what would be different?&lt;/p&gt;

&lt;p&gt;Let's redo everything from scratch, but skip the hack. Depending on particular actions and events it can result in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;tslib@^2.0.3, tslib@^2.4.0&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;version "2.4.0"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or &lt;strong&gt;TWO&lt;/strong&gt; versions of &lt;code&gt;tslib&lt;/code&gt;, which can be &lt;em&gt;collapsed&lt;/em&gt; into one via &lt;strong&gt;deduplication&lt;/strong&gt; and there is &lt;a href="https://medium.com/@bnaya/yarn-deduplicate-the-hero-we-need-f4497a362128" rel="noopener noreferrer"&gt;another story about&lt;/a&gt; it.&lt;/p&gt;

&lt;p&gt;Our problem is a part of duplication one. About the same version fragmentation and bloating node_modules with, but more often without a reason. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You might have already A LOT of duplications in your lock file - try to dedupe them if you never tried and tell me the results. At least check how many &lt;code&gt;tslib&lt;/code&gt;s you've got.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PS: deduplication is available for any package manager, as a built-in or as a separate package. Just google.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1569409158163865601-187" src="https://platform.twitter.com/embed/Tweet.html?id=1569409158163865601"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1569409158163865601-187');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1569409158163865601&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  A real life example?
&lt;/h3&gt;

&lt;p&gt;🤔 probably the last example was also now quite sound. Let's create something better. Something that has bitten me personally multiple times.&lt;/p&gt;

&lt;p&gt;Let's talk about a real stuff, about consuming &lt;em&gt;intertwined&lt;/em&gt; packages.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;1️⃣ &lt;code&gt;cool-widget&lt;/code&gt; uses &lt;code&gt;cool-form&lt;/code&gt; uses &lt;code&gt;cool-button&lt;/code&gt; (and other packages) &lt;br&gt;
2️⃣ &lt;code&gt;cool-widget&lt;/code&gt; uses &lt;code&gt;cool-button&lt;/code&gt; as well 😎&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fb215puko4y4l0qin5okp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fb215puko4y4l0qin5okp.png" alt="Modal Form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again - this case is not applicable to simple projects. This case is not very applicable to monorepos. &lt;br&gt;
This case requires a presence of some &lt;em&gt;flexibility&lt;/em&gt; and a non-zero &lt;em&gt;distance&lt;/em&gt; between package. It needs a lag, it needs a gap, it needs a latency.&lt;/p&gt;
&lt;h2&gt;
  
  
  This case needs one repo consuming another to have a &lt;strong&gt;gap&lt;/strong&gt; in the &lt;em&gt;npm logistic layer&lt;/em&gt; in between
&lt;/h2&gt;

&lt;p&gt;Let's create a &lt;em&gt;supply chain disruption&lt;/em&gt; ⬇️&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1️⃣ Imagine you have a &lt;code&gt;Button&lt;/code&gt;. Just a &lt;code&gt;button&lt;/code&gt; exported as a npm package - &lt;code&gt;cool-button&lt;/code&gt;. Every UIKit has such primitive.&lt;/li&gt;
&lt;li&gt;2️⃣ and then you use that &lt;code&gt;cool-button&lt;/code&gt; in many other   packages. For example in &lt;code&gt;cool-form&lt;/code&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;code&gt;cool-widget&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;3️⃣ and &lt;code&gt;cool-widget&lt;/code&gt; uses &lt;code&gt;cool-form&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;It is a big organism consuming other molecules(form) &lt;strong&gt;and atoms&lt;/strong&gt; (button).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;➡️ And then you introduce a new major version of your very &lt;code&gt;cool-button&lt;/code&gt; 🙀.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The tricky part here is how "major version update" &lt;em&gt;propagates&lt;/em&gt; through packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cool-button&lt;/code&gt; should have get a major version bump due to public interface change&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cool-form&lt;/code&gt; might got a patch update, as nothing changes for it's public interface. Button is implementation details and is not affecting look-n-feel of a form&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cool-widget&lt;/code&gt; actually does not &lt;em&gt;have&lt;/em&gt; to do anything....
or haven't updated all required dependencies &lt;em&gt;yet&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;Our &lt;code&gt;cool-widget&lt;/code&gt; might be patch-updated, as it does not change public interface, just internals, and &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it may use a new version of a &lt;code&gt;cool-button&lt;/code&gt;, because some renovate-bot (or a button's developer) updated it in all consumers.&lt;/li&gt;
&lt;li&gt;depend on a &lt;code&gt;cool-form&lt;/code&gt;, which also was just updated to use a new button, but... 😉 there is no reason for &lt;code&gt;cool-widget&lt;/code&gt; to update dependency on &lt;code&gt;cool-form&lt;/code&gt; as nothing actually was changed. It's the same &lt;code&gt;cool-form&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;In other words - dependency `cool-form` will be kept as is
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;What 😕? How so? Why not updated? &lt;/p&gt;

&lt;p&gt;Let's stop here and check if cool-widget have to react and incorporate every single move of every single piece. Any reason?&lt;/p&gt;

&lt;p&gt;🤷‍♂️ Why someone should be bothered to bump every &lt;code&gt;dependency&lt;/code&gt; in package.json every time every &lt;code&gt;dependency&lt;/code&gt;, a little spare part of a bigger whole, updates? It could be ten times a day for ten packages, and it sounds like a lot of useless work! Especially some work is required to perform update, run test, verify the result, deploy the result. Oh&lt;/p&gt;

&lt;p&gt;Ok, ok. Let's imagine you are fine with it, You want it. So a &lt;code&gt;button&lt;/code&gt; update will cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1️⃣ a cascade update of ALL packages depending on it, &lt;/li&gt;
&lt;li&gt;2️⃣ and then of all packages depending on just changed &lt;/li&gt;
&lt;li&gt;3️⃣ and then of all packages depending on just changed&lt;/li&gt;
&lt;li&gt;4️⃣ and then of all packages depending on just changed&lt;/li&gt;
&lt;li&gt;5️⃣ should I stop here?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It actually can be a loop - &lt;em&gt;sometimes&lt;/em&gt; packages might depends on previous versions of themselves. Like &lt;code&gt;babel&lt;/code&gt; uses &lt;code&gt;babel&lt;/code&gt; to compile self.&lt;br&gt;
So 😕 I really hope you don't want that. You probably do update in batches, or not really doing it at all, and that's ok - if stuff does work, just don't touch it.&lt;/p&gt;



&lt;p&gt;Long story short - &lt;code&gt;cool-widget&lt;/code&gt; have got a new &lt;code&gt;cool-button@v2&lt;/code&gt; directly updated, but still have the old &lt;code&gt;cool-button@v1&lt;/code&gt; from the &lt;em&gt;kept-as-is&lt;/em&gt; &lt;code&gt;cool-form&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  So now we have two buttons, with different major versions, and this cannot be &lt;em&gt;deduplicated&lt;/em&gt;.
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.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%2Ffvlfttexer7iijqs6hjs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffvlfttexer7iijqs6hjs.jpg" alt="Ball of yarn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;😠: &lt;em&gt;"HEY! Wait a minute. I've got you and I am promising to be a good lad and keep my deep dependencies up to date!"&lt;/em&gt;&lt;br&gt;
😿: &lt;em&gt;"Unfortunately this is not about you, this is __about packages created by someone else&lt;/em&gt;&lt;em&gt;, about the packages you don't control"&lt;/em&gt;&lt;br&gt;
😕: &lt;em&gt;"I dont control?"&lt;/em&gt;&lt;br&gt;
😾: &lt;em&gt;"You don't"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You have got a problem with &lt;strong&gt;stale intermediate dependency&lt;/strong&gt;. A dependency of your dependency which you don't directly control. And a dependency [of your dependency of your dependency]. And a dependency [of your dependency of your dependency of your dependency]. And ....&lt;/p&gt;

&lt;p&gt;And that is &lt;strong&gt;the problem we were chasing&lt;/strong&gt; all this time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;First time this issue was encountered back in 2017 – &lt;a href="https://github.com/yarnpkg/yarn/issues/4986" rel="noopener noreferrer"&gt;Yark: How to upgrade indirect dependencies?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Chapter 2 - Solving the problem
&lt;/h2&gt;

&lt;p&gt;It's an easy job to point a finger on a problem and tell everyone - &lt;em&gt;"People! Here is the problem"&lt;/em&gt;. &lt;br&gt;
It is completely another job to propose a solution.&lt;/p&gt;
&lt;h3&gt;
  
  
  Going back and upgrading
&lt;/h3&gt;

&lt;p&gt;Lets make another step back and look on what you do control - the direct dependencies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you can declare dependencies you need and their versions

&lt;ul&gt;
&lt;li&gt;as their versions might represent a wide range - the particular versions to use will be stored in your &lt;code&gt;lock file&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if by any reason you get a newer version of already existing dep - it will be automatically &lt;em&gt;raised&lt;/em&gt; to the highest one. If not automatically, then after &lt;em&gt;dedupe&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;😅 so by installing a new dep you can change dependencies of your existing? 

&lt;ul&gt;
&lt;li&gt;This is why changes in &lt;code&gt;yarn.lock&lt;/code&gt; might need a review&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;you can manage and especially update those deps.

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;yarn up&lt;/code&gt;, or &lt;code&gt;yarn upgrade-interactive&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;or use a little bit more advanced &lt;a href="https://github.com/raineorshine/npm-check-updates" rel="noopener noreferrer"&gt;npm-check-updates&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;in both cases only &lt;code&gt;package.lock&lt;/code&gt; gonna be changed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how you can control &lt;strong&gt;direct&lt;/strong&gt; dependencies. The ones explicitly declared in your &lt;code&gt;package lock&lt;/code&gt;. You have no control over indirect dependencies totally &lt;em&gt;derived&lt;/em&gt; from requirements of the &lt;em&gt;real ones&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Package managers are trying to preserve as much as possible in order to reduce the impact of the change and amount efforts users might need to perform in order to manage consequences. Known as &lt;strong&gt;Principle of least action&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Package manager's job is to keep things. Our goal is to _loosen some bolts...&lt;/p&gt;

&lt;p&gt;Please welcome...&lt;/p&gt;
&lt;h1&gt;
  
  
  Yarn-unlock-file
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://github.com/theKashey/yarn-unlock-file" rel="noopener noreferrer"&gt;yarn-unlock-file&lt;/a&gt; is a new library, capable of editing your lock file and addressing issues created by indirect dependencies &lt;/p&gt;

&lt;p&gt;The simplest use case is nothing more than&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx yarn-unlock-file all
&lt;span class="c"&gt;# and don't forget to&lt;/span&gt;
yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is it - the command will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔐 keep any of dependencies declared by you&lt;/li&gt;
&lt;li&gt;🔓 "unlock" all indirect ones

&lt;ul&gt;
&lt;li&gt;"unlock" means "delete" old records from &lt;code&gt;yarn.lock&lt;/code&gt; letting the newer, might be more correct versions to be installed&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  What you are dependencies?
&lt;/h3&gt;

&lt;p&gt;There is &lt;strong&gt;one thing we forgot&lt;/strong&gt; – the purpose of package managers. What is &lt;code&gt;yarn&lt;/code&gt;, what is &lt;code&gt;npm&lt;/code&gt; and what they do...&lt;/p&gt;

&lt;p&gt;PackageManagers are primarily managing &lt;code&gt;logistics&lt;/code&gt; - they provide transport layer between &lt;code&gt;npm repository&lt;/code&gt; and your &lt;code&gt;project&lt;/code&gt;.&lt;br&gt;
Then PackageManagers are in charge to recreate the same environment, the same combination of packages across different machines to make our live more &lt;em&gt;predictable&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;However, if you use a library, you probably &lt;em&gt;rely&lt;/em&gt; on it to be tested and behave well, but this is possible &lt;strong&gt;only&lt;/strong&gt; if the library was &lt;em&gt;assembled&lt;/em&gt; in your projects in exactly same way it was built and tested in the place of the origin - it's own space.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So it's important to &lt;em&gt;let free&lt;/em&gt; artificial boundaries preventing the similar environments&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Everything has limits, and a perfect tool capable to capture and &lt;em&gt;freeze&lt;/em&gt; your decisions in time might need a hand.&lt;/p&gt;

&lt;p&gt;No tool should change your decisions and change package versions picked by you, but it might help you manage decisions you haven't made consciously - concrete versions for your indirect dependencies.&lt;/p&gt;

&lt;p&gt;Try commands like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npx yarn-unlock-file dev&lt;/code&gt; to update only devDependencies, or&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npx yarn-unlock-file matching @material-ui/*&lt;/code&gt; to update dependencies of &lt;code&gt;material-ui&lt;/code&gt; &lt;strong&gt;but not&lt;/strong&gt; MUI itself&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Safety first
&lt;/h2&gt;

&lt;p&gt;There is a reasons why we are not just deleting &lt;code&gt;yarn.lock&lt;/code&gt; - the result can be unpredictable. Or it can be "too much" - you will get a broken build or a broken application if your tests are not great in detecting anomalies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One should bumping your dependencies regularly, but it's not always safe and can go unpredictable in large projects.

&lt;ul&gt;
&lt;li&gt;One might update versions in the same range, and "unlocking" is a good way to do that.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;One might still be cautions about updating direct dependencies, or even dependencies of dependencies. But not many layers is there?

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npx yarn-unlock-file levels all&lt;/code&gt; will tell you how much.

&lt;ul&gt;
&lt;li&gt;I haven't seen more than 8. &lt;/li&gt;
&lt;li&gt;I haven't seen less than 3.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;😎 updating dependencies of dependencies of dependencies should be safe

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npx yarn-unlock-file all --min-level 3&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Dry run
&lt;/h4&gt;

&lt;p&gt;Well, why one should blindly trust some tool to delete only what you want. Trust, but verify. Use dry run mode.&lt;br&gt;
&lt;code&gt;npx yarn-unlock-file all --min-level 3 --dry-run&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media.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%2Ffbees0trv1zphzl3qu9y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Ffbees0trv1zphzl3qu9y.png" alt="memoize-one unlock"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The picture above is a good indication of how many layers can be hidden inside a simple solution, &lt;a href="https://github.com/alexreardon/memoize-one" rel="noopener noreferrer"&gt;memoize-one&lt;/a&gt; in this case.&lt;/p&gt;

&lt;p&gt;One might ask the question - why level 8 dependency &lt;code&gt;is-arraysh&lt;/code&gt; is here, and what causes it?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lets ask: &lt;code&gt;yarn why is-arrayish&lt;/code&gt;
&amp;gt; nyc#test-exclude#read-pkg-up#read-pkg#load-json-file#parse-json#error-ex#is-arrayish&lt;/li&gt;
&lt;li&gt;let's update only this branch: &lt;code&gt;npx yarn-unlock-file matching nyc --dry-run&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.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%2F41wp9uwvfak6qes2ehlr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2F41wp9uwvfak6qes2ehlr.png" alt="remove nyc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1️⃣ look 2️⃣ pick &lt;code&gt;min-level&lt;/code&gt; you are comfortable with 3️⃣ wipe&lt;/p&gt;
&lt;h4&gt;
  
  
  Note about Npm-check-Updates
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://github.com/raineorshine/npm-check-updates#doctor-mode" rel="noopener noreferrer"&gt;ncu has a "doctor" mode&lt;/a&gt; to update dependency, run tests, and only then update another dependency.&lt;br&gt;
While this works just great - it actually can &lt;em&gt;tangle&lt;/em&gt; your lock file beyond imagination because packages you install today affects the shape of package you install tomorrow 😉&lt;/p&gt;

&lt;p&gt;Having more control over this process is quite beneficial.&lt;/p&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For years I was giving an advice of &lt;em&gt;"just find something in your lock file and delete"&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For years I was looking into &lt;code&gt;yarn.lock&lt;/code&gt; updates to correct result of deduplication sometimes by selecting a few hundred of lines to &lt;em&gt;delete and regenerate&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🤷‍♂️ enough is enough. It's time to understand that deterministic builds is one problem, but &lt;em&gt;supply chain disruption&lt;/em&gt; is different. &lt;/p&gt;



&lt;p&gt;Authors of packages and tools you use &lt;em&gt;expect and test&lt;/em&gt; their creations  using some know (to them) set of other packages and tools, which are in turn rely on some other set of libraries. Any dependency specified within an accepted "range", and most of them are, is a subject for version mismatch. Or an &lt;em&gt;expectation&lt;/em&gt; that the end consumers will use a new patch version of a tiny library with something very important fixed.&lt;/p&gt;

&lt;p&gt;There are dependencies you know, the ones you want to use.&lt;br&gt;
Everything else has to be unlocked on a weekly basic.&lt;/p&gt;

&lt;p&gt;You can use Renovate, Dependabot or &lt;code&gt;npm-check-updates&lt;/code&gt;&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1569310121880350722-730" src="https://platform.twitter.com/embed/Tweet.html?id=1569310121880350722"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1569310121880350722-730');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1569310121880350722&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;But it's not enough&lt;br&gt;
&lt;a href="https://github.com/theKashey/yarn-unlock-file" rel="noopener noreferrer"&gt;https://github.com/theKashey/yarn-unlock-file&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PS: Did you know that &lt;code&gt;dependabot&lt;/code&gt; can update dependencies in your lock.file? Like &lt;a href="https://github.com/theKashey/react-focus-lock/pull/223" rel="noopener noreferrer"&gt;here it bumps terser&lt;/a&gt; changing only lock file, because it's an indirect dependency.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  So what?
&lt;/h1&gt;

&lt;p&gt;Just try it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx yarn-unlock-file dev
yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we will see 😈&lt;/p&gt;

&lt;p&gt;💡: this is a first, partially experimental solution, currently capable to handle only yarn(v1 and v3).&lt;/p&gt;

</description>
      <category>yarn</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>UI? Piece a Cake</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Sun, 31 Oct 2021 08:17:41 +0000</pubDate>
      <link>https://dev.to/thekashey/ui-piece-a-cake-1anb</link>
      <guid>https://dev.to/thekashey/ui-piece-a-cake-1anb</guid>
      <description>&lt;p&gt;One of the first &lt;code&gt;false assumptions&lt;/code&gt; one could face during a long journey of becoming a developer, is that said journey is just about development, about you just writing some code. &lt;br&gt;
Like - start a new project by writing code, and finish it in the same way. &lt;br&gt;
Only later one will be told about testing, or the need to solve real customer problems, and other "business as usual" stuff, not sure which one came first. &lt;br&gt;
It's fine to start your journey in this way, everything needs a beginning, but this is not how it should continue.&lt;/p&gt;

&lt;p&gt;This is not how it could succeed.&lt;/p&gt;

&lt;p&gt;Our job is not about writing code, it's about writing the right code, writing it "Once and only Once",  testing it, solving problems and finishing assigned tasks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;It's not about creating &amp;gt;new&amp;lt; things, 
but more usually about changing the &amp;gt;old&amp;lt; ones.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Software engineering is programming over time. Engineering is about considering the long-term effects of your code. Both direct and indirect. &lt;a href="https://swizec.com/blog/what-i-learned-from-software-engineering-at-google/"&gt;Link&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read it this way - while moving forward think hard about what you are leaving behind and what you need to make the next step.&lt;br&gt;
💡 Applicable to your life as well.&lt;/p&gt;

&lt;p&gt;While the vast majority of information you can find out there is focused on how to "make" things, let's talk about future maintenance, about reducing different burdens - from the classical &lt;code&gt;technical debt&lt;/code&gt; to &lt;code&gt;cognitive load&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's talk about the multidimensional "Cake" approach, also known as &lt;a href="https://en.wikipedia.org/wiki/Multitier_architecture"&gt;Multitier architecture&lt;/a&gt;, also known as Onion Architecture, and how it applies to UI-based applications.&lt;/p&gt;
&lt;h1&gt;
  
  
  Where is the Problem?
&lt;/h1&gt;

&lt;p&gt;The problem is not only "where", the problem is also "when".&lt;/p&gt;

&lt;p&gt;Let's imagine that you are working on a very agile project, of course you are, and you just bootstrapped a new application that already has experienced two pivots and going to have another one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The essence of Agile is about being reactive to the changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is absolutely ok to start a random redesign, it's absolutely ok to abandon an almost complete feature and start redoing it in a little different way, it's ok to adapt for the new requirements and the only thing a developer should be focused on this point - be able to &lt;strong&gt;preserve as much as possible&lt;/strong&gt;, about how NOT to start every time from the scratch. That happens to all of us but is not any efficient.&lt;/p&gt;

&lt;p&gt;While the majority might understand the solution for a "Happy Live" as &lt;a href="https://blog.codinghorror.com/falling-into-the-pit-of-success/"&gt;Pit of Success&lt;/a&gt;, where &lt;em&gt;a well-designed system makes it easy to do the right things and annoying (but not impossible) to do the wrong things&lt;/em&gt;, it's still about &lt;em&gt;making&lt;/em&gt; things(note "do the right thing"), not &lt;em&gt;changing&lt;/em&gt; something existing, even something created yesterday (we "agile", right 🙄?).&lt;br&gt;
I reckon the Solution for the &lt;em&gt;change&lt;/em&gt; might have roots in the &lt;a href="https://en.wikipedia.org/wiki/Chaos_engineering"&gt;Chaos Engineering&lt;/a&gt;, where you have to accept that something will go wrong, a build a system resilient to it. While the essence of this philosophy is something you should always have in mind, there is another way to address the same problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Chaos? This is what happens during(before or instead of) the family Christmas dinner, meetup and especially during the Gala Concert - too many things are happening at once and everybody is just running around screaming. In all cases, the path to success is to have some protocols, procedures and preparation. &lt;/p&gt;
&lt;h2&gt;
  
  
  Path to Success is a proper foundation.
&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Standing_on_the_shoulders_of_giants"&gt;Standing on the shoulders of Giants&lt;/a&gt; - a general concept that &lt;em&gt;prior&lt;/em&gt; knowledge, and not only knowledge, could and should be used today 👇&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using the understanding gained by major thinkers who have gone before in order to make intellectual progress&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;every time you use &lt;code&gt;webpack&lt;/code&gt;, or any other bundler, and do not create your own one - &lt;em&gt;you stand on the shoulders&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;every time you use &lt;code&gt;React&lt;/code&gt;, or any other UI abstraction - &lt;em&gt;you stand on the shoulders&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;every time you use any library, not writing code from scratch - &lt;em&gt;you stand on the shoulders&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The majority of developers would use some preexisting (third party) solution to solve their problem, and would stand on the shoulders of other developers and "The Platform", but the same majority of developers are also missing the ability to &lt;strong&gt;stand on their own shoulders&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👉 every time you need to &lt;em&gt;change&lt;/em&gt; something, there should be a giant you can rely on. You have to &lt;em&gt;giant&lt;/em&gt; yourself.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;A digital platform is a foundation of self-service APIs, tools, services, knowledge and support which are arranged as a compelling internal product. Autonomous delivery teams can make use of the platform to deliver product features at a higher pace, with reduced coordination. &lt;a href="https://martinfowler.com/articles/talk-about-platforms.html"&gt;What is a 'Platform' anyway?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuqgqfju9rk38pt0t7pg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuqgqfju9rk38pt0t7pg.jpeg" alt="Shoulders" width="620" height="348"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  I've seen it
&lt;/h2&gt;

&lt;p&gt;We will jump into some concrete examples shortly, but let's first create some concepts to act as a foundation, let's create our first small Giant, the one you should know very well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤖 Terminator 1 -&amp;gt; 🦾 Terminator 2 -&amp;gt; 🦿Terminator 3. They all are backing plot of each other. Without the very first you cannot have the second.&lt;/li&gt;
&lt;li&gt;📖Book (Hobbit) -&amp;gt; 💍Film (Hobbit, well 3 films). While there are many differences between the book and the film, they share the same foundation&lt;/li&gt;
&lt;li&gt;🤯Total Recall(1990) -&amp;gt; 🤯Total Recall(2012). Those films have nothing in common, except 😉 the same foundation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every remake, every sequel or prequel, every film based on a book or a book based on a film are examples of &lt;code&gt;Standing on the Shoulders of Giants&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdowea2h3a0qili5vtoda.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdowea2h3a0qili5vtoda.jpeg" alt="3 spider mans" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which other Giants exist?&lt;/p&gt;
&lt;h1&gt;
  
  
  Layers
&lt;/h1&gt;

&lt;p&gt;Before you run away let us pick some examples you definitely will understand. Probably it will be more correct to say - that a lot of people for some strange reason expect you to understand it, and once upon a time during every second interview for a JavaScript position you might be asked about this thing, and it always was not very clear for me, like it's 100% not related... until today. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Layers of &lt;a href="https://dev.toOSI%20model"&gt;OSI Model&lt;/a&gt;, also known as a internet layer cake&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hms0xtgh8r4lt7tdu9o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3hms0xtgh8r4lt7tdu9o.png" alt="OSI model" width="798" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey! I said do not run away! Look how one layer of OSI &lt;em&gt;stands on the shoulders&lt;/em&gt; of another.&lt;br&gt;
There is no difference for you how &lt;em&gt;the device you are reading this information from&lt;/em&gt; is connected to the internet - Ethernet, Wifi, 2G, 4G or 5G - it just works. The top-most(7th) layer is unbound from any network hardware.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Implementation details are abstracted into many layers and some of those layers are even interchangeable(WiFi!==Ethernet!==Cellular).&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;I hope you would like to experience the same smooth journey during UI development. Strangely, but often developers are trying to &lt;em&gt;shorten&lt;/em&gt; processes, &lt;em&gt;collapse&lt;/em&gt; layers and especially not &lt;em&gt;separate concerns&lt;/em&gt; and trying to get something valuable from it. Again and again, with no Giants supporting them.&lt;/p&gt;



&lt;p&gt;Well, might be using OSI as an example was a little too much, but &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;would you consider &lt;code&gt;React&lt;/code&gt; as a &lt;code&gt;layer&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;would you consider &lt;code&gt;webpack&lt;/code&gt; as a &lt;code&gt;layer&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;would you consider &lt;code&gt;MaterialUI&lt;/code&gt; as the next &lt;code&gt;layer&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;and &lt;code&gt;NextJS&lt;/code&gt; as one more extra &lt;code&gt;layer&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the User, there is no difference if an Application has been built with &lt;code&gt;Nuxt&lt;/code&gt;, &lt;code&gt;Next&lt;/code&gt; or bare &lt;code&gt;webpack&lt;/code&gt;. For &lt;code&gt;webpack&lt;/code&gt; there is also no difference if it is used by the application directly or hidden inside Next. &lt;/p&gt;

&lt;p&gt;Can you see all those giants, on the shoulder of which your application is standing?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you ever wonder why your &lt;code&gt;node_modules&lt;/code&gt; are so huge, better to say GIGANTIC -&amp;gt; that's it! 😅&lt;/p&gt;
&lt;/blockquote&gt;

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



&lt;p&gt;Another good example is &lt;code&gt;Redux&lt;/code&gt;, as "Redux" by itself means nothing. It can be very different and you'll never know which recipe was used to bake it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Redux&lt;/code&gt;+&lt;code&gt;Thunk&lt;/code&gt;, or &lt;code&gt;Redux&lt;/code&gt;+&lt;code&gt;Saga&lt;/code&gt; provides a little more &lt;em&gt;context&lt;/em&gt; for an expected &lt;em&gt;taste&lt;/em&gt; of a given solution, however only &lt;a href="https://redux-toolkit.js.org/"&gt;RTK&lt;/a&gt; looks like a properly &lt;em&gt;layered cake&lt;/em&gt;. Mmmm, tasty!&lt;/p&gt;
&lt;h2&gt;
  
  
  The Whole and the Parts
&lt;/h2&gt;

&lt;p&gt;Speaking of Redux, there is a very common "mistake" in the understanding of the difference between "Redux" and "Context API". To be more concrete - the difference between &lt;code&gt;useReducer&lt;/code&gt; + &lt;code&gt;React.Context API&lt;/code&gt; and &lt;code&gt;Redux&lt;/code&gt; as the latter is technically the same as "Reducer + Context".&lt;br&gt;
Right after the React Context presentation many people, really many people, were wondering - 🤔 do they really need Redux or what?&lt;/p&gt;

&lt;p&gt;Well, probably they didn't, but the more proper way to explain what is wrong with such a common and simple misconception is to refer to &lt;a href="https://rbcs-us.com/documents/Segue.pdf"&gt;Weinberg’s Law of Decomposition&lt;/a&gt;, which states &lt;em&gt;"the whole is greater than the sum of its parts"&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Very easy to prove, just combine baking 🤯 soda and vinegar 💥.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By the fact, Redux is not only reducers, but also patterns, DevTools, and different middlewares for different use cases. &lt;br&gt;
While Redux &lt;strong&gt;is&lt;/strong&gt; ContextAPI + Reducer, it is BIGGER than &lt;em&gt;a sum of its parts&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👉 the real work of an engineer is to see such &lt;em&gt;bigger wholes&lt;/em&gt; looking at the pieces. Some things are visible only from a distance. Take a step back, do not focus too much on low-level details.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnx0yf7pq1t9txhnj1wu.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnx0yf7pq1t9txhnj1wu.jpeg" alt="Cat geo-glyph" width="300" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An interesting moment about said law is that it simultaneously states the opposite:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Weinberg’s Law of Decomposition is subtler. It says that if you&lt;br&gt;
measure a system according to some gauge of functionality or&lt;br&gt;
complexity, and then decompose it, and measure up what you&lt;br&gt;
end up with, that &lt;strong&gt;the sum of the parts is greater than the whole&lt;/strong&gt;.&lt;br&gt;
Huh? This seems to contradict the Law of Composition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The best way to read this is to accept that you are never going to &lt;em&gt;consume&lt;/em&gt; something in full, as a whole, only the required pieces. And there will be always some stuff left &lt;em&gt;unused&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Very easy to prove, just combine Cola and Whiskey 🤢
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Foundation: the Essence and the Variables
&lt;/h1&gt;

&lt;p&gt;The very first step towards our goal is the ability to... leave something behind. Separate flyes and cutlets, extract placeholders from templates, and split a single whole into &lt;code&gt;the Essence and the Variables&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The best and the most common example for this are &lt;code&gt;DSL&lt;/code&gt;s - Domain Specific Languages, including any &lt;strong&gt;Template&lt;/strong&gt; languages, including &lt;strong&gt;React&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;😉 is there any difference between &lt;code&gt;&amp;lt;div&amp;gt;{{userName}}&amp;lt;/div&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;User name={userName}&amp;gt;&lt;/code&gt;?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A very important moment is that the &lt;code&gt;Essence/Variables&lt;/code&gt; Separation can be performed by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moving the &lt;code&gt;Essence&lt;/code&gt; to the Layer below (sinking functionality)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Variables&lt;/code&gt; would be "kept"(emerge) automatically, as you will need to find a way to configure the underlying functionality.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This concept is almost equal to &lt;a href="https://en.wikipedia.org/wiki/Software_product_line"&gt;Software Product Line&lt;/a&gt; - methods, tools and techniques for creating a collection of similar software systems from a shared set of software assets using a common &lt;code&gt;means of production&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is also quite close to the &lt;code&gt;Ports and Adapters&lt;/code&gt;(hexagonal architecture), where the "actual functionality"(Platform capabilities) is &lt;em&gt;hidden&lt;/em&gt; behind Adapters (Essence in this case), which are in turn &lt;em&gt;hidden&lt;/em&gt; behind Ports(Variables in this case). &lt;/p&gt;

&lt;p&gt;To better understand, let's create a few examples:&lt;/p&gt;

&lt;h2&gt;
  
  
  Button Group
&lt;/h2&gt;

&lt;p&gt;At many sites you might see &lt;code&gt;Buttons&lt;/code&gt; positioned next to each other. Technically speaking they are &lt;strong&gt;nothing more&lt;/strong&gt; than two &lt;code&gt;Buttons&lt;/code&gt; placed in one parent and separated by some &lt;code&gt;Gap&lt;/code&gt;. However, does it mean that this is what you should do?&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="nx"&gt;ActionButtons&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;grid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;gridGap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;16px&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="p"&gt;&amp;gt;&lt;/span&gt;Do&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;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Something&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="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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How many different ways you know to create said gap, and how many different &lt;code&gt;gaps&lt;/code&gt; you can use - 2px, 4px, 20px?&lt;br&gt;
Probably said &lt;code&gt;gap&lt;/code&gt; should be proportional to &lt;code&gt;Button&lt;/code&gt; size to create a "coupling" between two buttons and let you use a larger gap to create a "distinction".&lt;/p&gt;

&lt;p&gt;This is why it's very important to create an abstraction - &lt;code&gt;ButtonGroup&lt;/code&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ButtonGroup&lt;/span&gt; &lt;span class="cm"&gt;/* don't think how*/&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;Do&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;Button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Something&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;ButtonGroup&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;Or even give underlying logic more control over look-n-feel,  and create an opportunity to &lt;em&gt;collapse&lt;/em&gt; a few Buttons in one group into one &lt;code&gt;Dropdown&lt;/code&gt; on mobile devices.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ifMobile&lt;/span&gt; &lt;span class="p"&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;Dropdown&lt;/span&gt; &lt;span class="na"&gt;caption&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Edit"&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;Edit&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;Button&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;Dropdown&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ButtonGroup&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;Edit&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;Button&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;ButtonGroup&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;// ⬇️⬇️⬇️⬇️&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ResponsiveButtonGroup&lt;/span&gt;
    &lt;span class="na"&gt;actions&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;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;Edit&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="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;Delete&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="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt; 
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move one &lt;em&gt;giant shoulder&lt;/em&gt; up. There are so many &lt;em&gt;reasons&lt;/em&gt; to have buttons grouped somehow, and all those use cases can be named to be used for a known reason!&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Table
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Table&lt;/code&gt; is another example where second-abstractions can help you a lot.&lt;br&gt;
Let's imagine you need to display a table. You have two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;render the table by yourself&lt;/li&gt;
&lt;li&gt;use some other library to do it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the first case you might need to spend more time than needed to handle edge cases, implement virtualisation, sorting, you name it.&lt;br&gt;
In the second case, you might find any particular library to not matching your expectations in some &lt;em&gt;details&lt;/em&gt; with no ability to change the pre-backed solution.&lt;/p&gt;

&lt;p&gt;Often in such case, developers are picking the first case as the only possible, while they always need the second - some "solution" they can just use. It just has to be "as they want". &lt;br&gt;
In the &lt;code&gt;Component Approach&lt;/code&gt; such a solution is known as a &lt;code&gt;Component&lt;/code&gt; 🤷‍♂️, no more, no less.&lt;/p&gt;

&lt;p&gt;So, yes, go with option one, pick your way to render HTML, not a big deal, pick the way you do(if you do) virtualisation, pick the way to handle "table data" - there are many &lt;em&gt;headless&lt;/em&gt; tables on NPM, and assemble in a way you need.&lt;br&gt;
If one day later you will have another use case with slightly different requirements - create another &lt;code&gt;Component&lt;/code&gt;, assembled in another way.&lt;br&gt;
But it is important to have this &lt;em&gt;intermediate&lt;/em&gt; abstraction layer, which states "This is how tables are made here", as exactly this point may change in time (redesign) and you want to avoid &lt;a href="https://en.wikipedia.org/wiki/Shotgun_surgery"&gt;Shotgun surgery&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Domino_effect"&gt;Domino Effect&lt;/a&gt;. You want a single change to a single component on UIKit/Design system side, not any client code.&lt;/p&gt;

&lt;p&gt;You want to stand on &lt;em&gt;Giant Shoulders&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Modal
&lt;/h2&gt;

&lt;p&gt;Modal is a combination of both cases above.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Modal&lt;/code&gt; itself should just provide you a &lt;code&gt;ModalDialog&lt;/code&gt; functionality.&lt;/li&gt;
&lt;li&gt;But the Application might need:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ConfirmModal&lt;/code&gt;, having a &lt;code&gt;Cancel button&lt;/code&gt; and the &lt;code&gt;Action button&lt;/code&gt;, next to each other in &lt;a href="https://medium.com/theorem/button-ambiguity-alignment-order-a42736e25334"&gt;some particular order&lt;/a&gt; (depending on the operation system), with (probably) &lt;code&gt;Cancel&lt;/code&gt; autofocused.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;InformationModal&lt;/code&gt;, having only one &lt;code&gt;Got it button&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;OperationModal&lt;/code&gt; to indicate some process and having no buttons.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plus &lt;code&gt;FileModal&lt;/code&gt;, that is not a "Design Primitive", but a separate experience with its own rules and principles.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;HTML Dialog Element&lt;/code&gt; -&amp;gt; &lt;code&gt;JS Modal Dialog&lt;/code&gt; -&amp;gt; &lt;code&gt;Use Case Dialog&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;🤷‍♂️ We are ok to use &lt;code&gt;window.alert&lt;/code&gt; and &lt;code&gt;window.confirm&lt;/code&gt;, but almost no "UI-library" provide a second-abstraction over their modals to reflect the same functionality.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Modal is a lower-level construct that is leveraged by the following components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dialog&lt;/li&gt;
&lt;li&gt;Drawer&lt;/li&gt;
&lt;li&gt;Menu&lt;/li&gt;
&lt;li&gt;Popover&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(source &lt;a href="https://mui.com/api/modal-unstyled/"&gt;Material UI&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If it is ok for you to use a &lt;code&gt;Modal&lt;/code&gt; in &lt;em&gt;some&lt;/em&gt; patterns, some of which do not look that &lt;em&gt;modal&lt;/em&gt;, why not create more patterns that are closely relayed to the &lt;code&gt;Modal&lt;/code&gt;/&lt;code&gt;Dialog&lt;/code&gt;, but represent particular use case?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Once you have a foundation - try to build something from it
and create a foundation for the next layer. 

Then try to build something from it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Unidirection flow
&lt;/h1&gt;

&lt;p&gt;Another crucial but constantly overlooked part of separating something into layers is the &lt;code&gt;controlling of the relations&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;level above should be built on the level below

&lt;ul&gt;
&lt;li&gt;in no circumstances level below can know about layer above&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;level above should be confident in the level below

&lt;ul&gt;
&lt;li&gt;level below should change less frequently&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This translates into two well known and well hated and thus ignored laws:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Law of Demeter&lt;/a&gt; or &lt;strong&gt;principle of least knowledge&lt;/strong&gt;. Read it as - you can know about webpack, webpack cannot know about you. &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://khalilstemmler.com/wiki/stable-dependency-principle/"&gt;Stable Dependency Principle&lt;/a&gt; stating that &lt;em&gt;components dependencies should be in the direction of stability&lt;/em&gt;, so you can build your code &lt;code&gt;Once and only once&lt;/code&gt;, and not rewrite it every month to adjust to ever-changing platform.

&lt;ul&gt;
&lt;li&gt;mind &lt;a href="https://en.wikipedia.org/wiki/Shotgun_surgery"&gt;Shotgun surgery&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Domino_effect"&gt;Domino Effect&lt;/a&gt;, there is basically no time for it.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Middle-level architecture
&lt;/h1&gt;

&lt;p&gt;So, UI is a &lt;em&gt;piece a cake&lt;/em&gt;?&lt;br&gt;
👉 Yes, it is if you think about it as about Cake. Layer on top of another Layer.&lt;/p&gt;

&lt;p&gt;Are you already using Onion Architecture, where layers are separated?&lt;br&gt;
👉 Of course. Look inside your &lt;code&gt;node_modules&lt;/code&gt;, and think how many other packages, libraries and layers are hidden behind the ones you know about.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/High_Level_Architecture"&gt;High-Level Architecture&lt;/a&gt;(read pictures) and &lt;a href="https://en.wikipedia.org/wiki/Low-level_programming_language"&gt;Low-Level Architecture&lt;/a&gt;(building primitives), what is this one about?&lt;br&gt;
👉 And this one is about something exactly in between - Middle-level Architecture, combining "some given blocks" to create an Application according to HLA. &lt;br&gt;
The one usually forgotten, and the one you always have to define for yourself by yourself.&lt;/p&gt;

&lt;h1&gt;
  
  
  Actionable advice
&lt;/h1&gt;

&lt;p&gt;Take a single component and try to find another structure inside it. Find a &lt;code&gt;Modal&lt;/code&gt; behind a &lt;code&gt;Dialog&lt;/code&gt;, find a &lt;code&gt;FocusLock&lt;/code&gt; behind that &lt;code&gt;Modal&lt;/code&gt;, go to the very end on the left (atoms) and then go back to the very right(combinations).&lt;/p&gt;

&lt;p&gt;Think in Atoms -&amp;gt; Molecules -&amp;gt; Organisms, not from &lt;a href="https://atomicdesign.bradfrost.com/chapter-2"&gt;Atomic Design&lt;/a&gt; point of view, but as a unidirectional &lt;em&gt;complexity flow&lt;/em&gt;. &lt;br&gt;
Remember the &lt;code&gt;Table&lt;/code&gt; – you should be able to have a &lt;code&gt;Complex Component A&lt;/code&gt; break it into pieces and assemble into &lt;code&gt;Complex Component B&lt;/code&gt;. Then go back to those pieces and break them down.&lt;br&gt;
👉 That is converting a single whole to the Essence and the Variables. &lt;/p&gt;

&lt;p&gt;The point here - layers &lt;strong&gt;should not interfere&lt;/strong&gt;, and should not be used in skip levels(Organism should never use Atom) that will enable their reusability and provide maintainability free from &lt;code&gt;Shotgun Surgery&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create a fancy cake, starting from &lt;code&gt;More Generic&lt;/code&gt; layers and going to &lt;code&gt;Less Generic&lt;/code&gt; ones. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhu9pzn17x8qd12dfsju.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhu9pzn17x8qd12dfsju.jpeg" alt="portal cake" width="640" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And a cherry on top.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>BEM vs CSS Grid</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Sat, 28 Aug 2021 05:14:18 +0000</pubDate>
      <link>https://dev.to/thekashey/bem-vs-css-grid-22e8</link>
      <guid>https://dev.to/thekashey/bem-vs-css-grid-22e8</guid>
      <description>&lt;p&gt;&lt;code&gt;BEM&lt;/code&gt; is not a “naming convention”. It’s a separation between &lt;code&gt;Blocks&lt;/code&gt; and &lt;code&gt;Elements&lt;/code&gt;. And &lt;code&gt;Modifiers&lt;/code&gt;... but let’s just forget about them for a while. &lt;br&gt;
Today we better focus on something different.&lt;/p&gt;

&lt;p&gt;So, I've written this article because people do not understand the core principles behind &lt;code&gt;BEM&lt;/code&gt;, not to be able to see them behind other features. &lt;br&gt;
This is why let’s forget about &lt;code&gt;BEM&lt;/code&gt; for a while as well.&lt;/p&gt;

&lt;p&gt;To get things started we all can generally agree that…&lt;/p&gt;
&lt;h1&gt;
  
  
  CSS Grids are awesome 🥳
&lt;/h1&gt;

&lt;p&gt;The main difference between &lt;code&gt;display block&lt;/code&gt; and &lt;code&gt;display flex&lt;/code&gt; is that the first one sees all children nodes as a separate elements, while they act like a Team🤜 within &lt;code&gt;flex&lt;/code&gt; – they can &lt;em&gt;grow&lt;/em&gt; and &lt;em&gt;shrink&lt;/em&gt;.&lt;br&gt;
They are connected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Foentles2l2rwn9cppfrq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Foentles2l2rwn9cppfrq.png" alt="Flex Grow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Grid&lt;/code&gt; fosters this connection, lets you handle bigger blocks, giving more power and more control.&lt;/p&gt;

&lt;p&gt;But there is one big difference, really &lt;strong&gt;BIG&lt;/strong&gt; difference, - the majority of power and control is given to the “grid parent”, not “grid element”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.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%2Fmny1ai5v9w4fg50ca6gn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fmny1ai5v9w4fg50ca6gn.png" alt="Grid Areas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's imagine a conversation between Grid and Cell:&lt;/p&gt;

&lt;p&gt;🤖: Dear Grid-Item, I've prepared a place for you, where shall you stay according to my very plan 😈&lt;br&gt;
📦: Can I have my own opinion?&lt;br&gt;
🤖: Dear Grid-Item, well yes, some of you can move self to other places, but not particularly you 😅. Please stay within my template because I do have a plan for you 👮🏻‍♂️.&lt;/p&gt;

&lt;p&gt;And like the &lt;code&gt;Grid&lt;/code&gt;, which can use &lt;code&gt;grid template&lt;/code&gt; or &lt;code&gt;grid areas&lt;/code&gt; to control all direct children, BEM also has a plan...&lt;/p&gt;
&lt;h1&gt;
  
  
  BEM has a Plan
&lt;/h1&gt;

&lt;p&gt;Technically speaking &lt;code&gt;BEM&lt;/code&gt; works in the same way as &lt;code&gt;Grid&lt;/code&gt; - they share the same ideology. &lt;code&gt;BEM&lt;/code&gt; is just not bound to the "2d grid" and one level of children nodes.&lt;/p&gt;

&lt;p&gt;It can be easier to think about &lt;code&gt;BEM&lt;/code&gt; from a &lt;code&gt;Component Model&lt;/code&gt; point of view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there is a &lt;code&gt;Parent&lt;/code&gt; component and a few &lt;code&gt;Elements&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;according to the plan&lt;/em&gt; &lt;code&gt;Elements&lt;/code&gt; has to be placed in some well known location.&lt;/li&gt;
&lt;li&gt;children &lt;code&gt;Elements&lt;/code&gt; should not think or even know about their placement.
&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ParentTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&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;body&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;header&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;slot&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;Component1&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="err"&gt;---&lt;/span&gt; &lt;span class="na"&gt;Another&lt;/span&gt; &lt;span class="na"&gt;block&lt;/span&gt;
        &lt;span class="err"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="na"&gt;slot&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;header&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;main&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;slot&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;Component2&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="err"&gt;---&lt;/span&gt; &lt;span class="na"&gt;Another&lt;/span&gt; &lt;span class="na"&gt;block&lt;/span&gt;
        &lt;span class="err"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="na"&gt;slot&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;main&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;body&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;html&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;a href="https://media.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%2Fn8bnhaoa7pgk0373a8ww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.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%2Fn8bnhaoa7pgk0373a8ww.png" alt="BEM Composition"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  A few rules
&lt;/h1&gt;

&lt;p&gt;Let me be honest - there are two major sites about BEM methodology, where you can read some information - &lt;a href="http://getbem.com/" rel="noopener noreferrer"&gt;http://getbem.com/&lt;/a&gt; and &lt;a href="https://en.bem.info/" rel="noopener noreferrer"&gt;https://en.bem.info/&lt;/a&gt;. I hope you likely to see the key information hidden between the lines, but according to my experience no one has seen it yet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;BEM is not about that-strange__naming--convention&lt;br&gt;
BEM is about the Separation between &lt;code&gt;B&lt;/code&gt; and &lt;code&gt;E&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here is what you might miss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Elements do not lay themselves out&lt;/strong&gt;. Parent &lt;code&gt;Block&lt;/code&gt; does&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block style themselves and layout only their children&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocks cannot be (visually) styled 🎨 outside&lt;/strong&gt;, except via own known &lt;code&gt;Modifiers&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Every &lt;code&gt;Element&lt;/code&gt; can be a &lt;code&gt;Block&lt;/code&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: "Children" is not an "immediate DOM node". Still easy to think in React terms - children is everything defined among component&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&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="nx"&gt;List&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; // children
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; // also children
   &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeItem&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; // still children, but also a Block
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Rule them all
&lt;/h1&gt;

&lt;p&gt;How &lt;code&gt;Block&lt;/code&gt; can rule children? Usually (for the last 15 years? BEM was created back in 2006) by passing extra &lt;code&gt;classname&lt;/code&gt;, which is expected to obey the principles above and cannot &lt;em&gt;style&lt;/em&gt; &lt;code&gt;children&lt;/code&gt;, except using &lt;code&gt;modifiers&lt;/code&gt; defined in the &lt;code&gt;children&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;modifiers&lt;/code&gt; are &lt;em&gt;equal&lt;/em&gt; to (React) &lt;code&gt;props&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Block&lt;/code&gt; only can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;lay&lt;/em&gt; &lt;code&gt;Elements&lt;/code&gt; inside. In the same way &lt;code&gt;Grid&lt;/code&gt; can &lt;em&gt;lay&lt;/em&gt; &lt;code&gt;Grid-Items&lt;/code&gt; inside.&lt;/li&gt;
&lt;li&gt;configure own children by picking/using different modifiers/props, but only among the explicitly supported by children Components. Well, you can do the same with &lt;code&gt;Grids&lt;/code&gt;, not something particular bound to BEM.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Look like there are at least something in common between BEM and Grid. Grids are just more about "how" to do something - they are providing a particular way to command a Browser Engine. While BEM 🤷‍♂️ it's just a way to keep things clear&lt;/p&gt;

&lt;p&gt;Both Grid and BEM define layout for their children gently asking those children not to interfere.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While this moment might sounds like NOT something really important - it is the core essence of both technologies&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Step away from technical implementation. Try to understand the intent behind the actual approach and principles according to which both technologies ended like this.&lt;/p&gt;

&lt;h1&gt;
  
  
  What to do
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;(dimension) do not let components define own dimensions - different Parents can have different Plans

&lt;ul&gt;
&lt;li&gt;and your parent will configure "you" one way or another - or by placing "you" in &lt;code&gt;grid&lt;/code&gt; (browser layout) or by giving you extra classname with &lt;code&gt;flex&lt;/code&gt; styles (explicit layout). That is not "your" problem.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;(gaps) do not let components define margins - that gonna break any order anyone will try to establish

&lt;ul&gt;
&lt;li&gt;margins are still file, just define it "inside" block, the area under your control, not "outside", creating unexpected behaviour for consumers.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;(isolation) do not style other components, tell them what they shall do&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  So what?
&lt;/h1&gt;

&lt;p&gt;So please stop writing random code, which always ends in some messy, completely unmaintainable state, causing a lot of performance issues, especially if you overuse CSS-in-JS for no reason.&lt;/p&gt;

&lt;p&gt;Think structurally. Think in relationships. Think about you styles in the same way you think about your code, files, function and packages - and I believe there are some rules you follow and some pain you've experienced due to bad habits.&lt;/p&gt;




&lt;p&gt;Well, apart of Grids there is another concept which should explain you the main point behind separation of responsibilities and concerns - &lt;a href="https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle" rel="noopener noreferrer"&gt;Open Closed Principle&lt;/a&gt;, a part of &lt;a href="https://en.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;SOLID pattern&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;software entities should be open for extension, but closed for modification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which, in this case, controls what Elements can be &lt;em&gt;asked&lt;/em&gt; to do by Blocks(blocks are "extension"), and how Blocks could not affect Elements(which are "closed for modification")&lt;/p&gt;

&lt;h2&gt;
  
  
  See also:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://non-traditional.dev/encapsulated-css-the-key-to-composable-layouts-94f11c177cc1" rel="noopener noreferrer"&gt;https://non-traditional.dev/encapsulated-css-the-key-to-composable-layouts-94f11c177cc1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.joshwcomeau.com/css/styled-components/#isolated-css" rel="noopener noreferrer"&gt;https://www.joshwcomeau.com/css/styled-components/#isolated-css&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mxstbr.com/thoughts/margin/" rel="noopener noreferrer"&gt;https://mxstbr.com/thoughts/margin/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Wait!
&lt;/h3&gt;

&lt;p&gt;Should you read anything about BEM methodology in particular?&lt;/p&gt;

&lt;p&gt;No, because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you don't need naming pattern with CSSModules, and especially CSS-in-JS&lt;/li&gt;
&lt;li&gt;the main thing is a separation, and frankly speaking it does not have to be exactly the same separation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep the last point in mind. Remember how Grids work. Only then go and research information about BEM you can found in other places. &lt;/p&gt;

&lt;p&gt;And keep in your mind one more thing - as I've mentioned above the vast majority of developers, including the ones who uses BEM, "did not get the point", something more than that_strange__naming--pattern.&lt;br&gt;
I know this for sure. I was among them.&lt;/p&gt;

</description>
      <category>bem</category>
      <category>css</category>
      <category>maintenance</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What Problem We Solve</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Thu, 26 Nov 2020 06:07:48 +0000</pubDate>
      <link>https://dev.to/thekashey/what-problem-we-solve-21no</link>
      <guid>https://dev.to/thekashey/what-problem-we-solve-21no</guid>
      <description>&lt;p&gt;There is a single question you should ask yourself a few times a day. Every time it will sounds a little different, and every time it will require an absolutely different answer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ask yourself:
   `What Problem We Solve`
   `Which Problem We Solve`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;👉 Where &lt;code&gt;What&lt;/code&gt;/&lt;code&gt;Which&lt;/code&gt; is a choice between a number of possibilities. &lt;/p&gt;
&lt;h1&gt;
  
  
  The System
&lt;/h1&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;What&lt;/strong&gt; problem we solve?
&lt;/h2&gt;

&lt;p&gt;Is there any need to solve this problem? &lt;strong&gt;This&lt;/strong&gt; problem, in &lt;strong&gt;this&lt;/strong&gt; area. &lt;br&gt;
Does anyone need your solution?&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Which&lt;/strong&gt; problem we solve?
&lt;/h2&gt;

&lt;p&gt;Where are many different &lt;em&gt;kinds&lt;/em&gt; of a single problem. Do we know &lt;strong&gt;which&lt;/strong&gt; one we are going to solve? &lt;br&gt;
Who is solving others?&lt;/p&gt;
&lt;h2&gt;
  
  
  What &lt;strong&gt;Problem&lt;/strong&gt; we solve?
&lt;/h2&gt;

&lt;p&gt;Is it a problem? Will anyone be happy if we resolve it? Does anyone ready to pay for it?&lt;/p&gt;
&lt;h2&gt;
  
  
  What problem &lt;strong&gt;We&lt;/strong&gt; solve?
&lt;/h2&gt;

&lt;p&gt;Are &lt;strong&gt;we&lt;/strong&gt; the right people to solve this problem? Are we able to do it? Are we missing something or actually have everything to make it happen?&lt;br&gt;
Might be another team can do better?&lt;/p&gt;
&lt;h2&gt;
  
  
  What problem we &lt;strong&gt;Solve&lt;/strong&gt;?
&lt;/h2&gt;

&lt;p&gt;Well, do we know what solve the problem? Can we understand that the problem is actually solved? Are we going to solve it completely or just make it a little better?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do we have a solution already? In this case, go backwards and find the problem it can be applied to efficiently.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;Actually sounds very &lt;code&gt;SIMple&lt;/code&gt; (Specific, Important, Measurable) framework, as many others which were created to help you to 1) start something, 2) maintain, and 3) finish. &lt;br&gt;
Take a look at &lt;a href="https://dev.to/thekashey/why-what-how-framework-24gd"&gt;Why What How&lt;/a&gt; post for details.&lt;/p&gt;
&lt;h1&gt;
  
  
  Does it work?!
&lt;/h1&gt;

&lt;p&gt;While it can sound too simply - that simplicity is the key to efficiency.&lt;br&gt;
Just ask yourself this question every time you need to make a next step to understand where you are, and clarify how to make that next step.&lt;/p&gt;

&lt;p&gt;Firstly, it works like planning and inspiration. You need to find the right problem to solve. Or you can try to find the right problem for a solution you just envisioned.&lt;/p&gt;

&lt;p&gt;Secondary, it works like &lt;em&gt;QA-kickoff&lt;/em&gt;, ensuring that the next step is worth making. That we should try to solve this problem, not find a better problem to solve.&lt;/p&gt;

&lt;p&gt;Then it works like… QA-kickoff, ensuring that the right team was given the right task. Maybe it’s the right time to get more people on board.&lt;/p&gt;

&lt;p&gt;And at last, it defines The End Goal. Explains why it will be a solution. Why people will need it, use it, and be happy with it.&lt;/p&gt;

&lt;p&gt;Ask yourself &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤷‍♂️ Why you need a new phone. What problem it will solve?&lt;/li&gt;
&lt;li&gt;🤷‍♂️ Why you need new work. What is the problem?&lt;/li&gt;
&lt;li&gt;🤷‍♂️ Why this PR should be merged. What problem does it solve?&lt;/li&gt;
&lt;li&gt;🤷‍♂️ Why should we apply the principles above? We?&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Prior art
&lt;/h1&gt;

&lt;p&gt;The origin of this principle is &lt;a href="https://github.com/twirl/The-API-Book/blob/gh-pages/src/en/clean-copy/02-Section%20I.%20The%20API%20Design/02.md#defining-an-application-field" rel="noopener noreferrer"&gt;The API Book&lt;/a&gt; by Twirl.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__user ltag__user__id__538546"&gt;
    &lt;a href="/twirl" class="ltag__user__link profile-image-link"&gt;
      &lt;div class="ltag__user__pic"&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%2Fuser%2Fprofile_image%2F538546%2F726ab612-b43d-45d4-9d50-bd0ae375dbdb.jpeg" alt="twirl image"&gt;
      &lt;/div&gt;
    &lt;/a&gt;
  &lt;div class="ltag__user__content"&gt;
    &lt;h2&gt;
&lt;a class="ltag__user__link" href="/twirl"&gt;Sergey Konstantinov&lt;/a&gt;Follow
&lt;/h2&gt;
    &lt;div class="ltag__user__summary"&gt;
      &lt;a class="ltag__user__link" href="/twirl"&gt;Developing APIs for over a decade: maps APIs, integration APIs, reviewing W3C specs, etc.&lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;






&lt;p&gt;Don't have an answer to any part of the Question? Probably you should solve another problem.&lt;/p&gt;

&lt;p&gt;Which? 🤔 What? 😲 Oh! 🙀 &lt;/p&gt;

</description>
    </item>
    <item>
      <title>The limits of 2 dimensions</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Thu, 05 Nov 2020 10:58:54 +0000</pubDate>
      <link>https://dev.to/thekashey/the-limits-of-2-dimensions-2aa3</link>
      <guid>https://dev.to/thekashey/the-limits-of-2-dimensions-2aa3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article was written to design a solution for &lt;a href="https://terravigil.com" rel="noopener noreferrer"&gt;terravigil.com&lt;/a&gt; articles ordering. It will start as a problem related to articles, and will end with the same problem as well. But in between...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's do some math:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;open your favourite site with some articles on the main page - &lt;code&gt;bbc.com&lt;/code&gt;, &lt;code&gt;reddit&lt;/code&gt; or &lt;code&gt;dev.to&lt;/code&gt;, it does not matter.&lt;/li&gt;
&lt;li&gt;check what you see&lt;/li&gt;
&lt;li&gt;probably that's latest and the best news or articles&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;latest&lt;/code&gt; AND &lt;code&gt;the best&lt;/code&gt;.&lt;br&gt;
These are &lt;strong&gt;two&lt;/strong&gt; different &lt;strong&gt;properties&lt;/strong&gt; to order. Simultaneously.&lt;br&gt;
These are &lt;strong&gt;two&lt;/strong&gt; different &lt;strong&gt;dimensions&lt;/strong&gt; to discover.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;💡 There is an easy way to "experience" this problem - open any &lt;code&gt;table&lt;/code&gt; within some table processor (Excel) and try to sort by a field. And then another field. And then by two fields simultaneously -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;😅 but there is no such operation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Speaking in a more common language (SQL):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you can &lt;code&gt;ORDER BY time, rating LIMIT 10&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;but it will first sort by &lt;code&gt;time&lt;/code&gt; and only then by &lt;code&gt;rating&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want to get &lt;em&gt;by time AND by rating&lt;/em&gt; simultaneously - that is not possible, the ordering is happening sequentially, or it's better to say &lt;em&gt;in the &lt;code&gt;1D world&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;However, it's easy to start the story from another example. From the actual &lt;code&gt;2D world&lt;/code&gt;. Something we all experienced, and able to understand.&lt;/p&gt;

&lt;p&gt;From &lt;strong&gt;maps&lt;/strong&gt; 😉&lt;/p&gt;

&lt;h1&gt;
  
  
  Maps
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;🗺 Maps are 2D. Obviously.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's do some math:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;open your favourite site, powered by some maps, and displaying some stuff on the map (that's important!).&lt;/li&gt;
&lt;li&gt;check what you see.&lt;/li&gt;
&lt;li&gt;probably there are some "dots"(Points Of Interest) on that map.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For the sake of simplicity - let's use &lt;a href="https://www.domain.com.au/rent/?excludedeposittaken=1&amp;amp;startloc=-33.82907940464621%2C151.08880273011536&amp;amp;endloc=-33.9215763365357%2C151.25874749329896&amp;amp;displaymap=1" rel="noopener noreferrer"&gt;domain.com.au&lt;/a&gt; as an example.&lt;/p&gt;

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

&lt;p&gt;Let's check what we actually looking at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ it's a City Of Sydney&lt;/li&gt;
&lt;li&gt;✅ majority of POIs are located in the Downtown&lt;/li&gt;
&lt;li&gt;✅ there are almost 9000 places to rent&lt;/li&gt;
&lt;li&gt;💩 just a few dozen are displayed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, this is "our situation" - we have &lt;strong&gt;more data&lt;/strong&gt; than we could, or should display, so we have to apply some &lt;code&gt;limits&lt;/code&gt; -  we have to pick "&lt;code&gt;latest&lt;/code&gt; AND &lt;code&gt;the best&lt;/code&gt;" items to display. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We have to pick &lt;code&gt;the best&lt;/code&gt; items with restriction by &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt;. Already 1-dimensional ordering and 2-dimensional filtering.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, I would like to point in that strange fact, that there is &lt;strong&gt;almost no information outside of Downtown&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Probably nobody is selling or leasing their houses so far from the centre. People are not living in those wild areas! Sounds reasonable? 🤷‍♂️ why not?&lt;/p&gt;

&lt;p&gt;However, let's double-check it - zoo-oo-ooming in!&lt;/p&gt;

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

&lt;p&gt;😎 I would assure you, there is life outside of Sydney's CBD, we just are not able to see it due to &lt;strong&gt;limitation of 2D dimensions&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I've got a video for you&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/-kOZdUAj5V4"&gt;
&lt;/iframe&gt;
&lt;br&gt;
👉 In short: there is A LOT of "dots" outside the Downtown, but we don't see them.&lt;/p&gt;

&lt;p&gt;The root cause of this effect is - &lt;strong&gt;information tend to be displayed in the areas of higher density&lt;/strong&gt;. And yes - it comes, and become worse and worse, with a scale.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;information tend to be displayed in the areas of higher density. Every entity has an equal probability to be picked, and that's why higher "density" produces more "picks"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Actually, the root cause here can be observed as the overall "speed" of updating information on the map as well.&lt;br&gt;
Every time I move the map, &lt;code&gt;domain&lt;/code&gt; fetches the new information from the backend, and then displays it. Very often, especially within "areas of high density", the updated data does not represent the previous dataset (it might be very different), even if I am searching roughly the same area.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This causes heavy load on the backend, very slow and non-responsive frontend, as well as annoying &lt;em&gt;POI-glittering&lt;/em&gt;. Really VERY annoying. Especially when some point you had a plans to inspect just disappears... &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1248453560146116609-625" src="https://platform.twitter.com/embed/Tweet.html?id=1248453560146116609"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1248453560146116609-625');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1248453560146116609&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h1&gt;
  
  
  Living in 2-dimensions
&lt;/h1&gt;

&lt;p&gt;We have two problems here:&lt;/p&gt;

&lt;h3&gt;
  
  
  Problem 1
&lt;/h3&gt;

&lt;p&gt;Every request is unique. You can move a map as you want, and every time it would be absolutely unique. You will have to reach the server, spend time, return a unique result.&lt;/p&gt;

&lt;p&gt;Two customers, looking at one area, are looking at ABSOLUTELY different ones.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd8wqxo0wybfcinuexwle.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fd8wqxo0wybfcinuexwle.png" alt="Example from Yandex maps"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There is one thing you have to understand - maps "displaying" some stuff are here for some time. For "some time" - since IE6 and pre-iPhone era. Since "before" AWS. Since the times, when you had a single database for all 1000000 customers per day.&lt;br&gt;
In other words - 10 years ago you were not able to "scale up", and had to provide performant and efficient backend, or &lt;strong&gt;your Frontend will DDOS your backend&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And cartographical services of the past &lt;strong&gt;have&lt;/strong&gt; to solve the problem. And had solved it. &lt;/li&gt;
&lt;li&gt;But cartographical services of the present are not giving a crap, resulting in the issue mention above, the fix for which is known for years.
&amp;gt; The solution will be explained later&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Problem 2
&lt;/h3&gt;

&lt;p&gt;Problem number 2 consist of the other two problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SELECT * WHERE X and Y&lt;/code&gt; gives us 10.000 records. So you can select much more information than you can display. So you have to &lt;code&gt;LIMIT&lt;/code&gt; it. But limiting needs sorting to keep "the best" records.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ORDER BY rating&lt;/code&gt; is keeping records in the areas of higher density. And you want to display all possible &lt;em&gt;opportunitues&lt;/em&gt;.
If all records have the same probability to be displayed - the result would represent just information density.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And "information density" is the problem you have to fix first. Not to &lt;em&gt;fix&lt;/em&gt; - but &lt;em&gt;neutralize&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Clustering
&lt;/h3&gt;

&lt;p&gt;For example,​ you can do N smaller requests to "cover" the whole requested area.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT WHERE X and Y ORDER BY rating LIMIT 100 
⬇️⬇️⬇️
100 times x(SELECT WHERE x and y ORDER BY rating LIMIT 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time instead of one big select we are making a dozen smaller, every of which still tends to display the most "dense" part of it, but covering the whole block more or less &lt;strong&gt;evenly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However - &lt;strong&gt;it is not efficient&lt;/strong&gt;. There is a better way - &lt;code&gt;group by&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT WHERE X and Y ORDER BY rating LIMIT 100
⬇️⬇️⬇️
SELECT WHERE X and Y GROUP BY (ROUND(x/10), ROUND(y/10)) ORDER BY rating
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case we have grouped all points in some "smaller area" together, resulting potentially up to 100 rows(0.1x0.1 grouping).&lt;br&gt;
This is, again, not efficient, but could it help us with reducing dev city of the data and making coverage a bit more “flat”.&lt;/p&gt;

&lt;p&gt;We just make a complex task a bit simpler.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;this is not clusterization&lt;/strong&gt; we probably should use to properly display high density information. All we did is &lt;strong&gt;aggregation&lt;/strong&gt;, and that's enough! But we did it not in the best way.&lt;br&gt;
There is a better one.&lt;/p&gt;
&lt;h1&gt;
  
  
  Problems with "random queries"
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;group by ROUND(x/10)&lt;/code&gt; is not working. &lt;code&gt;/10&lt;/code&gt; should be different for every zoom level. With every zoom, Map becomes twice bigger, so multiplier should also adjust (x2 every zoom)
&amp;gt; Plus grouping is actually slow. No matter how you do it - it would be slow.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WHERE x BETWEEN left and right&lt;/code&gt; would be unique for every user looking at your map. And that is a problem bot only for the network cache, but for the database cache as well
&amp;gt; 👉 Two customers, looking at one area, are looking at ABSOLUTELY different ones.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;
  
  
  Z for Z-code
&lt;/h1&gt;

&lt;p&gt;The goal of aggregation is to &lt;em&gt;collapse&lt;/em&gt; some records, which could be grouped somehow, into one record.&lt;br&gt;
For 2d data the most common solution is known as &lt;a href="https://en.wikipedia.org/wiki/Z-order_curve" rel="noopener noreferrer"&gt;Z or Morton code&lt;/a&gt;, as well as &lt;a href="https://en.wikipedia.org/wiki/Geohash" rel="noopener noreferrer"&gt;geohash&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Gray_code" rel="noopener noreferrer"&gt;Gray code&lt;/a&gt; or &lt;a href="https://en.wikipedia.org/wiki/Hilbert_curve" rel="noopener noreferrer"&gt;Hilbert curve&lt;/a&gt; - they all are some sort of &lt;em&gt;spatial filling curves&lt;/em&gt;, literally a &lt;em&gt;line&lt;/em&gt; which stitches N dimension together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;it is called "Z" because every iteration it "Z" itself (and Hilbert curve "U" itself)&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;It might take a while to understand how such curves work, but the essence of the idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;values which are "close" on the curve, are "close" in the N-dimension as well&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our case that would sounds like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT WHERE X and Y 
GROUP BY zcode &amp;amp; 0xFFFF00  &amp;lt;---
ORDER BY rating LIMIT 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where &lt;code&gt;0xFFFF00&lt;/code&gt; is playing a role of a "mask" and groups 😎&lt;em&gt;values which are "close" on the curve&lt;/em&gt;😎 effectively clustering elements which are close to each other in 2D.&lt;/p&gt;

&lt;p&gt;The explanation how "clustering" work is best seen on &lt;a href="https://docs.microsoft.com/en-us/bingmaps/articles/bing-maps-tile-system" rel="noopener noreferrer"&gt;Bings Tile "coordinate" System&lt;/a&gt; - quadkeys (the same Z code) which uses 2 bits (0-1-2-3) per one "division". So masking the "following" bits can "group" all points with the same &lt;em&gt;beginning&lt;/em&gt; of the code. And all points in one "rectangle" will have the same beginning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F159fj6mz1059h6xlecyd.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F159fj6mz1059h6xlecyd.jpg" alt="QuadKey"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Word-to-vec
&lt;/h1&gt;

&lt;p&gt;A bit different approach is used in search engines, which also need to &lt;em&gt;find and rank&lt;/em&gt; something among a billion documents.&lt;br&gt;
"Similarity" search is one of key algorithms there, and &lt;a href="https://en.wikipedia.org/wiki/Word2vec" rel="noopener noreferrer"&gt;word2vec&lt;/a&gt; is a key technique here.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As the name implies, word2vec represents each distinct word with a particular list of numbers called a vector. The vectors are chosen carefully such that a simple mathematical function (the cosine similarity between the vectors) indicates the level of semantic similarity between the words represented by those vectors.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Mathematically speaking it's the same case - "close" words or "documents" would end "close" to each other in the (very) multi-dimension space (for the reference it's not 2D or 3D, but closer to 1000D).&lt;/p&gt;

&lt;h1&gt;
  
  
  Terravigil
&lt;/h1&gt;

&lt;p&gt;However let's back to our articles case, about displaying "the best and the most fresh" data.&lt;/p&gt;

&lt;p&gt;What we actually want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we want to see "the best of the best" news longer - more people should read them&lt;/li&gt;
&lt;li&gt;we want to display hot news as soon as possible, so &lt;em&gt;freshness&lt;/em&gt; is important&lt;/li&gt;
&lt;li&gt;but there two points violates each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are two possible solutions here: &lt;code&gt;buckets&lt;/code&gt; and &lt;code&gt;score&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Buckets
&lt;/h3&gt;

&lt;p&gt;Selects news in predefined time internals, and order inside each group separately.&lt;br&gt;
Literally "display top news of today" and then "display top news of tomorrow". &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the size of a bucket can be adjusted, like more than a day or less than a day&lt;/li&gt;
&lt;li&gt;buckets might overlap, like you can merge the top news today, and the top news from the past week.&lt;/li&gt;
&lt;li&gt;buckets can be fixed (in time), thus cacheable, or floating, changing intervals they represent every minute or hour.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Buckets are first &lt;del&gt;sort by time&lt;/del&gt; bucket by time, then sort by rate.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Score
&lt;/h3&gt;

&lt;p&gt;Selects news ordered by a single "score", which is the main problem of this article.&lt;br&gt;
While spatial curves can help with 2D and other &lt;em&gt;geometrical&lt;/em&gt; cases - they are more or less useless for this particular case. &lt;/p&gt;

&lt;p&gt;Why? Because some elements "close" on the 2D plot would be VERY far on the curve. Just think for "start" is different from the "end", while curve starts and ends in the same point.&lt;/p&gt;

&lt;p&gt;Solution here is to use or special "vector" data formats or databases known as KNN - &lt;a href="https://en.wikipedia.org/wiki/K-nearest_neighbors_algorithm" rel="noopener noreferrer"&gt;k-nearest neighbours search&lt;/a&gt; (or &lt;a href="https://en.wikipedia.org/wiki/Nearest_centroid_classifier" rel="noopener noreferrer"&gt;Nearest centroid&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Javascript&lt;/code&gt; implementation &lt;a href="https://github.com/mourner/rbush-knn" rel="noopener noreferrer"&gt;https://github.com/mourner/rbush-knn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ElasticSearch&lt;/code&gt; &lt;a href="https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/knn.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/knn.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Postgres&lt;/code&gt; support it as a part of &lt;code&gt;PostGIS&lt;/code&gt; - remember that our problem can be seen as a geometrical problem&lt;/li&gt;
&lt;li&gt;MySQL does not have any &lt;a href="https://stackoverflow.com/questions/574691/mysql-great-circle-distance-haversine-formula" rel="noopener noreferrer"&gt;efficient&lt;/a&gt; way to handle this, and you will probably kill your database if you try.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;A sample data set of points considered as "neighbours"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Long story short - &lt;code&gt;Terravigil&lt;/code&gt; uses &lt;strong&gt;buckets&lt;/strong&gt; as long as it's easy to &lt;em&gt;design&lt;/em&gt; them and understand how they work, so you can create a correct result.&lt;br&gt;
As well it uses &lt;strong&gt;score&lt;/strong&gt; to derive a single metric from many different other signals to at least understand which article is "the best". &lt;/p&gt;

&lt;p&gt;But all you have to do - just look at the problem from another angle. If you were told to do a 2-dimensional sorting, thinks about limits of the 2-nd dimension.&lt;/p&gt;

&lt;p&gt;And it's not just about how to do it, it's also about how to make it FAST.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>maps</category>
      <category>rating</category>
      <category>sql</category>
    </item>
    <item>
      <title>"Why? What? How?" framework</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Wed, 14 Oct 2020 04:53:35 +0000</pubDate>
      <link>https://dev.to/thekashey/why-what-how-framework-24gd</link>
      <guid>https://dev.to/thekashey/why-what-how-framework-24gd</guid>
      <description>&lt;p&gt;"We cannot solve our problems with the same thinking that created them" – Albert Einstein&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is Why→What→How, as well as Why←What←How. &lt;br&gt;
A way you move forward, and the way you take a step back.&lt;br&gt;
You will see.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  An evil Jinn
&lt;/h1&gt;

&lt;p&gt;Once upon a time I've used &lt;a href="https://dev.to/thekashey/the-duck-tales-ihi"&gt;a concept of an Evil Jinn&lt;/a&gt;, which turns your wishes against you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;😎: &lt;em&gt;(why)&lt;/em&gt; have no idea why, but...&lt;/li&gt;
&lt;li&gt;😎: &lt;em&gt;(what)&lt;/em&gt; I want to be rich!&lt;/li&gt;
&lt;li&gt;🧞‍♂️: &lt;em&gt;(how)&lt;/em&gt; There are many different ways to make your wish come true. I'll pick the most painful one.&lt;/li&gt;
&lt;li&gt;🧞‍♂️: so, here you go. You are rich as Scrooge McDuck. Because &lt;strong&gt;you are&lt;/strong&gt; Scrooge McDuck. Well, exactly as you commanded, master. Have a good day, quack. &lt;em&gt;Quack 🤣, gosh, another looser&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;😎: 😟, hey! wait! I didn*x$ssshhh 💨. Quack!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what happens when your goal is &lt;code&gt;what&lt;/code&gt; and you are not thinking about &lt;code&gt;how&lt;/code&gt;. You gave too much power to the 🧞‍♂️, haven't explained constraints and the detailed requirements.&lt;/p&gt;

&lt;p&gt;👉 Take a step back. Try to find &lt;code&gt;why&lt;/code&gt; you want to be rich. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is a whole film about this - &lt;a href="https://en.wikipedia.org/wiki/Bedazzled_(2000_film)" rel="noopener noreferrer"&gt;Bedazzled&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--S1O1YYQE--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pwe6mew037skc82k01k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--S1O1YYQE--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pwe6mew037skc82k01k.jpg" alt="Bedazzled"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Frameworks
&lt;/h1&gt;

&lt;p&gt;There are many other widely known frameworks developed to help you avoid painful consequences of unwise decisions. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/OKR" rel="noopener noreferrer"&gt;OKR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/SMART_criteria" rel="noopener noreferrer"&gt;SMART&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;and &lt;a href="https://www.ccl.org/articles/leading-effectively-articles/closing-the-gap-between-intent-and-impact/" rel="noopener noreferrer"&gt;SBI&lt;/a&gt;.
All have a purpose to help you structure something from "end to end" and "understand better".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example - understand what you truly desire and what is truly required. And separate one from another.&lt;/p&gt;

&lt;h2&gt;
  
  
  OKR
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/OKR" rel="noopener noreferrer"&gt;Objectives and key results&lt;/a&gt; is a goal-setting framework for defining and tracking objectives and their outcomes. Used to run many businesses and make planning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;OKRs comprise an objective, clearly defined goal and 3–5 key-result specific measures used to track the achievement of that goal. The goal of OKR is to define how to achieve objectives through concrete, specific and measurable actions. The key benefits of OKRs are focus, alignment and engagement.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The biggest difference OKR and his best friend &lt;a href="https://en.wikipedia.org/wiki/Performance_indicator" rel="noopener noreferrer"&gt;KPI&lt;/a&gt; (often used together) is the last point - focus, alignment and engagement.&lt;br&gt;
&lt;code&gt;Key Performance Indicator&lt;/code&gt; alone is a subject for &lt;a href="https://en.wikipedia.org/wiki/Goodhart%27s_law" rel="noopener noreferrer"&gt;Goodhart's law&lt;/a&gt;, which is derived from the &lt;a href="https://en.wikipedia.org/wiki/Uncertainty_principle" rel="noopener noreferrer"&gt;Heisenberg's Uncertainty principle&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Any observed statistical regularity will tend to collapse once pressure is placed upon it for control purposes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words - &lt;code&gt;key results&lt;/code&gt; without an &lt;code&gt;objective&lt;/code&gt; is a road to Hell.&lt;/p&gt;

&lt;p&gt;OKR can be read as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WHAT you want to achieve. "I want to be rich!" 😎&lt;/li&gt;
&lt;li&gt;WHY you want it. "It will let me buy a new car!!"&lt;/li&gt;
&lt;li&gt;HOW to do it. Not able to give you an advice, but here is multiple steps, &lt;code&gt;key results&lt;/code&gt;, which will lead you to the goal.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;and that's a very poorly designed OKR 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's very important to distinguish the &lt;code&gt;goal&lt;/code&gt; and the &lt;code&gt;result&lt;/code&gt;. True Goal should be a &lt;code&gt;direction&lt;/code&gt;, not something that you can achieve. &lt;br&gt;
👉 If you can achieve it - it is a key result. Just a step on the way to the goal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feaa4indpom4m0t9dsot1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Feaa4indpom4m0t9dsot1.jpg" alt="life is a journey not a destination"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Life is a journey not a destination:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key Results are the &lt;strong&gt;journey&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Objective is the &lt;strong&gt;destination&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  SMART
&lt;/h3&gt;

&lt;p&gt;S.M.A.R.T. - is very alike Fallout &lt;a href="https://en.wikipedia.org/wiki/Fallout_(video_game)#SPECIAL_system" rel="noopener noreferrer"&gt;SPECIAL&lt;/a&gt;, but for project management. A &lt;em&gt;mnemonic acronym&lt;/em&gt;, and a very role-playing in both cases.&lt;br&gt;
SMART is a way you can describe your &lt;code&gt;objective&lt;/code&gt;. The definition should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specific – target a specific area for improvement.&lt;/li&gt;
&lt;li&gt;Measurable – quantify or at least suggest an indicator of progress.&lt;/li&gt;
&lt;li&gt;Assignable – specify who will do it.&lt;/li&gt;
&lt;li&gt;Realistic – state what results can realistically be achieved, given available resources.&lt;/li&gt;
&lt;li&gt;Time-related – specify when the result(s) can be achieved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So your objective should not be just "I want to be rich!", it should be a little SMARTer. At least more &lt;em&gt;Realistic&lt;/em&gt;, and &lt;em&gt;Time-related&lt;/em&gt; - you probably want to be rich today, not 70-y years later.&lt;/p&gt;

&lt;p&gt;🧞‍♀️ is waiting for your mistake, looking for every missed detail in your &lt;code&gt;WHAT&lt;/code&gt; he could use against you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmlysk865cxrno6012xxh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmlysk865cxrno6012xxh.jpg" alt="You can't just define an objective"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another important moment about SMART, as it pointed by authors a few times:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is the &lt;strong&gt;combination&lt;/strong&gt; of the &lt;code&gt;objective&lt;/code&gt; and its &lt;code&gt;action&lt;/code&gt; plan that is really important. Therefore serious management should focus on these twins and not just the objective. &lt;em&gt;Thank you Wikipedia.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Which is again - an &lt;code&gt;objective&lt;/code&gt; without &lt;code&gt;key results&lt;/code&gt; is not  something good.&lt;/p&gt;




&lt;p&gt;There are more &lt;em&gt;mnemonic acronym&lt;/em&gt; based approaches&lt;/p&gt;

&lt;h4&gt;
  
  
  SMARTer or SMARTAA
&lt;/h4&gt;

&lt;p&gt;A smarter SMART with more features &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trackable and Agreed&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  CLEAR
&lt;/h4&gt;

&lt;p&gt;Collaborative, Limited, Emotional, Appreciable, Refinable&lt;/p&gt;

&lt;h4&gt;
  
  
  SIMple goal framework
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Specific&lt;/li&gt;
&lt;li&gt;Important&lt;/li&gt;
&lt;li&gt;Measurable&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  RISK
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Requirements&lt;/li&gt;
&lt;li&gt;Information&lt;/li&gt;
&lt;li&gt;Suppositions&lt;/li&gt;
&lt;li&gt;Knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Requirements: what is the expected result of this project&lt;/p&gt;

&lt;p&gt;Information: is all the information clear about what I need to do and all it’s parts&lt;/p&gt;

&lt;p&gt;Suppositions: are my assumptions true? Is there any flawed assumptions?&lt;/p&gt;

&lt;p&gt;Knowledge: do I have the required knowledge to understand and solve the problem? Do I need to learn something new?&lt;/p&gt;

&lt;h4&gt;
  
  
  SPEAKING
&lt;/h4&gt;

&lt;p&gt;Setting and Scene, Participants, Ends, Acts sequence, Key, Instrumentalities, Norms, &amp;amp; Genre&lt;/p&gt;

&lt;h2&gt;
  
  
  SBI
&lt;/h2&gt;

&lt;p&gt;The Situation-Behavior-Impact Model (SBI) was created to provide a better feedback - make it &lt;em&gt;structured&lt;/em&gt;, reduce the anxiety of delivering feedback and also reduce the defensiveness of the recipient. &lt;br&gt;
The SBI feedback model is simple and direct: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you capture and clarify the &lt;code&gt;Situation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;describe the specific &lt;code&gt;Behaviors&lt;/code&gt; observed&lt;/li&gt;
&lt;li&gt;and explain the &lt;code&gt;Impact&lt;/code&gt; that the person’s behavior had on you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;today&lt;/code&gt;, &lt;code&gt;after reading this article&lt;/code&gt;, &lt;code&gt;I liked it&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yesterday during the meeting&lt;/code&gt;, &lt;code&gt;your internet connection was unstable&lt;/code&gt;, &lt;code&gt;we lost you&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;last year&lt;/code&gt;, &lt;code&gt;we had a lunch together&lt;/code&gt;, &lt;code&gt;you will owe me&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sounds too simple and almost obvious but this is the goal - provide you with a framework to make so. You don't have to think much about the SBI - just follow the pattern.&lt;/p&gt;

&lt;p&gt;The hack is: Situation/Behavior/Impact is the same thing as Arrange/Act/Assert!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AAA: First you set up all the data you need for your example (Arrange), then you call the method under test (Act), then you verify the output was up to your standard (Assert).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;First explain all the circumstances (Situation/Arrange), then you explain what the individual did (Behavior/Act), then you explain how it ended (Impact/Assert). &lt;br&gt;
And yes, this means that the “system under test” is the individual.&lt;/p&gt;

&lt;p&gt;SBI(as well as tests) can be viewed differently if flip it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to cause an &lt;code&gt;Impact&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Which &lt;code&gt;behaviour&lt;/code&gt; I should use&lt;/li&gt;
&lt;li&gt;In which &lt;code&gt;situations&lt;/code&gt; it will work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then you can work towards creating such situation. You know what you have to do.&lt;/p&gt;

&lt;p&gt;🤔 Not much difference from OKR - moving towards some goal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F50d4d1fgbfayogkbg0u0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F50d4d1fgbfayogkbg0u0.png" alt="Which way?"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;And here we go. Let's try to derive a new system from the existing ones.&lt;/p&gt;

&lt;h1&gt;
  
  
  WHY/WHAT/HOW
&lt;/h1&gt;

&lt;p&gt;I did not invent WWH. It was in use by therapists, especially Psychotherapy for ages. As well as detectives, marketologs, analysts and so on used it.&lt;/p&gt;

&lt;p&gt;To be honest I never had any therapy, but from many different films I know that their job is to explain &lt;em&gt;WHY you are you&lt;/em&gt;. WHY you are doing that, not this. Their job is to find root of your behaviour and explain it to you. Hello Sigmund Freud my old friend.&lt;/p&gt;

&lt;p&gt;But we are not here for the therapy. Right?&lt;/p&gt;




&lt;p&gt;My grandfather knew what he needs, and usually was asking his grandsons to help him.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every time he asked us to do something, my brother was doing exactly &lt;strong&gt;WHAT&lt;/strong&gt; he was told to do.&lt;/li&gt;
&lt;li&gt;and I was asking &lt;strong&gt;WHY&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;And it was way faster to do &lt;em&gt;that something&lt;/em&gt;, than to explain me why it’s needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's ok, and sometimes you need to do what you were told to do. But it's better to think what you are doing, how you are doing it, and why.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Why was the change made this way?&lt;/li&gt;
&lt;li&gt;How does it help?&lt;/li&gt;
&lt;li&gt;Is it working as we want?&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's imagine you are looking at the code. You can see only &lt;code&gt;how&lt;/code&gt; it was written. Then you understand &lt;code&gt;what&lt;/code&gt; was made, and then you can think about &lt;code&gt;why&lt;/code&gt; it was made.&lt;br&gt;
You are real detective 🕵️‍♀️!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Every time I ask my kids to clean the house - am not expecting questions like &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"WHY". To keep it clear, dummy!&lt;/li&gt;
&lt;li&gt;"WHAT". What?! Clean the house!&lt;/li&gt;
&lt;li&gt;“HOW”? "How" is ok, as long as there are many ways to keep it clean, and, ok, you can skip mopping today.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jokes apart - &lt;strong&gt;why should always come first&lt;/strong&gt;. After you have a reason, a target to reach - "I like the house to be tidy",- you might find a way to fulfil it, probably home chores are the solution; and then find an exact way to do it (vacuum, mopping, and so on).&lt;/p&gt;

&lt;p&gt;Recently our kids at last got the point - we didn't ask them to do home chores (which are &lt;code&gt;how&lt;/code&gt;). We wanted their rooms to be clean (which is &lt;code&gt;what&lt;/code&gt;). They did not yet understand &lt;code&gt;why&lt;/code&gt; we need it, but already can act more thoughtfully, keeping everything constantly tidy and not spending too much time on chores.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;WHY&lt;/code&gt; is like - you &lt;strong&gt;want&lt;/strong&gt; the iPhone 12. But... why? Do you really need it?&lt;br&gt;
So you will be told why you need it, and why you can't live without it any longer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Go To the Apple Store! Now!&lt;br&gt;
This is &lt;code&gt;how&lt;/code&gt; you can get ~that~&lt;code&gt;what&lt;/code&gt; thing, and click thing button to watch our &lt;code&gt;why&lt;/code&gt; presentation one more time 😉&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcfdl90pgjmp6xcy0ow25.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcfdl90pgjmp6xcy0ow25.jpeg" alt="iphone meme"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;There is the same point, from a different perspective - from a Start With Why. Like this is “why” you are buying an iPhone every year - you believe in Apple's stories. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7a501ktaqeempfpsolze.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7a501ktaqeempfpsolze.png" alt="Start with Why"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What
&lt;/h2&gt;

&lt;p&gt;What is a problem? I mean - &lt;code&gt;what&lt;/code&gt; is a problem. &lt;code&gt;What&lt;/code&gt; is what people tend to start from. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we want that no matter why&lt;/li&gt;
&lt;li&gt;Let's do it! I have no idea why&lt;/li&gt;
&lt;li&gt;I WANT TO BE RICH! &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But &lt;code&gt;why&lt;/code&gt;? Is there any reason? You might want to buy a new house? Why? Might be you need more space? Why?&lt;/p&gt;

&lt;p&gt;👉 Every time you &lt;code&gt;what&lt;/code&gt; - make a step back and find your &lt;code&gt;why&lt;/code&gt;. Only then make a step forward to &lt;code&gt;how&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That’s a standard trick, especially in movies - when someone is going to do something - as them &lt;code&gt;why&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And then the bad guy will start a long monolog explaining his devil plans and the reasons to nuke the city. Got enough popcorn?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj4t7t6sg8v4rjang6osq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj4t7t6sg8v4rjang6osq.jpg" alt="Why oh Why"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What is always the least valuable thing. It is in between of WHY and HOW.&lt;/p&gt;

&lt;h2&gt;
  
  
  How
&lt;/h2&gt;

&lt;p&gt;And &lt;code&gt;how&lt;/code&gt; is always different. How is the end and the beginning (remember - this is Why→What→How, as well as Why←What←How).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript is "how". It's not going to fix anything without  a &lt;em&gt;fixable&lt;/em&gt; subject.&lt;/li&gt;
&lt;li&gt;GraphQL is "how". This is how you talk to server, but not "why"&lt;/li&gt;
&lt;li&gt;Expensive Nikon Camera is "how". You can picture the same "what" using your phone. So &lt;code&gt;why&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Almost any other technological solution is a senseless "how" without an &lt;code&gt;Objective&lt;/code&gt; and &lt;code&gt;Reason&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Refer back to the other models and try to understand that it is all One Question. A holistic point of view.&lt;/p&gt;

&lt;p&gt;Note the difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How are you doing
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpibinpyt0ewd37w7i5zp.jpg" alt="How"&gt;
&lt;/li&gt;
&lt;li&gt;What you are doing
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmpu0u15279zni40gg4dq.jpg" alt="What"&gt;
&lt;/li&gt;
&lt;li&gt;Why you are doing
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3b0kdcc3zrhi5gqcbm04.png" alt="Why"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  How can this help you?
&lt;/h1&gt;

&lt;h3&gt;
  
  
  It can help you code
&lt;/h3&gt;

&lt;p&gt;Coding is &lt;code&gt;how&lt;/code&gt;. Keep in mind &lt;code&gt;what&lt;/code&gt; while you are doing it (and &lt;code&gt;it&lt;/code&gt; is &lt;code&gt;what&lt;/code&gt; as well).&lt;br&gt;
Don't think much "what you are writing", think "what you are doing". That will protect you from refactoring for the sake of refactoring, hooks for hooks, speed for speed.&lt;/p&gt;

&lt;p&gt;This is something OKR is about - to keep the right direction &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"It is the __combination&lt;/em&gt;_ of the &lt;code&gt;objective&lt;/code&gt; and its &lt;code&gt;action&lt;/code&gt; plan that is really important"_. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Planning is &lt;code&gt;what&lt;/code&gt;. &lt;code&gt;What&lt;/code&gt; is something to do, something you are doing, or done. An &lt;code&gt;objective&lt;/code&gt;.&lt;br&gt;
But how to decide what to do? Find the most and least important, and even define the way to calculate the importance?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Why&lt;/code&gt; is usually a missing part. Start from it, and end on it.
&lt;/h2&gt;

&lt;p&gt;React, Angular, Vue - they are different &lt;code&gt;how&lt;/code&gt;, different &lt;code&gt;why&lt;/code&gt;, but the same &lt;code&gt;what&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;What&lt;/code&gt; is something user might experience, and it does not matter &lt;code&gt;how&lt;/code&gt; it is made.&lt;/p&gt;

&lt;p&gt;However - make a step back - why you should pick one framework, but not another? It's not only about customer experience, but developer experience, and (sometime the main) business needs and requirements.&lt;/p&gt;

&lt;p&gt;A single &lt;code&gt;what&lt;/code&gt; might driven by different &lt;code&gt;why&lt;/code&gt;. One &lt;code&gt;why&lt;/code&gt; can create any &lt;code&gt;what&lt;/code&gt;. There is an infinite number of &lt;code&gt;how&lt;/code&gt; you can actually implement it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There is another mental concept here - &lt;a href="https://en.wikipedia.org/wiki/Blind_men_and_an_elephant" rel="noopener noreferrer"&gt;blind men and an elephant&lt;/a&gt; - which is about a single thing(an elephant), can be described in many ways.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--4gJL4jdd--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnzv5asba07hmlwkzdiy6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fpracticaldev%2Fimage%2Ffetch%2Fs--4gJL4jdd--%2Fc_limit%252Cf_auto%252Cfl_progressive%252Cq_auto%252Cw_880%2Fhttps%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnzv5asba07hmlwkzdiy6.jpg" alt="blind men and an elephant"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;ul&gt;
&lt;li&gt;You can have a problem to solve - it's &lt;code&gt;why&lt;/code&gt;. &lt;strong&gt;Take a step forward&lt;/strong&gt; and find &lt;code&gt;what&lt;/code&gt; you can do to solve it.&lt;/li&gt;
&lt;li&gt;You can have an idea - it is &lt;code&gt;what&lt;/code&gt;. &lt;strong&gt;Take a step back&lt;/strong&gt; to double-check does it worth it, and &lt;strong&gt;then step forward&lt;/strong&gt; to find a way to make it real.&lt;/li&gt;
&lt;li&gt;You can just want to apply something, try a new language or framework, play around... solve something in a better way? It's &lt;code&gt;how&lt;/code&gt;, and it need &lt;code&gt;what&lt;/code&gt; and &lt;code&gt;why&lt;/code&gt;
&amp;gt; except you just enjoy doing it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Too many people are just doing. Using Redux because they were told to. Not understanding CSS or CAS theorem. Focused only on the code.&lt;/p&gt;

&lt;p&gt;Too many people are just doing a thing. No matter how, and it ends as a technical debt nightmare. But we are building a cool this? Sure?&lt;/p&gt;

&lt;p&gt;Too many people are after "why". They might truly believe that it's a good reason... to start a war for example. This is not &lt;code&gt;how&lt;/code&gt; you should resolve problems and not &lt;code&gt;what&lt;/code&gt; you have to do.&lt;/p&gt;

&lt;p&gt;This all working only holistically.&lt;/p&gt;

&lt;h1&gt;
  
  
  Technical and non-functional requirement
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Non-functional_requirement" rel="noopener noreferrer"&gt;Wikipedia defines&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;Broadly, &lt;code&gt;functional requirements define what a system is supposed to do&lt;/code&gt; and &lt;code&gt;non-functional requirements define how a system is supposed to be&lt;/code&gt;. &lt;br&gt;
Functional requirements are usually in the form of "system shall do ", an individual action or part of the system, perhaps explicitly in the sense of a mathematical function, a &lt;strong&gt;black box description&lt;/strong&gt; input, output, process and control functional model or IPO Model. &lt;br&gt;
In contrast, non-functional requirements are in the form of "system shall be ", an overall property of the system as a whole or of a particular aspect and not a specific function. The system's overall properties commonly mark the difference between whether the development project has succeeded or failed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functional requirements is &lt;code&gt;what&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;non-functional requirements is &lt;code&gt;how&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;👉 both are not &lt;code&gt;why&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Let me be short - this is a stock photo about "talking therapy".&lt;br&gt;
On the left is your spaghetti code, and on the right is Why/What/How&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb5ftzr5lnkacyshildf7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb5ftzr5lnkacyshildf7.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's really that simple.&lt;/p&gt;

&lt;p&gt;PS: Read &lt;a href="https://dev.to/thekashey/the-duck-tales-ihi"&gt;the Duck Tales&lt;/a&gt; for more mental models you can apply as a software engineer.&lt;/p&gt;

&lt;p&gt;PPS: And “Start With Why” talk - &lt;a href="https://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action" rel="noopener noreferrer"&gt;https://www.ted.com/talks/simon_sinek_how_great_leaders_inspire_action&lt;/a&gt; - the same idea, different order.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;🤔 &lt;code&gt;why&lt;/code&gt; did I write this post? I know &lt;code&gt;what&lt;/code&gt; I wrote, and &lt;code&gt;how&lt;/code&gt; I wrote it, but &lt;code&gt;why&lt;/code&gt;.........&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>statemachines</category>
    </item>
    <item>
      <title>You dont need CSS-in-JS #2: What?</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Thu, 19 Mar 2020 10:02:51 +0000</pubDate>
      <link>https://dev.to/thekashey/you-dont-need-css-in-js-2-what-13k4</link>
      <guid>https://dev.to/thekashey/you-dont-need-css-in-js-2-what-13k4</guid>
      <description>&lt;p&gt;In the first part, I've tried to explain what &lt;code&gt;CSS-in-JS&lt;/code&gt; is nothing more than a &lt;strong&gt;style delivery system&lt;/strong&gt;, not &lt;strong&gt;style system&lt;/strong&gt;, and you actually don't need it.&lt;br&gt;
The question - why do you actually need?&lt;/p&gt;

&lt;h1&gt;
  
  
  What's the goal?
&lt;/h1&gt;

&lt;p&gt;There are 3 things you might need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ship the result as fast as possible. Bussiness would appreciate. Common rumours usually tangle CSS-in-JS and Dev speed, however, I am not sure why they are tanged.&lt;/li&gt;
&lt;li&gt;make something reusable. Like build your own UI Library (everybody builds their UI Libraries nowadays), and by some reason it's like HAVE TO BE written using CSS-in-JS. Don't ask me why.&lt;/li&gt;
&lt;li&gt;share that UI library across different product and teams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is also one, or two more things, which you also need, but they were not present in the list above, and the majority ignores their absence.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;client side performance. It should be fast. My kids still use IPad Mini 2 (5 years old), my mother-in-law uses some laptop which was cheap 5 years ago, and not it's almost not working...&lt;/li&gt;
&lt;li&gt;server side performance. It should not cost you much, as well as SSR is working better then it's FAST.&lt;/li&gt;
&lt;li&gt;you should understand what you are doing, and how it would work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And actually, the last point is the most important one. And it's not bound to CSS-in-JS or -CSS.&lt;/p&gt;

&lt;p&gt;I urge you to ​read this presentation - &lt;a href="https://slides.com/davidkhourshid/dotcss2019#/"&gt;Crafting Stateful Styles&lt;/a&gt; - about rethinking WHAT to write inside CSS. Like one more methodology.&lt;/p&gt;

&lt;p&gt;Let's go deeper&lt;/p&gt;

&lt;h2&gt;
  
  
  Your style is not a collection of props
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; color: while
 {(props) =&amp;gt; props.isPrimary &amp;amp;&amp;amp; `color:blue`}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Sounds familiar? Sounds terrible! There is no way to predict how your styles would look like with some random set of props, and many different combinations are possible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.bem.info/methodology/css/#modifiers"&gt;BEM&lt;/a&gt;(CSS) as well as &lt;a href="https://github.com/danieldelcore/trousers"&gt;trousers&lt;/a&gt;(CSS-in-JS) has an idea of "modifiers" which are a more "static" and predictable way to handle complex styles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reusability is about separation
&lt;/h2&gt;

&lt;p&gt;This is something people are usually missing in CSS-in-JS - a "methodology", like SMACSS, BEM and visa versa.&lt;br&gt;
And the core idea of probably all those metodologies (but not technologies) is separation - a separation between Block and Elements, as well as State and Theme in SMACSS.&lt;/p&gt;

&lt;p&gt;Every element would be "constructed" from different style pieces, and expect you do add a few more pieces to complete the picture.&lt;/p&gt;

&lt;p&gt;For example in BEM terms &lt;code&gt;Button&lt;/code&gt; is a &lt;code&gt;Block&lt;/code&gt;. And &lt;code&gt;Block&lt;/code&gt; may not define &lt;code&gt;dimensions&lt;/code&gt;. That leads to the expectation that you will &lt;em&gt;consume&lt;/em&gt; &lt;code&gt;Button&lt;/code&gt; as an &lt;code&gt;Element&lt;/code&gt; of your component. And &lt;code&gt;Element&lt;/code&gt; might define &lt;code&gt;dimensions&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Block&lt;/code&gt; styles are meeting &lt;code&gt;Element&lt;/code&gt; styles and forming a Voltron&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In JS we are talking about reusability, composition and all that stuff. In CSS there is the same stuff, just use it.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion​
&lt;/h1&gt;

&lt;p&gt;CSS is not your friend, and CSS-in-JS is not your foe. People saying you should use X, but not Y - are your enemies.​&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And all the people saying you should use CSS-in-JS, not CSS are just victims.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's not about the technologies, but about the way you use them.&lt;br&gt;
About the reason to use in one or another way.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;are you getting any feasible improvements from Y&lt;/li&gt;
&lt;li&gt;are you sure, any number or at least theoretical proofs?&lt;/li&gt;
&lt;li&gt;what would change in a year? I am speaking of tech debt.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>You dont need CSS-in-JS #1: Why?</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Thu, 19 Mar 2020 10:02:43 +0000</pubDate>
      <link>https://dev.to/thekashey/you-dont-need-css-in-js-1-why-3eo9</link>
      <guid>https://dev.to/thekashey/you-dont-need-css-in-js-1-why-3eo9</guid>
      <description>&lt;p&gt;The cover image was taken from another article, named exactly the same &lt;a href="https://www.freecodecamp.org/news/you-dont-need-css-in-js-why-i-use-stylesheets/" rel="noopener noreferrer"&gt;You Don't Need CSS-in-JS: Why (and When) I Use Stylesheets Instead&lt;/a&gt; by &lt;a class="mentioned-user" href="https://dev.to/colbyfayock"&gt;@colbyfayock&lt;/a&gt;, however there are not much articles like that (except &lt;a href="https://dev.to/colbyfayock/you-don-t-need-css-in-js-why-i-use-stylesheets-20"&gt;this one - You Don't Need CSS-in-JS&lt;/a&gt;, which uses the same image and, well, the same author 😎), or like this - usually &lt;strong&gt;everybody praises CSS-in-JS&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why CSS-in-JS is so COOL?!
&lt;/h1&gt;

&lt;p&gt;Because it's much better than just CSS, according to the other authors:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/rleija_" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F38217%2F881477fe-a3d7-4dad-8549-aba8ce584c7d.jpg" alt="rleija_"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/rleija_/5-reasons-to-go-with-css-in-js-for-your-next-application-43m" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;5 reasons to go with CSS in JS for your next application&lt;/h2&gt;
      &lt;h3&gt;Ruben ・ Mar 19 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Global namespace
&lt;/h2&gt;

&lt;p&gt;Like CSS &lt;em&gt;shits&lt;/em&gt; into the global namespace, while CSS-in-JS provides you an "encapsulation" plus "isolation.&lt;/p&gt;

&lt;p&gt;👉 use CSS Modules, they are providing the same level of the thing above, and in the &lt;strong&gt;exactly the same way&lt;/strong&gt; - "hashing" classNames, so they would never conflict.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implicit dependencies
&lt;/h2&gt;

&lt;p&gt;By which different authors imply &lt;del&gt;technologies&lt;/del&gt; methodologies like &lt;code&gt;BEM&lt;/code&gt;, &lt;code&gt;SMACSS&lt;/code&gt; or &lt;code&gt;Atomic&lt;/code&gt; CSS, which might help you to &lt;strong&gt;to reduce the lack of built-in scoping mechanism&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;👉 please go read about these methodologies again. They have nothing with "scope" and "namespacing", only with &lt;strong&gt;separation of conserns&lt;/strong&gt;, the majority of &lt;code&gt;CSS-in-JS&lt;/code&gt; believers truly understand.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dead code elimination
&lt;/h2&gt;

&lt;p&gt;Like in CSS-in-JS you can have your styles next to your component, and delete them as you delete your component. For example. It might also be just about styles no longer in use.&lt;/p&gt;

&lt;p&gt;Is it true? With &lt;code&gt;CSSModules&lt;/code&gt; you refer to your styles as &lt;code&gt;styles.someClass&lt;/code&gt;, making the fact of usage explicit, and it should be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;not a problem to delete &lt;code&gt;Component.scss&lt;/code&gt; when you delete &lt;code&gt;Component.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;not a problem to track which styles are used, and which are not. That's a linting/IDE problem, not something bound to the technology itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 that's not a problem of technology. That's problem of your code style&lt;/p&gt;

&lt;h2&gt;
  
  
  Minification
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;CSS out of the box doesn’t have a feature to minify code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As well as for &lt;code&gt;JavaScript&lt;/code&gt;. It's faster to fix the problem, that to talk about it.&lt;br&gt;
Even more - usually CSS minification happends on the &lt;code&gt;css-chunk&lt;/code&gt; level, which may contain many &lt;code&gt;.css&lt;/code&gt; files, which may contain styles for many components. Read - it WAY MORE EFFICIENT.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sharing constants
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CSS-in-JS&lt;/code&gt; is quite good with it. It's easy to share &lt;code&gt;js&lt;/code&gt; constants.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LESS&lt;/code&gt;/&lt;code&gt;SASS&lt;/code&gt; is not worse - it's easy to share constants from CSS-&amp;gt;to-&amp;gt;JS, and back using webpack loaders.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 ... and yes - usually everyone is talking about &lt;strong&gt;constants&lt;/strong&gt;, not dynamic variables.&lt;/p&gt;

&lt;p&gt;People use &lt;code&gt;CSS-in-JS&lt;/code&gt; to create dynamic styles, and share some variables from JS. Like &lt;code&gt;gridSize&lt;/code&gt; or &lt;code&gt;whiteColor&lt;/code&gt;, or &lt;code&gt;margin-left&lt;/code&gt;. They are using dynamic nature if CSS-in-JS to create static styles, which will be never changed in runtime. The &lt;code&gt;night mode&lt;/code&gt; included. It could no more than a media query - it's more about your code style.&lt;/p&gt;
&lt;h1&gt;
  
  
  Let's double-check
&lt;/h1&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/mxstbr"&gt;@mxstbr&lt;/a&gt;, creator of &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;Styles Components&lt;/a&gt; once wrote an article &lt;a href="https://mxstbr.com/thoughts/css-in-js" rel="noopener noreferrer"&gt;Why I Write CSS in JavaScript&lt;/a&gt;. So Why?&lt;/p&gt;
&lt;h2&gt;
  
  
  CSS-in-JS boosts my confidence
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I can add, change and delete CSS without any unexpected consequences. My changes to the styling of a component will not affect anything else. If I delete a component, I delete its CSS too. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 &lt;code&gt;CSSModules&lt;/code&gt;. Full Stop.&lt;/p&gt;
&lt;h2&gt;
  
  
  keeps our codebase clean and lets us move quicker
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;With CSS-in-JS, we automatically sidestep common CSS frustrations such as class name collisions and specificity wars...regardless of experience levels.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 No, only &lt;strong&gt;methodologies&lt;/strong&gt; prevents &lt;code&gt;specificity wars&lt;/code&gt;, as well as helping moving forward &lt;em&gt;regardless of experience levels&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;C'mon - it's possible to create terrible things with CSS, and CSS-in-JS as well. Nothing stops you. That's not something CSS-in-JS could you give - that's you.&lt;/p&gt;
&lt;h2&gt;
  
  
  Keeps CSS small
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Regarding performance, CSS-in-JS libraries keep track of the components I use on a page and only inject their styles into the DOM.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 That "tracking" costs WAY more that extra work browser could perform working with a bit larget CSS tables.&lt;/p&gt;

&lt;p&gt;Just follow the best practices, which usually sounds like - &lt;strong&gt;don't use nested selectors&lt;/strong&gt;, as long as browser matches them from left to right, so they might greatly slowdown CSS engine...&lt;/p&gt;
&lt;h2&gt;
  
  
  Pit of success
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;CSS-in-JS combines all these benefits into one handy package and enforces them. It guides me to the pit of success: doing the right thing is easy, and doing the wrong thing is hard (or even impossible).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👉 That's not truth, in the moment of "right thing", and especially in the moment of "even impossible". CSS-in-JS is actually causing more chaos than helping making things "right".&lt;/p&gt;

&lt;p&gt;There are "better" versions or &lt;code&gt;CSS-in-JS&lt;/code&gt;, like &lt;a href="https://github.com/styled-system/styled-system" rel="noopener noreferrer"&gt;styled-system&lt;/a&gt; - it's a &lt;strong&gt;SYSTEM&lt;/strong&gt;, or &lt;a href="https://xstyled.dev/" rel="noopener noreferrer"&gt;xstyled&lt;/a&gt; - which is also a SYSTEM, or &lt;a href="https://github.com/danieldelcore/trousers" rel="noopener noreferrer"&gt;thousers&lt;/a&gt; - which is a real &lt;strong&gt;styling STATE MACHINE&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;However, CSS-in-JS by itself is usually nothing more than &lt;strong&gt;style delivery system&lt;/strong&gt;. It doesn't give you anything special. It's up to you how to use it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;While my .js bundles are slightly heavier, my users download the smallest possible CSS payload and avoid extra network requests for .css files.&lt;/p&gt;

&lt;p&gt;This leads to a marginally slower time to interactive, but a much quicker first meaningful paint! 🏎💨&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;CSS-in-JS&lt;/code&gt; send only the critical CSS to the user for a rapid first paint. Which is called &lt;code&gt;critical css extraction&lt;/code&gt; and not a feature of CSS-in-JS&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/thekashey" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F113306%2F18ae0122-205c-4952-8f73-240175b4ae1d.png" alt="thekashey"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/thekashey/optimising-css-delivery-57eh" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;🎨 Optimising CSS Delivery&lt;/h2&gt;
      &lt;h3&gt;Anton Korzunov ・ Oct 4 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Recap: CSS in JS benefits
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Generates minimum CSS requires, which is not required.&lt;/li&gt;
&lt;li&gt;Good runtime performance, which is way worse than with a plain CSS-in-CSS&lt;/li&gt;
&lt;li&gt;Supports dynamic styling, which you might not need&lt;/li&gt;
&lt;li&gt;Easy to pre-render important CSS, which also possible with CSS-in-CSS&lt;/li&gt;
&lt;li&gt;Letting to extract all CSS to CSS, if you want&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Recap: CSS in CSS benefits
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Generates big style chunks, which is easy to optimize in bulk.&lt;/li&gt;
&lt;li&gt;It's way faster to load and parse CSS files, than JS files&lt;/li&gt;
&lt;li&gt;Unbound caching for JS and CSS, leading to a better user experience.&lt;/li&gt;
&lt;li&gt;Letting you embed CSS in JS, if you want.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So... honestly - there is no GOOD reason to use CSS-in-JS. Probably you need something else. Something more (like a "system"), or something less(like just styles). Usually less.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
    </item>
    <item>
      <title>The Duck Tales</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Wed, 19 Feb 2020 05:31:55 +0000</pubDate>
      <link>https://dev.to/thekashey/the-duck-tales-ihi</link>
      <guid>https://dev.to/thekashey/the-duck-tales-ihi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Once upon a time I was thinking about all the stupid things and other shenanigans I've done throughout my life. Things, I never wanted to create, things I never wanted to rewrite, and things I wanted to never see again. About thoughtfulness and a bit of wisdom. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;4 things to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🦆: If it walks like a duck and it quacks like a duck, then it must be a &lt;del&gt;duck&lt;/del&gt; JavaScript &lt;a href="https://en.wikipedia.org/wiki/Duck_typing" rel="noopener noreferrer"&gt;Duck-Typing&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;🙈🙉: Our world is experienced differently by blind or deaf people, but it's still the same world, just different perspectives - &lt;a href="https://www.google.com/search?q=6+vs+9" rel="noopener noreferrer"&gt;6 vs 9&lt;/a&gt;, as well as &lt;a href="https://en.wikipedia.org/wiki/Blind_men_and_an_elephant" rel="noopener noreferrer"&gt;blind men and an elephant&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;👁: An observable system is one whose &lt;strong&gt;internal state can be deeply understood&lt;/strong&gt; just by observing its outputs.&lt;/li&gt;
&lt;li&gt;🔨: &lt;strong&gt;if all you have is a hammer, everything looks like a nail&lt;/strong&gt; - &lt;a href="https://en.wikipedia.org/wiki/Law_of_the_instrument" rel="noopener noreferrer"&gt;Law of the instrument&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Which was originally known as &lt;em&gt;"Give a boy a hammer and chisel; show him how to use them; at once he begins to hack the doorposts, to take off the corners of shutter and window frames, until you teach him a better use for them, and how to 👉keep his activity within bounds👈."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I am going to give you a really BIG HAMMER. Believe me or not, you can use it to &lt;em&gt;hammer&lt;/em&gt; literally any problem.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;church bells ringing.&lt;/li&gt;
&lt;li&gt;the appearance of a man in a tuxedo with a woman in a flowing white gown.&lt;/li&gt;
&lt;li&gt;rice flying through the air.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🙀 sounds like a wedding! // The theory behind &lt;a href="https://en.wikipedia.org/wiki/Complex_event_processing" rel="noopener noreferrer"&gt;Complex event processing&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;There is a little problem with React and Redux state. And the idea of &lt;code&gt;State&lt;/code&gt; in general - it's not necessarily a state, that's just a collection of some values - a few &lt;code&gt;key&lt;/code&gt;/&lt;code&gt;value&lt;/code&gt; pairs just met in one place and formed some &lt;code&gt;data&lt;/code&gt;. Dead data. Impossible data.&lt;/p&gt;

&lt;p&gt;Confused? Well, "confused" is your &lt;code&gt;state&lt;/code&gt;. My words have changed something inside you, and the result can be observed as a final emotional state on your face – 😕&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;But - if you &lt;em&gt;walks like a &lt;code&gt;confused&lt;/code&gt; and you quacks like a &lt;code&gt;confused&lt;/code&gt;, then you are a &lt;code&gt;confused&lt;/code&gt;&lt;/em&gt;. And everything else is implementation details 😟&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a core idea of &lt;a href="https://en.wikipedia.org/wiki/Duck_typing" rel="noopener noreferrer"&gt;Duck Typing&lt;/a&gt; and this idea will save your life. Already saved, maybe even multiple times, because &lt;em&gt;Ducking&lt;/em&gt; – is what doctors do. &lt;/p&gt;

&lt;p&gt;It's called a &lt;code&gt;triage&lt;/code&gt; – an attempt to understand the patient's state, the major problems and the minor problems, to save their lives. Just by looking at them, looking at how they walk and how they quack. Hopefully just looking first, and using surgery to get guts out only if necessary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Triage is the process of determining the priority of patients' treatments based on the severity of their condition - &lt;a href="https://en.wikipedia.org/wiki/Triage" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In short, when a patient comes – nurse checks: &lt;br&gt;
1) the patient is yet alive&lt;br&gt;
2) is not actively dying&lt;br&gt;
3) and has a medical insurance&lt;br&gt;
No insurance? Then the patient is probably healthy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it walks like a 🤒, and quacks like a 🤧 – it's 😷! Cut a leg!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just remember the last time you went to the GP - they asked you some questions, measured your temperature and pressure, and came up with some conclusion about your health problem - like &lt;code&gt;drink more water&lt;/code&gt;. Next!&lt;/p&gt;

&lt;p&gt;Usually, there are enough indicators to &lt;strong&gt;intent&lt;/strong&gt; the overall system state - is it actually in a "healthy" state(it does not matter how exactly) or it's in an "unhealthy" state(does not matter how exactly).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The goal of triage is not to heal💉, but plan the next step.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Signs, Signs are everywhere! Just read them! And dont forget to left the breadcrumbs, that’s called a good UX. And &lt;em&gt;rice flying through the air&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8niazt5qrrheghyvqux3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F8niazt5qrrheghyvqux3.jpg" alt="Signs are everywhere"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the same way doctors are able to understand what’s wrong with you JavaScript is able to understand why &lt;em&gt;undefined is not a function&lt;/em&gt;. Well, what is a function? What is an object? What is an array?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;if something has &lt;code&gt;.push&lt;/code&gt; and &lt;code&gt;.forEach&lt;/code&gt; - then it could be an &lt;code&gt;Array&lt;/code&gt;. Or, at least, something &lt;code&gt;Iteratable&lt;/code&gt;. 👉 it doesn't have to be an &lt;code&gt;Array&lt;/code&gt; - it should 🦆 as &lt;code&gt;Array&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But there is one moment - a thing could contain many different properties, implementing different interfaces, like &lt;code&gt;IDuck&lt;/code&gt;, &lt;code&gt;IQuacker&lt;/code&gt; as well as &lt;code&gt;IEggLayer&lt;/code&gt;, and duck like a &lt;code&gt;pack&lt;/code&gt;.&lt;br&gt;
This makes things a bit complicated... to explain...&lt;/p&gt;
&lt;h1&gt;
  
  
  What I am looking for?
&lt;/h1&gt;

&lt;p&gt;I personally prefer to call a principle behind this question a &lt;strong&gt;WTF principle&lt;/strong&gt; - like you are displaying your cool stuff to a friend, manager, investor or QA engineer, and they are asking you: "_So, ok that was cool, but could you please explain 👉WTF is this👈?".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Belive the old pirate - this is exactly how all your friends are thinking about your new creation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may replay in a short and sound manner - 🤬, but you know, there should be a better way to answer, and a bit more polite. &lt;br&gt;
And probably your friend, manager, investor or QA/QE need different responses.&lt;/p&gt;

&lt;p&gt;It's actually very hard to predict what these different people might &lt;strong&gt;want&lt;/strong&gt; to hear from you, it's better and much easier to understand what they &lt;strong&gt;need&lt;/strong&gt; to hear. To do this let's just imagine that they are in the same situation as you, and would have to talk about "your stuff" with someone else. Then - let's go and find the top of this food chain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💰CEO: Hey, I need you to build a new feature. I don't care how you will do it, I just trust you.&lt;/li&gt;
&lt;li&gt;😎Director: Hey, I need you to build a new feature. I don't care how you will do it, I just trust you.&lt;/li&gt;
&lt;li&gt;😸Manager: Hey, We need you to build a new feature. I don't care how you will do it, I just trust you.&lt;/li&gt;
&lt;li&gt;👻Quality: Hey, I do care how you will do, not what. And I just don't trust you.&lt;/li&gt;
&lt;li&gt;🤖Developer: 👉Hey, I've built a cool stuff👈&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is an expectation of Trust going from the top to the bottom, and no one is actually interested in the implementation details... so...&lt;/p&gt;

&lt;p&gt;So the expectations for the &lt;code&gt;backflow&lt;/code&gt; are the same - something they can &lt;strong&gt;trust&lt;/strong&gt;, and nobody interested how you actually did it - that's implementation details, not the product itself. And you were asked to create a product 😉.&lt;/p&gt;

&lt;p&gt;And "trust" means - your work shall &lt;strong&gt;meet some expectations&lt;/strong&gt;, probably unique for every level.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it walks like our &lt;code&gt;acceptance criteria&lt;/code&gt;, and quacks like &lt;code&gt;what we asked for&lt;/code&gt; – it's our &lt;code&gt;feature&lt;/code&gt;! 🚀Ship it immediately🚀!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is something you shall keep in mind -&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/thekashey" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F113306%2F18ae0122-205c-4952-8f73-240175b4ae1d.png" alt="thekashey"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/thekashey/prefer-integration-tests-think-twice-1l6d" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Prefer Integration Tests? Think twice&lt;/h2&gt;
      &lt;h3&gt;Anton Korzunov ・ Jul 29 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#testing&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codequality&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tdd&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Duck typing
&lt;/h1&gt;

&lt;p&gt;As I said above - a single thing could quack like a &lt;strong&gt;pack of ducks&lt;/strong&gt;. Let's ask every 🦆 in that pack, how it &lt;em&gt;quacks&lt;/em&gt; about a &lt;code&gt;Good Product&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;💰bussiness: It should be profitable. &lt;del&gt;My&lt;/del&gt; Your salary depends on it.&lt;/li&gt;
&lt;li&gt;🤖developer: It should be maintainable.&lt;/li&gt;
&lt;li&gt;🚀performance: Loading time can't be more than 2 seconds.&lt;/li&gt;
&lt;li&gt;🕸network: latency below 300ms.&lt;/li&gt;
&lt;li&gt;🕵️‍♀️QA: code coverage above 95%.&lt;/li&gt;
&lt;li&gt;👩‍🎤design: all margins should be the same.&lt;/li&gt;
&lt;li&gt;🚔GDPR: Ha-ha! Gotcha!&lt;/li&gt;
&lt;li&gt;👂a11y: don't forget about us&lt;/li&gt;
&lt;li&gt;🤖another developer: And it still should be fun!&lt;/li&gt;
&lt;li&gt;🕵️‍♀️QA: me again. Here are 20 &lt;strong&gt;testing notes&lt;/strong&gt; you should check your PR against, which is basically everything above. You're welcome, enjoy your day.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Yep, QA/QEs are duck typing their expectation since forever.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Long story short - if &lt;code&gt;Product&lt;/code&gt; wants to be a &lt;code&gt;Good Product&lt;/code&gt; it should meet different and &lt;strong&gt;parallel&lt;/strong&gt; expectations. For every case, there should be a simple &lt;code&gt;acceptance criteria&lt;/code&gt;, and it should be clear how to meet these requirements. &lt;br&gt;
One by one.&lt;/p&gt;



&lt;p&gt;To better understand this moment, let's take a step back, and refer to the ancient knowledge. To the &lt;a href="https://en.wikipedia.org/wiki/Blind_men_and_an_elephant" rel="noopener noreferrer"&gt;Blind men and an elephant&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnzv5asba07hmlwkzdiy6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnzv5asba07hmlwkzdiy6.jpg" alt="Blind Monks and an Elephant"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A group of blind men heard that a strange animal, called an elephant, had been brought to the town, but none of them were aware of its shape and form. Out of curiosity, they said: "We must inspect and know it by touch, of which we are capable". So, they sought it out, and when they found it they groped about it. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the case of the first person, whose hand landed on the trunk, said "This being is like a thick snake". &lt;/li&gt;
&lt;li&gt;For another one whose hand reached its ear, it seemed like a kind of fan. &lt;/li&gt;
&lt;li&gt;As for another person, whose hand was upon its leg, said, the elephant is a pillar like a tree-trunk. &lt;/li&gt;
&lt;li&gt;The blind man who placed his hand upon its side said the elephant, "is a wall". &lt;/li&gt;
&lt;li&gt;Another who felt its tail, described it as a rope. &lt;/li&gt;
&lt;li&gt;The last felt its tusk, stating the elephant is that which is hard, smooth and like a spear.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;In some versions, the blind men then discover their disagreements, suspect the others to be not telling the truth and come to blows. &lt;br&gt;
In some versions, they stop arguing, start listening and collaborate to "see" the full elephant.&lt;br&gt;
In another, a sighted man enters the parable and describes the entire elephant from various perspectives, the blind men then learn that they were all partially correct and partially wrong.&lt;/p&gt;

&lt;p&gt;👉 🦆 are the blind men and your application is an Elephant 👈&lt;/p&gt;

&lt;p&gt;You might try to describe it in various ways, and then find a whole object, matching all expectations at once.&lt;/p&gt;



&lt;p&gt;In big companies, there are different &lt;em&gt;ceremonies&lt;/em&gt;, &lt;em&gt;patterns&lt;/em&gt;, &lt;em&gt;protocols&lt;/em&gt; and &lt;em&gt;standards&lt;/em&gt; you have to meet to launch a new product. You have to pass audits and reviews, but that is... &lt;strong&gt;so boring&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There should be a better way to understand what shall be done, and thus let's recall another piece of ancient knowledge, recall what a &lt;em&gt;classic&lt;/em&gt; said (Lev Tolstoy, 1828): &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All happy families &lt;strong&gt;resemble each other&lt;/strong&gt;, &lt;br&gt;
each unhappy family is unhappy in its own way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words: happy families &lt;strong&gt;share a common set of attributes&lt;/strong&gt; which lead to happiness, while any of a variety of attributes can cause an unhappy family. &lt;/p&gt;

&lt;p&gt;This concept, known as &lt;a href="https://en.wikipedia.org/wiki/Anna_Karenina_principle" rel="noopener noreferrer"&gt;Anna Karenina principle&lt;/a&gt;, is quite fundamental and explain a lot - from animal domestication to PayPal (🤷‍♂️ according to Wikipedia)&lt;/p&gt;

&lt;p&gt;And you know - All happy families resemble each other, as well as All &lt;strong&gt;Little Black Rain Clouds&lt;/strong&gt; resemble each other. There is no difference.&lt;br&gt;
They are all black, rainy, and not as small as that bear. Oh, that's a bear!!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F536se7jdb5sj3sdfu1rl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F536se7jdb5sj3sdfu1rl.png" alt="Pooh the Little Black Rain Cloud"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And again, it's a subtype of Duck Typing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We will return to the &lt;code&gt;little&lt;/code&gt;+&lt;code&gt;black&lt;/code&gt;+&lt;code&gt;rain&lt;/code&gt;+&lt;code&gt;clouds&lt;/code&gt; later, as well as check why the &lt;code&gt;green great dragon&lt;/code&gt; cannot exist...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Behaviour
&lt;/h1&gt;

&lt;p&gt;Let's try to formalize Duck Typing for some Application. Should be pretty straightforward (if not - we are doing something wrong):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's imagine you are a QE, and I am demoing my stuff to you&lt;/li&gt;
&lt;li&gt;Then, when I press that button&lt;/li&gt;
&lt;li&gt;Something magical should happen (and not an explosion)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not quite formal? What about this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: "localhost:8080/my-cool-app"
opened in a Google Chrome

When: I press the Big Blue Button

Then: "Hello World" is displayed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That might look like &lt;a href="https://en.wikipedia.org/wiki/Behavior-driven_development" rel="noopener noreferrer"&gt;BDD testing&lt;/a&gt;, with all those &lt;code&gt;Given/When/Then&lt;/code&gt;, but it's actually Duck Typing, again and again.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: a 🦆
When: you kick the 🦆
Then: it quacks
So: 🦆 is alive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This principle also is known as &lt;a href="https://en.wikipedia.org/wiki/Smoke_testing_(software)" rel="noopener noreferrer"&gt;smoke tests&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;an acceptance test is preliminary testing to reveal simple failures severe enough to, for example, reject a prospective software release. Smoke tests are a subset of test cases that cover the most important functionality of a component or system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Let's write a bit more tests
&lt;/h2&gt;

&lt;p&gt;What would you say about this one?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: a 🥛 glass of water
Then: it's full
When: you take a sip
Then: it's 70% full

When: you take a sip
Then: it's 40% full

When: you take a sip
Then: 🥛 glass is empty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Probably there are some implementation details. Like 30/30/40 per cent of the water sipped every time. That's too fragile&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: a 🥛 full glass of water
When: you take 3 sips
Then: 🥛 glass is empty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Much more compact, and sound.&lt;/p&gt;
&lt;h2&gt;
  
  
  6 vs 9 ?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;6/9&lt;/code&gt; is about different perspectives. Like the 🥛glass could be 50% full as well as 50% empty.&lt;br&gt;
What if the same actions affect more that one thing?&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: you are thirsty 
When: you take 3 sips
Then: you are full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Of course! You action affects not only a 🥛glass, but you as well.&lt;br&gt;
Another example? The opposite this time.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: 🌏 is spinning
When: you take 3 sips
Then: 🌏 is still spinning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;All our tests&lt;/strong&gt; are the same:&lt;/p&gt;
&lt;h4&gt;
  
  
  Given
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;you open some &lt;code&gt;Page&lt;/code&gt;, or mount some &lt;code&gt;Component&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;you provide some &lt;code&gt;data&lt;/code&gt;, or some &lt;code&gt;props&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  When
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;you click somewhere&lt;/li&gt;
&lt;li&gt;you change some props or data&lt;/li&gt;
&lt;li&gt;you perform some action&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Then
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;you again check something&lt;/li&gt;
&lt;li&gt;you expect to be "somewhere"
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Given 👉 When 👉 Then
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1219963656089341952-624" src="https://platform.twitter.com/embed/Tweet.html?id=1219963656089341952"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1219963656089341952-624');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1219963656089341952&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;What it actually IS? Remove all sugar, remove all extra words. What is THE MAIN?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Given -&amp;gt; When -&amp;gt; Then&lt;/p&gt;

&lt;p&gt;Precondition -&amp;gt; Action -&amp;gt; Postcondition&lt;/p&gt;

&lt;p&gt;Somewhere -&amp;gt; Action -&amp;gt; Somewhere else&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Where we are&lt;/code&gt; -&amp;gt; &lt;code&gt;What we do&lt;/code&gt; -&amp;gt; &lt;code&gt;Where we are&lt;/code&gt;&lt;/p&gt;



&lt;p&gt;Long story short - this is how &lt;code&gt;State Machines&lt;/code&gt; works. All those BDD tests are testing nothing more but &lt;code&gt;transitions&lt;/code&gt; from one State to another State, caused by some event. Nothing more.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Or from some &lt;code&gt;data&lt;/code&gt; to some &lt;code&gt;data&lt;/code&gt;, like in &lt;strong&gt;Redux&lt;/strong&gt;/&lt;strong&gt;Flux&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;State + Action = New State&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgj2v9hcu624t63uvsvex.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgj2v9hcu624t63uvsvex.png" alt="state"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This image is taken from &lt;a class="mentioned-user" href="https://dev.to/davidkpiano"&gt;@davidkpiano&lt;/a&gt; presentation &lt;a href="https://slides.com/davidkhourshid/finite-state-machines#/16" rel="noopener noreferrer"&gt;Infinitely Better UIs with Finite Automata&lt;/a&gt;, and there is also a few xstate-related articles you can read at dev.to (and much more in the wild).&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/davidkpiano" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F19667%2F2231c0e9-2d8f-4b0a-be43-1ac5223a93a5.jpg" alt="davidkpiano"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/davidkpiano/no-disabling-a-button-is-not-app-logic-598i" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;No, disabling a button is not app logic.&lt;/h2&gt;
      &lt;h3&gt;David K. 🎹 ・ Nov 13 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#state&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#statemachine&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#async&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h2&gt;
  
  
  Quack!
&lt;/h2&gt;

&lt;p&gt;However, you know, state machines are great... but while we are talking about them, you probably do not use them in your code.&lt;br&gt;
However, I would not be so sure, even if you really don't use them intentionally, explicitly or even implicitly.&lt;/p&gt;

&lt;p&gt;Finite State Machines are all about the finite amount of States something could be in, and by some reason. Like could be little black cloud not rainy? Could large rainy cloud not black? What is your expectations from the cloud? Why do you think it is rainy?&lt;/p&gt;

&lt;p&gt;Even if David once said - &lt;em&gt;"disabling a button is not app logic"&lt;/em&gt; - "Disabled Button" has to have &lt;code&gt;disabled&lt;/code&gt; attribute, or at least looks like disabled. Well, quacks 🦆 like a &lt;code&gt;disabled&lt;/code&gt;, so everyone will understand your intent. &lt;code&gt;WAI-ARIA&lt;/code&gt; included.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;👁: An observable system is one whose &lt;strong&gt;internal state can be deeply undertood&lt;/strong&gt; just by observing its outputs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, keeping the main principles of Duck Typing - is it possible to &lt;strong&gt;infer the Page State from observing the Page&lt;/strong&gt;?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if we know how every page &lt;strong&gt;state should quack&lt;/strong&gt;. Could we &lt;strong&gt;find the right duck&lt;/strong&gt;?&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;🦆 + action = 🦆&lt;/p&gt;



&lt;p&gt;However, is it really the case? Let's recall the case with a cup of water.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: you are thirsty 
When: you take 3 sips
Then: you are full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You were in one 🦆, took an action, and now you are in another 🦆. In reality you just drunk some water, and your digestion system reported that your are now ok. In fact you are not yet, the water is yet in your digestion system. &lt;br&gt;
👉 The BDD test is actually testing a &lt;strong&gt;derived&lt;/strong&gt; reaction. Which is even not real.&lt;/p&gt;

&lt;p&gt;It tests the RESULT, not the implementation details. You heard it multiple times, and let's recall another ancient knowledge to understand the meaning.&lt;/p&gt;




&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Life is a journey, not the destination.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Well in our case it’s the opposite. The destination is the reality, and the journey is an implementation detail.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To finish the moment, to find the journey’s end in every step of the road, to live the greatest number of good hours, is wisdom.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Allegory_of_the_cave" rel="noopener noreferrer"&gt;Allegory of the cave&lt;/a&gt;, Plato's, 514ad. Which is, long story short, "The Matrix".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Plato begins by having Socrates ask Glaucon to imagine a cave where people have been imprisoned from childhood. These prisoners are chained so that their legs and necks are fixed, forcing them to gaze at the wall in front of them and not look around at the cave, each other, or themselves. &lt;br&gt;
Behind the prisoners is a fire, and between the fire and the prisoners is a raised walkway with a low wall, behind which people walk carrying objects or puppets "of men and other living things". &lt;br&gt;
The people walk behind the wall so their bodies do not cast shadows for the prisoners to see, but the objects they carry do. &lt;br&gt;
The prisoners cannot see any of what is happening behind them, they are only able to see the shadows cast upon the cave wall in front of them. The sounds of the people talking echo off the walls, and the prisoners believe these sounds come from the shadows.&lt;br&gt;
👉 The shadows are reality for the prisoners because they have never seen anything else; they do not realize that what they see are shadows of objects in front of a fire&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpn09xg42jwgflx5bjquy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpn09xg42jwgflx5bjquy.png" alt="shadows on the wall"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By now you should understand, that your code, your codestyle, patterns and everything else are "the real objects", but "the prisoners", your users in this case, are able to see only &lt;em&gt;shadows&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Real customers are facing the combination of many unrelated to each other processes, TCP/IP and the way their screens displays the data included.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;😉 if it walks like an Application, and it swims like an Application, that's an application, not a random collection of bytes.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Reverse Duck
&lt;/h2&gt;

&lt;p&gt;Reverse Duck is what our E2E tests (should) look like &lt;br&gt;
– open some page, and assert some selector. If that selector exists – then we are on the expected page, and the test continues.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We are doing some actions, and again checking some selectors - is our page walks like the right page?&lt;/li&gt;
&lt;li&gt;doing more actions, and again checking selectors - is our page swims like the right page?&lt;/li&gt;
&lt;li&gt;Oh, it is not? quack!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every test starts in one 🦆, and ends in another 🦆. Your ability to test your application is limited to your ability to define those distinct states, and here a picture, explaining a lot, again from one of David's presentation. &lt;a href="https://slides.com/davidkhourshid/mbt-cse#/14" rel="noopener noreferrer"&gt;Write fewer tests&lt;/a&gt; this time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdrwe74xedrlkfjcbg9p7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fdrwe74xedrlkfjcbg9p7.png" alt="Automated tests"&gt;&lt;/a&gt;&lt;br&gt;
👉On the picture: you are in the State A, and you know "how" to go from it to State B or State C - you can create an automated test checking that your application is working "as designed".&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All good applications resemble correct &lt;del&gt;business processes&lt;/del&gt; state machines behind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having your application described as a state machine you CAN try to move from one State to another State and assert the result. Like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;have you reached the right State, as it was designed?
&lt;/li&gt;
&lt;li&gt;could go from the Very Beginning to the Very End?&lt;/li&gt;
&lt;li&gt;could you test transition between any sibling states?&lt;/li&gt;
&lt;li&gt;could you start your application in any Specific State? If not then why?&lt;/li&gt;
&lt;li&gt;could you understand that your application is in some Specific State right now?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Works in a quite obvious way - exactly as we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: 🦆 &amp;gt; ducks like your Home Page
When: You press The Most Important Button
Then: 🦆 &amp;gt; still ducks like your Home Page 😅
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, not many application works that way, especially SPAs - usually, they are a bit more complex. Usually, our applications are &lt;code&gt;Big Machines&lt;/code&gt;, composed of &lt;code&gt;Smaller machines&lt;/code&gt; - 🦆🦆🦆🦆, the Pack of Ducks.&lt;/p&gt;

&lt;p&gt;If you just clicked &lt;code&gt;The Most Important Button&lt;/code&gt; - it might open a &lt;code&gt;Modal Dialog&lt;/code&gt; - like it added something on the page, something parallel to everything else. A new 🦆.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Given: 🦆 &amp;gt; ducks like your Home Page
When: You press The Most Important Button
Then: 🦆 &amp;gt; still ducks like your Home Page, 
         &amp;gt; and The Modal Dialog
         &amp;gt; and network activity indicator
         &amp;gt; and system await user action
         &amp;gt; ....
         &amp;gt; there are just not “blind monks” describing your Elephant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good examples of "small machines", many of which could be found inside bigger ones are &lt;code&gt;React Hooks&lt;/code&gt; - &lt;strong&gt;small and simple&lt;/strong&gt; state machines. And they can form &lt;strong&gt;React Component&lt;/strong&gt; - a &lt;code&gt;Big Machine&lt;/code&gt;, the composition of some data machines (&lt;code&gt;useState&lt;/code&gt;) plus effect machines (&lt;code&gt;useEffect&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;There is no way you can reproduce a really Big Machine using one State, but who said it should be one?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;when you are opening your application – you are changing it State. From &lt;code&gt;Closed&lt;/code&gt; to &lt;code&gt;Open&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;when you changing а current page – you are changing a nested machine state or sub-state. From &lt;code&gt;Page A&lt;/code&gt; to &lt;code&gt;Page B&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;when you are changing something on a page, filling &lt;code&gt;inputs&lt;/code&gt; in the &lt;code&gt;Form&lt;/code&gt; you are not changing anything, except machines inside those inputs. &lt;/li&gt;
&lt;li&gt;but once you have filled everything a &lt;code&gt;Form State&lt;/code&gt; could change –  Empty-&amp;gt;Invalid-&amp;gt;Valid.&lt;/li&gt;
&lt;li&gt;there are many state machines coexisting in your application. Without proper management it is leading, I'm afraid, to &lt;a href="https://en.wikipedia.org/wiki/Schizophrenia" rel="noopener noreferrer"&gt;Schizophrenia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;with proper management, they form &lt;a href="https://en.akinator.com/" rel="noopener noreferrer"&gt;Akinator&lt;/a&gt;, which is nothing more than a pretty big &lt;code&gt;decision tree&lt;/code&gt;, which is, well, &lt;strong&gt;Recursive Duck Typing&lt;/strong&gt;. And Triage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F65t7ko46qgirnqhwb4cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F65t7ko46qgirnqhwb4cg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To prevent any misunderstandings let's define terminology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;State&lt;/code&gt; – is an internal state of an object, &lt;strong&gt;not observable&lt;/strong&gt; from outside. Like React or Redux state. It could be even NOT used for the current page (There is always some useless pieces of data 😿)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Duck State&lt;/code&gt; – is a part of an underlying state machine, including the “shadow” of explicit machine &lt;strong&gt;observable from outside&lt;/strong&gt;. And let's call it a &lt;code&gt;Phase&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Phase&lt;/code&gt; of a State Machines is the current &lt;code&gt;state&lt;/code&gt; this machine is in. Like you are &lt;code&gt;reading article&lt;/code&gt;. State machine might be in single one state at the one point of time, but remember 🦆🦆🦆 - there could be parallel and nested machines.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's easy to distinguish State and Phase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State could be a composite object, with dozen variables inside.&lt;/li&gt;
&lt;li&gt;Phase always just one. The something major about the subject greatly altering subjects behaviour.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;think about the blind monk. The monk as to describe what he experienced in one or two words. Which?&lt;br&gt;
If you are not able to do it - add more monks.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Tier
&lt;/h2&gt;

&lt;p&gt;You cannot represent😅 your application with a simple and only one state machine - the real application is like a puzzle, or even like a Quest.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are in point A&lt;/li&gt;
&lt;li&gt;you have to play a mini-game, like a boss fight, to move to point B&lt;/li&gt;
&lt;li&gt;you are in point B&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;that minigame is an application inside an application - a nested submachine&lt;/li&gt;
&lt;li&gt;that forms multi-layered, multi-dimensional or multi-tiered architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or a Timing/Flow/Sequence Diagram, which explains what is happening layer by layer.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Multitier_architecture" rel="noopener noreferrer"&gt;Multitier architecture&lt;/a&gt; is quite common and popular. Many patterns could be considered as multi-tiered - from microservices to MVC. &lt;br&gt;
Usually, the separation between tiers is "logical": Presentation layer, Service Layer, Business logic layer, Data access layer. This is how the majority understands it. Not me.&lt;br&gt;
I don't like this sort of separation, as well as I hate "testing Pyramid" and the separation between unit/integration and E2E tests - it's not logical.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Really, "the difference" between &lt;code&gt;unit&lt;/code&gt; and &lt;code&gt;E2E&lt;/code&gt; tests that the first usually runs on the "server", and the "second" in the Browser. It's a separation by the tool used to run your tests, not the tests. And that's a good example of abstraction leaking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;the first tier is a feature definition. It defines how something should work. This is what you want to build, not how.&lt;/li&gt;
&lt;li&gt;the second tier is a testing layer. A duck machine, where you have to define how every particular state quacks. This is where &lt;code&gt;Design&lt;/code&gt; and &lt;code&gt;Observability&lt;/code&gt; met each other.&lt;/li&gt;
&lt;li&gt;the third tier is the implementation of a specific component. Of a Step. How a single Big Machine should work.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;is the current duck walking as expected, is current duck quacking as expected. &lt;/li&gt;
&lt;li&gt;If no duck is quacking – it's a fail. &lt;/li&gt;
&lt;li&gt;If more than one duck is failing – it's a fail.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Surprisingly – the last tier is helping to re-define the first. No Phases should quack the same. If something is different inside – it should be different outside.&lt;br&gt;
Situations when customer trying to click a &lt;code&gt;save button&lt;/code&gt;, without any effect cos it's "disabled", but not from UI perspective – much be not possible. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If this is a major &lt;code&gt;behavioural condition&lt;/code&gt; – it shall have its own Phase, own State, and shall have its own Duck🦆.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By fact - is very hard to define the proper requirements, it’s really easy to desire something not you really want.&lt;br&gt;
Like “build it with React and Redux” cannot be a business requirement, and usability, conversion rate and a11y cannot be a technical one.&lt;/p&gt;



&lt;p&gt;Let’s refer to another ancient knowledge - the Djinn in the bottle.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧞‍♂️: here I stand, let’s make it fast - 3 wishes&lt;/li&gt;
&lt;li&gt;🙀: I want to be riiiich!&lt;/li&gt;
&lt;li&gt;🧞‍♀️: as you wish, 😈&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A moment later you are rich. Very rich. And old. And everybody hates you. And trying to kill you.  Cos you are Narcos.&lt;br&gt;
Not actually what you wanted, but exactly what you’ve asked for.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Just for your information - there is a film about it - &lt;a href="https://en.wikipedia.org/wiki/Bedazzled_(2000_film)" rel="noopener noreferrer"&gt;Bedazzled&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pwe6mew037skc82k01k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pwe6mew037skc82k01k.jpg" alt="Bedazzled narcos"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;As a test, Elliot wishes for a Big Mac and a large Coke. The Devil takes him to McDonald's and places the order. Elliot has to pay for it, because, "there ain't no such thing as a free lunch." After taking Elliot to her office, based at a nightclub in Oakland, the Devil convinces Elliot to sign her contract, and delivers further wishes. Each wish has Elliot living them out with Alison and his co-workers in surrogate roles. However, the Devil always spoils his wishes by adding something he does not expect or want.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And, to be honest, that &lt;code&gt;evil djinn&lt;/code&gt;, who is going to use everything you said against &lt;code&gt;you&lt;/code&gt;... is &lt;code&gt;you&lt;/code&gt;, who is doing exactly what was asked for, but... the devil is in details. And that &lt;code&gt;you&lt;/code&gt; is &lt;code&gt;your project manager&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Well, manager, you’ve got what you deserved. Next time be more precise, wish something you really need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's always about your Duck definition. How it quack, what you asked Djinn for, what is the story of the blind man.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;The Duck Typing is a pattern matching. Is a way to define what something is by observing it.&lt;br&gt;
It is a way to understand​ what something actually is.&lt;br&gt;
It is a requirement to left some breadcrumbs, some details and nuances​ to be able to distinguish​ one duck from another.&lt;br&gt;
It is how to stop being an evil djinn.&lt;br&gt;
About what does really matters, and what is not.&lt;br&gt;
It's about design, UX, monitoring and observability. As I've said in the beginning - you can hammer literally​ everything with it.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;mental models&lt;/code&gt; derived from duck typing might help you develop a more thoughtful​ solution, which would do what you really need, as well as define and clarify why you actually need.&lt;/p&gt;

&lt;p&gt;Next time you will be asked​ to do something, just quack.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PS: and here are the slides from the talk&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;iframe src="https://www.slideshare.net/slideshow/embed_code/key/pe6rGmEEykcQQT" alt="pe6rGmEEykcQQT on slideshare.net" width="100%" height="487"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/QrOUndxFmdA"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>xstate</category>
    </item>
    <item>
      <title>IE11 and the Missing Polyfills</title>
      <dc:creator>Anton Korzunov</dc:creator>
      <pubDate>Wed, 11 Dec 2019 06:44:12 +0000</pubDate>
      <link>https://dev.to/thekashey/ie11-and-the-missing-polyfills-1cd9</link>
      <guid>https://dev.to/thekashey/ie11-and-the-missing-polyfills-1cd9</guid>
      <description>&lt;p&gt;It was a beautiful sunny day, and our brand new site was working well, as it usually does, however, nobody(except us) knew how cool is it, yet 😉. Our startup was in the stealth mode. &lt;br&gt;
We had no traffic, no customers, and, obviously, no worries.&lt;/p&gt;

&lt;p&gt;Everything was perfect - the code was DRY, KISS, fast, best practices applied, dependencies up to date, and even UX design was not that bad.&lt;br&gt;
And it was a launch day!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;All systems ready!  Prepare! Launch 🚀🚀🚀! &lt;br&gt;
3 seconds! Telemetry! All green! 10 seconds! 60 seconds! &lt;br&gt;
🥳 &lt;strong&gt;We are online!&lt;/strong&gt; 🥳&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We were confident - everything is ok. Of course, there was no reason to worry - we had proofs that everything &lt;strong&gt;is&lt;/strong&gt; perfect: 100% unit test coverage and puppeteer based E2E tests would not let any bug to exists.&lt;/p&gt;



&lt;p&gt;We were online...&lt;/p&gt;

&lt;p&gt;We were happy...&lt;/p&gt;

&lt;p&gt;We were not expecting anything bad to happen... but it happened...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9aq18h7ebp0vojvfiqkl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F9aq18h7ebp0vojvfiqkl.png" alt="Rollbar error"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;...shouted &lt;a href="https://rollbar.com/" rel="noopener noreferrer"&gt;rollbar&lt;/a&gt;, the service we use to monitor our frontend errors.&lt;/p&gt;

&lt;p&gt;...this and nothing more, keeping silence for the next minute. &lt;/p&gt;

&lt;p&gt;And then it happened AGAIN! And AGAIN! And AGAIN, and our happy life was destroyed, and our belief in ourselves has vanished 😭😭😭...&lt;/p&gt;
&lt;h1&gt;
  
  
  ...
&lt;/h1&gt;

&lt;p&gt;Sound like a scary story? Well, it was very scary, and a bit unexpected. But, looking behind, we did everything to get into this trouble - we &lt;strong&gt;haven’t provided required &lt;code&gt;polyfills&lt;/code&gt;&lt;/strong&gt; to let our so cool, and so modern code work in the &lt;em&gt;legacy browsers&lt;/em&gt;, the browsers no developer would ever use, the browsers which are still around.&lt;/p&gt;

&lt;p&gt;According to the statistic - usually, almost 90% of your customers are expected to use &lt;em&gt;more or less&lt;/em&gt; “modern” browsers, however, in some cases, it might be as low as just 50%. It depends who you are, where you are, and your target audience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa95o6q60h34epeeiyth7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fa95o6q60h34epeeiyth7.png" alt="Instagram users with ES2017 supported"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Percentage of Instagram users with ES2017 supported vs unsupported browsers, &lt;a href="https://instagram-engineering.com/making-instagram-com-faster-code-size-and-execution-optimizations-part-4-57668be796a8" rel="noopener noreferrer"&gt;source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;BTW: React and Create-React-App still supports IE9, 🦖&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And we nor made our code &lt;strong&gt;better for modern ones&lt;/strong&gt;, shipping more compact and fast “ES6” to the browser, which old browsers are absolutely unable to understand, but the new ones could benefit from. Nor made our code &lt;strong&gt;compatible with those “old” browsers&lt;/strong&gt;, shipping everything in "ES5", as well as adding the “missing pieces”, known as &lt;code&gt;polyfills&lt;/code&gt;, without which nothing would work as expected.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Polyfills are in fact a very bad thing, as long as they are a very big thing. Don't add them unless you need them. (well, so we didn't)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I would ask you one thing: what is better - provide the best experience possible for the majority of your customers, like around 90%, and let the other suffer... or provide the same "not great" experience for everyone, including that “majority”.&lt;/p&gt;

&lt;p&gt;And would you be surprised, if I tell you that no matter what you do, you will pick the first way? There are always people who cannot run as much JavaScript as you are sending, or just some settings and environments where JS is disabled at all.&lt;/p&gt;

&lt;p&gt;If not JavaScript, then CSS - maintaining perfect result across different browsers, when some of them just don’t (yet) support something is hard and (and that’s the truth) &lt;strong&gt;economically inefficient&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Even more - the common "target" for the bundle is "&lt;code&gt;2 last  versions&lt;/code&gt; + &lt;code&gt;Firefox ESR&lt;/code&gt; + &lt;code&gt;IE11&lt;/code&gt;".  So IE11 is the &lt;strong&gt;minumum&lt;/strong&gt; requirement, a vast majority of sites are designed to work with.&lt;br&gt;
But what if I am using IE10, or QQ Browser Mobile? (and I have no idea what it exactly is, but that’s not quite “standard” thingy).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So here is the point: it would be better for you to handle the bigger part of your customers in the best possible way - ie &lt;strong&gt;ship as &lt;em&gt;modern&lt;/em&gt; code, as possible&lt;/strong&gt;. However, you always should be ready to ship &lt;em&gt;de-modernized bundles&lt;/em&gt; for your other users, which &lt;strong&gt;should not be forgotten&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;de-modernized. de-gradated. de-evoluted. &lt;strong&gt;devoluted&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;PS: Have you heard about “graceful degradation”? Not a new thing.&lt;/p&gt;
&lt;h2&gt;
  
  
  🦎 -&amp;gt; 🦖
&lt;/h2&gt;

&lt;p&gt;However, this story is not about modern bundles from es5/es6/es7 perspective. This story is about polyfills. And polyfills - &lt;code&gt;language features polyfills&lt;/code&gt;, as well as &lt;code&gt;web platform polyfills&lt;/code&gt;, could be a quite big thing (and we are trying to make this “efficient”).&lt;/p&gt;

&lt;p&gt;I am still remembering my PTE English exam, where you have to explain a random picture or graph. _What could you tell me looking at this picture? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzchn99gdhap2816on1nd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fzchn99gdhap2816on1nd.png" alt="Bundle separation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By looking at this picture&lt;/em&gt; (I’ve borrowed from &lt;a href="https://www.smashingmagazine.com/2018/10/smart-bundling-legacy-code-browsers/" rel="noopener noreferrer"&gt;Smart Bundling&lt;/a&gt;), there are 4 points I want to highlight:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you don't have to ship polyfills to a browser which supports these features. Polyfills exists to &lt;em&gt;polyfill&lt;/em&gt; something missing.&lt;/li&gt;
&lt;li&gt;you don't have to ship a polyfill which is not going to be used straight ahead. You need it only when it's actually required.&lt;/li&gt;
&lt;li&gt;and you have to have all "missing functional parts" when they needed, or your code would produce a runtime exception.&lt;/li&gt;
&lt;li&gt;there is no way to automatically detect which parts are missing 🤔.
Well, that’s not clearly visible from the image, but is true.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The missing parts
&lt;/h2&gt;

&lt;p&gt;Let's imagine you use vanilla &lt;code&gt;JavaScript&lt;/code&gt;. You do &lt;code&gt;Object.entries&lt;/code&gt;, and it just works. For you. However it would not work for IE11, that's a sad but obvious fact.&lt;/p&gt;

&lt;p&gt;You may see the error in logs, and add &lt;code&gt;@babel/polyfills&lt;/code&gt; for the first time. It's like the first thing to do, and the first result in a google search. &lt;strong&gt;That's fixing the problem&lt;/strong&gt;, but is adding too much stuff you don't need - like &lt;strong&gt;all&lt;/strong&gt; possible polyfills.&lt;/p&gt;

&lt;p&gt;Should be a better way.&lt;/p&gt;
&lt;h3&gt;
  
  
  useBuitIns
&lt;/h3&gt;

&lt;p&gt;So, you google deeper, and found that &lt;code&gt;babel&lt;/code&gt; could magically make everything better - just use &lt;a href="https://babeljs.io/docs/en/babel-preset-env#usebuiltins-entry" rel="noopener noreferrer"&gt;usebuiltins: "entry"&lt;/a&gt;  &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry"
      }
    ]
  ]
}


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

&lt;/div&gt;
&lt;p&gt;What does it do? It replaces &lt;code&gt;@babel/polyfill&lt;/code&gt; &lt;strong&gt;with polyfills&lt;/strong&gt; actually &lt;strong&gt;required by &lt;code&gt;target&lt;/code&gt; system&lt;/strong&gt;, sometimes just halving their count. Once you configured - "modern + IE11" it will remove polyfills for IE9-10, as well A LOT of polyfills for Android related browsers.&lt;/p&gt;

&lt;p&gt;However, that "half" still might include stuff you are NOT using, and there is another option to tackle this - &lt;a href="https://babeljs.io/docs/en/babel-preset-env#usebuiltins-usage" rel="noopener noreferrer"&gt;usage&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

        "useBuiltIns": "usage"


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

&lt;/div&gt;
&lt;p&gt;the &lt;code&gt;usage&lt;/code&gt; is a bit smarter than &lt;code&gt;entry&lt;/code&gt; - it would add polyfills only for stuff you are &lt;em&gt;using&lt;/em&gt; in real. Halving already halved size.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;haven't used WeakSets? Removed!&lt;/li&gt;
&lt;li&gt;no RegExp? Removed!&lt;/li&gt;
&lt;li&gt;using Symbols? Polyfills!&lt;/li&gt;
&lt;li&gt;not using String.repeat? Re... Well...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What's not so great...
&lt;/h2&gt;

&lt;p&gt;Actually &lt;code&gt;"useBuiltIns": "usage"&lt;/code&gt; is not removing anything - it is &lt;strong&gt;adding&lt;/strong&gt;. Is somehow detect that stuff got used, work it out.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Usage&lt;/code&gt; has two design problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it's actually not quite "smart", as long as ”JavaScript”. I mean "JavaScript" is the reason why it’s working in a not best way.
&amp;gt; - If you do &lt;code&gt;anything.description&lt;/code&gt; it would add polyfill for &lt;code&gt;Symbol.description&lt;/code&gt;, cos ".description" 😉
&amp;gt; - If you do &lt;code&gt;Symbol.toStringTag&lt;/code&gt; it will add:

&lt;ul&gt;
&lt;li&gt;es.symbol.to-string-tag&lt;/li&gt;
&lt;li&gt;es.math.to-string-tag&lt;/li&gt;
&lt;li&gt;es.json.to-string-tag
Cos, you got it, &lt;code&gt;.toStringTag&lt;/code&gt; 😉.
As long as it's really don't know all types - JS is not a typed language. it’s 🦆 Duck Typing. If something quacks like &lt;code&gt;toStringTag&lt;/code&gt; - get it polyfilled!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;There is no way to fix it - &lt;code&gt;false positives&lt;/code&gt; would not break your application, while &lt;code&gt;false negatives&lt;/code&gt; might. So - live with it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is not a "real" problem. You might just get more polyfills that you really need, but still less than with &lt;code&gt;entry&lt;/code&gt; mode. &lt;br&gt;
And, the main difference, you will get required polyfills where you need them, not at your &lt;code&gt;entry point&lt;/code&gt;. So this more is the code splitting best friend. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the second problem is more severe. &lt;code&gt;usage&lt;/code&gt; is about "usage", and "usage" only within files "under babel management". If some of your &lt;code&gt;node modules&lt;/code&gt; requires any polyfill - it &lt;strong&gt;would not be detected&lt;/strong&gt;, and you will have to add it manually. I hope before shipping stuff to production. Well, like we did. 🥳&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes you might work this out expending &lt;code&gt;babel&lt;/code&gt; to the whole &lt;code&gt;node_modules&lt;/code&gt;, but that's not always an option.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;However enabled by default for &lt;code&gt;create-react-app&lt;/code&gt; as well as &lt;code&gt;parcel&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  CoreJS2 and CoreJS3
&lt;/h3&gt;

&lt;p&gt;By fact, there are two &lt;code&gt;useBuiltIns&lt;/code&gt; &lt;code&gt;usage&lt;/code&gt; plugins - one is for &lt;code&gt;corejs-2&lt;/code&gt; and one is for &lt;code&gt;corejs-3&lt;/code&gt;.&lt;br&gt;
v3 &lt;strong&gt;"detects"&lt;/strong&gt; much more cases, which is good from one point of view - you are more &lt;em&gt;"safe"&lt;/em&gt;, but from another, it leads to a much higher level of false positives.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Theoretically - a whole &lt;code&gt;corejs3&lt;/code&gt; is 50kb gzip, but you might need only 2kb from it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Takeaways?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;code&gt;@babel/polyfill&lt;/code&gt; or underlaying &lt;code&gt;core-js&lt;/code&gt; to make your application compatible with a wide amount of customers browsers, including aged or bugged browsers.&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;@babel/preset-env&lt;/code&gt; with &lt;code&gt;useBuiltIns: "entry"&lt;/code&gt; to &lt;strong&gt;safely&lt;/strong&gt; reduce the number of polyfills sent.&lt;/li&gt;
&lt;li&gt;use &lt;code&gt;@babel/preset-env&lt;/code&gt; with &lt;code&gt;useBuiltIns: "usage"&lt;/code&gt; to &lt;strong&gt;UNsafely&lt;/strong&gt; reduce the number of polyfills sent even more.&lt;/li&gt;
&lt;li&gt;😉 don't forget - using only one bundle for all customers is making this sort of optimizations inefficient, as long as too many polyfills, prepared for "legacy targets" would be sent to "modern targets". As well as less compact js code.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;8 polyfills(24kb) were needed for &lt;code&gt;modern&lt;/code&gt; bundle, and 37(154kb) were required for IE11 in our case. Sizes are before gzip.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fm6klko2xphtp0pwm9mow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fm6klko2xphtp0pwm9mow.png" alt="listing polyfills"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ spoiler alert ⚠️&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Core Duo
&lt;/h1&gt;

&lt;p&gt;So, to get something measurable from shipping right polyfills to the right client you have to send a &lt;code&gt;different code&lt;/code&gt; to &lt;code&gt;different clients&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are simple ways to do it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use &lt;a href="http://polyfills.io" rel="noopener noreferrer"&gt;polyfills.io&lt;/a&gt; to automatically deliver all required polyfills. One line fix 😉. One more blocking script at your head 🤔.&lt;/li&gt;
&lt;li&gt;use &lt;a href="https://www.pika.dev/cdn/" rel="noopener noreferrer"&gt;pika&lt;/a&gt; to deliver legacy/modern bundles. Sounds just amazing 🥳. Probably you have to change all your build pipeline 🤓.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a bit harder way - use &lt;code&gt;double bundling&lt;/code&gt; or &lt;code&gt;multicompiler mode&lt;/code&gt; to create different bundles targets, and that's the best you might get, but it's hard to manage. In terms of &lt;code&gt;code-splitting&lt;/code&gt;, &lt;code&gt;prefetching&lt;/code&gt; and &lt;code&gt;service-workers&lt;/code&gt;.&lt;br&gt;
&lt;code&gt;parcel2&lt;/code&gt; is promising to get it working out of the box, time will show how useful it is.&lt;/p&gt;

&lt;p&gt;There is another question to ask yourself - &lt;/p&gt;
&lt;h1&gt;
  
  
  Which bundle to build?
&lt;/h1&gt;

&lt;p&gt;And how this "double bundling works", and which operations are required to make your code compatible with browsers, and what's the goal...&lt;/p&gt;

&lt;p&gt;And that's simple, really simple - &lt;strong&gt;modern browsers are able to run your code as-is&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Babel&lt;/code&gt;, as well as &lt;code&gt;TypeScript&lt;/code&gt; are here to create a "lower" version of your code (&lt;code&gt;babel&lt;/code&gt; initially was named &lt;code&gt;6to5&lt;/code&gt;, it was converting es6 to es5, you got it 😉).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The idea about bundling is to get your files, combine them together, and create a version for a &lt;strong&gt;"lower target"&lt;/strong&gt;. Like &lt;strong&gt;es5&lt;/strong&gt;, eatable by any browser. Well, eatable with not language "downgraded", but also with "missing pieces" polyfilled, keep that in mind.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Double-bundling&lt;/code&gt; is doing exactly that, just twice - first for one target, and secondary for another. Modern and legacy. Module and no-modules.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And I think there is a more efficient way to handle it&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  🦎 -&amp;gt; (devolution) -&amp;gt; 🦖
&lt;/h1&gt;

&lt;p&gt;Idea behind &lt;a href="https://github.com/theKashey/devolution" rel="noopener noreferrer"&gt;devolution&lt;/a&gt; is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are compiling your bundle, you can run in your browser. Like the "modern" one&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;devolution&lt;/code&gt; takes it as an input, and produces the &lt;code&gt;legacy&lt;/code&gt; output, with language version "downgraded", and requited polyfills added.&lt;/li&gt;
&lt;li&gt;it makes it faster than bundler, with easier configuration, however with some cost to the final bundle side.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's go step by step:&lt;/p&gt;
&lt;h3&gt;
  
  
  you are compiling your bundle to a modern target
&lt;/h3&gt;

&lt;p&gt;Just do it. Pick &lt;code&gt;esmodules&lt;/code&gt; target, which targets browsers with "module" support, or pick even higher target, without old Safary inclided. Feel free to use &lt;a href="https://github.com/babel/preset-modules" rel="noopener noreferrer"&gt;preset-modules&lt;/a&gt;, which creates more compact es6 code than &lt;a href="https://babeljs.io/docs/en/babel-preset-env" rel="noopener noreferrer"&gt;preset-env&lt;/a&gt;, however not adding any polyfills&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1194336379477512192-34" src="https://platform.twitter.com/embed/Tweet.html?id=1194336379477512192"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1194336379477512192-34');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1194336379477512192&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;devolution&lt;/code&gt; takes it as an input, and produces the &lt;code&gt;legacy&lt;/code&gt; output
&lt;/h3&gt;

&lt;p&gt;Run run &lt;code&gt;yarn devolution&lt;/code&gt; and it will first create a self-documented &lt;a href="https://github.com/theKashey/devolution/blob/master/.devolutionrc.js" rel="noopener noreferrer"&gt;.devolutionrc&lt;/a&gt; letting you configure absolute everything.&lt;br&gt;
The second run will create a legacy bundle.&lt;/p&gt;


&lt;div class="ltag_asciinema"&gt;
  
&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;Well, asciinema is not looking good at &lt;code&gt;dev.to&lt;/code&gt; content width :(&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The process is split into a few steps: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;detecting required polyfills, using port of &lt;code&gt;babel&lt;/code&gt;'s usage plugin.&lt;/li&gt;
&lt;li&gt;adding missing polyfills, as well as elaborating what is required where&lt;/li&gt;
&lt;li&gt;recompiling code to another target, by fact - devoluting it&lt;/li&gt;
&lt;li&gt;re-minification of result code, to keep it compact&lt;/li&gt;
&lt;li&gt;and that's all..&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is only one piece left - pick the right bundle to use, and that's easy - just import the right one, everything else, including &lt;code&gt;_webpack_pulbic_path_&lt;/code&gt; update is already inside.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;script&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;prefix&lt;/span&gt; &lt;span class="o"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;noModule&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;check&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/ie11&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/esm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;script&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;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;This is the main difference between approach undertaken by devolution and common "double bundling" - &lt;strong&gt;devolution produces two structurally identical directories&lt;/strong&gt;, the difference in &lt;strong&gt;only&lt;/strong&gt; &lt;code&gt;public path&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The process is working quite fast, as long as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all heavy lifting is already done by the bundler&lt;/li&gt;
&lt;li&gt;each file is managed in a separate thread, so if you are using code splitting the process might be quite fast.&lt;/li&gt;
&lt;li&gt;you can opt-in for &lt;a href="https://github.com/swc-project/swc" rel="noopener noreferrer"&gt;swc&lt;/a&gt;, making compilation 10 times faster - &lt;strong&gt;there is no need to apply any babel plugins&lt;/strong&gt; again - they are already applied, so we are able to use more specialised tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bonus&lt;/strong&gt;: you are getting &lt;strong&gt;polyfills for the "whole" bundle&lt;/strong&gt;, all your &lt;code&gt;node_modules&lt;/code&gt; are covered. As well as es5 for the whole bundle - if you are using some es6-based &lt;a class="mentioned-user" href="https://dev.to/sindresorhus"&gt;@sindresorhus&lt;/a&gt; modules, like &lt;a href="https://github.com/sindresorhus/query-string" rel="noopener noreferrer"&gt;query-string&lt;/a&gt; - it would just work without any extra configuration!&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;another bonus&lt;/strong&gt;: it does not matter which framework or bundler you are using - this is working at deployment time. So - it would work even for closed systems like &lt;strong&gt;CRA&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;In numbers - it's taking 10 seconds to handle bundle it takes 30 seconds to build 😒, and 30 seconds to handle bundle it takes 20 minutes to build 😃.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bonus - you might use &lt;code&gt;preset-modules&lt;/code&gt;, which is not adding any polyfills to create a bundle, and then use &lt;code&gt;devolution&lt;/code&gt; to add required ones for your "esm bundle".&lt;/p&gt;
&lt;h3&gt;
  
  
  The point
&lt;/h3&gt;

&lt;p&gt;The result bundles are &lt;strong&gt;the same&lt;/strong&gt;. They are just laying in different directories. You can use &lt;code&gt;__webpack_public_path__&lt;/code&gt; to control which one has to be, or is loaded, while &lt;code&gt;parcel&lt;/code&gt; would work out of the box.&lt;/p&gt;

&lt;p&gt;Read an article about shipping &lt;code&gt;module&lt;/code&gt;/&lt;code&gt;nomodule&lt;/code&gt; bundles for details:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link"&gt;
  &lt;a href="/thekashey" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F113306%2F18ae0122-205c-4952-8f73-240175b4ae1d.png" alt="thekashey"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/thekashey/optimising-js-delivery-4h6l" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;🛳 Optimising JS Delivery&lt;/h2&gt;
      &lt;h3&gt;Anton Korzunov ・ Oct 4 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#codesplitting&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h1&gt;
  
  
  The real conclusion
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;you have to ship polyfills to support all possible browsers your customers might use&lt;/li&gt;
&lt;li&gt;it's quite bad idea to ship all theoretically required polyfills to everybody&lt;/li&gt;
&lt;li&gt;consider separating bundles for the "modern" and "legacy" browsers, or, at least, separating polyfills you are sending to your clients. Or, at least, use &lt;code&gt;babel/polyfill&lt;/code&gt; with &lt;code&gt;entry&lt;/code&gt; module &lt;code&gt;useBuiltIns&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And keep in mind &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are going to send more &lt;code&gt;javascript&lt;/code&gt; code to the aged browsers, as long as it would be a result of a transpilation from es6-es7-es8. &lt;/li&gt;
&lt;li&gt;amount of polyfills to be sent would increase and the numbers of features to polyfill grows &lt;/li&gt;
&lt;li&gt;the "legacy customer" will suffer in any case, as long as even "modern customers" suffer - there is too much javascript around.&lt;/li&gt;
&lt;li&gt;however, you might help at least the majority with a few lines&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Start using double bundling. Please. &lt;br&gt;
⚠️ However, removing polyfills, you dont need for the more modern bundle, could drive the biggest impact to the bundle size ⚠️, especially for the entry chunk.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't be a 🦖, let &lt;a href="https://github.com/theKashey/devolution/" rel="noopener noreferrer"&gt;devolution&lt;/a&gt; handle it. At least give it a try, you can setup it in moments and start being more efficient.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

yarn add &lt;span class="nt"&gt;--dev&lt;/span&gt; devolution
yarn devolution &lt;span class="o"&gt;[&lt;/span&gt;source-dist] &lt;span class="o"&gt;[&lt;/span&gt;target-dist]
// like
yarn devolution build build


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

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;feel free to use as modern code anywhere. &lt;code&gt;node_modules&lt;/code&gt; included. Create as modern bundle as you can, and &lt;em&gt;devolute&lt;/em&gt; it as a ​whole.&lt;/li&gt;
&lt;li&gt;be confident - all polyfills are included. &lt;code&gt;devolution&lt;/code&gt; uses the same &lt;code&gt;usage-plugin&lt;/code&gt; &lt;code&gt;@babel/preset-env&lt;/code&gt; uses internally and you can configure &lt;code&gt;corejs&lt;/code&gt; version to use.&lt;/li&gt;
&lt;li&gt;it's just a few lines to add it to your setup and start shipping separated bundles for different customers.&lt;/li&gt;
&lt;li&gt;well, it's the only one "safe" way to use &lt;code&gt;@babel/preset-modules&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;it's 100% configurable. &lt;code&gt;.devolutionrc.js&lt;/code&gt; let you control almost everything&lt;/li&gt;
&lt;li&gt;and it's fast - multy threaded nature with optional usage of lighting fast &lt;code&gt;swc&lt;/code&gt; transpiler.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webpack</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
