<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Valerii Udodov</title>
    <description>The latest articles on Forem by Valerii Udodov (@vudodov).</description>
    <link>https://forem.com/vudodov</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%2F618378%2Ff788643f-2dd6-4353-a7c2-57a377c5fbb9.jpeg</url>
      <title>Forem: Valerii Udodov</title>
      <link>https://forem.com/vudodov</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vudodov"/>
    <language>en</language>
    <item>
      <title>Git Hygiene</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Tue, 02 May 2023 00:00:40 +0000</pubDate>
      <link>https://forem.com/vudodov/git-hygiene-176j</link>
      <guid>https://forem.com/vudodov/git-hygiene-176j</guid>
      <description>&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%2Fu52fw527n7ekl2rp6322.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%2Fu52fw527n7ekl2rp6322.png" alt="git"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not by coincidence Git has become a default version control system for many of us. Git has proven itself to be predictable and reliable. Especially when it comes to conflict management, history traversal, and other daily developer routines.&lt;/p&gt;

&lt;p&gt;I have collected some recommendations that will enhance your day-to-day experience of working with Git. And hopefully, reveal some hidden features that have been laying around all this time.&lt;/p&gt;

&lt;p&gt;This article is not an ultimate Git guide by any means. Rather it is a set of common sense practices for using Git effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Branching
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Strategy
&lt;/h3&gt;

&lt;p&gt;There are ultimately two main branching strategies &lt;em&gt;feature branches&lt;/em&gt; and &lt;em&gt;trunk-based development.&lt;/em&gt; Everything else is just a variation of one or another. The biggest distinguishable difference between them is a scope of change that gets merged into the &lt;em&gt;trunk branch&lt;/em&gt; (aka &lt;em&gt;master, main, core, mainline&lt;/em&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Feature Branching is a poor man's modular architecture, instead of building systems with the ability to easily swap in and out features at runtime/deploytime they couple themselves to the source control providing this mechanism through manual merging.&lt;br&gt;
— &lt;em&gt;Dan Bodart&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Use &lt;em&gt;trunk-based development&lt;/em&gt; when possible. I won’t argue about the advantages of CI/CD, at least not in this article. I’ll just say that as the name suggest you can’t have CI/CD without Continuous Integration (CI). And by definition of the CI, you can’t have it without trunk-based development. Hence you can’t have CI/CD without trunk-based development.&lt;/p&gt;

&lt;p&gt;ℹ️ Trunk-based development is a version control management practice where developers merge small, frequent updates to a core “trunk” or main branch…&lt;br&gt;
— &lt;a href="https://www.atlassian.com/continuous-delivery/continuous-integration/trunk-based-development" rel="noopener noreferrer"&gt;Atlassian Trunk-based development definition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ℹ️ Continuous integration is a DevOps software development practice where developers regularly merge their code changes into a central repository, after which automated builds and tests are run. Continuous integration most often refers to the build or integration stage of the software release process…&lt;br&gt;
— &lt;a href="https://aws.amazon.com/devops/continuous-integration/" rel="noopener noreferrer"&gt;AWS CI definition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The most reasonable alternative to &lt;em&gt;trunk-based development&lt;/em&gt; is Gitflow. Given all the modern tooling for automation of testing, deployment, and releases Gitflow happens to be useful, but rarely. Deployment Hell that will unavoidably follow using Gitflow will likely cross any benefit you may think of.&lt;/p&gt;
&lt;h3&gt;
  
  
  Trunk-based development
&lt;/h3&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%2F46uiwqaxybg3n9ktbp61.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%2F46uiwqaxybg3n9ktbp61.png" alt="trunk-based development"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The diagram above was inspired by &lt;a href="https://twitter.com/jahnnie/status/937917022247120898?s=20" rel="noopener noreferrer"&gt;LeRoy's illustration&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately &lt;em&gt;trunk-based development&lt;/em&gt; is not always available right away. As the name suggests it is a process. Development process. And it has certain entrance criteria.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It should be possible to develop in small batches. It may be not only the developer’s prerogative as the work scope depends on planning. If the work is sliced in small chunks during the team planning then developing in small batches is a no brainer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The code review process should be balanced.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid overly heavy code-review process. Otherwise, developers will attempt to squeeze in as much work as possible to minimise the number of code reviews they have to go through.&lt;/li&gt;
&lt;li&gt;Somewhat opposed to the previous point, don’t make it a box-ticking exercise&lt;/li&gt;
&lt;li&gt;Code review is work and has to be recognised as such. It should be assigned and executed consciously.&lt;/li&gt;
&lt;li&gt;Code review should be a priority. Active branch lifetime should be minimised. Hence merged asap. So if the code is ready it should be reviewed asap.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The trunk branch should always stay healthy. Trunk branch health is an integral aspect of team performance. Thus there should be no way to break &lt;em&gt;trunk branch&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reviews, automated tests, and builds should be exhaustive and efficient.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Naming
&lt;/h3&gt;

&lt;p&gt;The most common use case for branch names is when we are looking for a specific branch to checkout. Consequently, the more discoverable branch is, the better.&lt;/p&gt;

&lt;p&gt;Usually, we know either the ticket number or the gist of work that has been (or will be) done there. However, we rarely know the exact name. It is often a good idea to incorporate a ticket number together with a distilled summary of the work. E.g. &lt;code&gt;123654-form-buttons-styling-uplift&lt;/code&gt; or &lt;code&gt;fixing-query-parameters-encoding-bug-344400&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Clean up
&lt;/h3&gt;

&lt;p&gt;Another pretty obvious one, but often overseen. Once the branch is no longer needed, it must be removed. The lower the number of obsolete branches, the better discoverability of active branches. Nowadays it is very easily automated task&lt;/p&gt;
&lt;h2&gt;
  
  
  Commits
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Message
&lt;/h3&gt;

&lt;p&gt;I like to think about a branch as a story that the developer tells about the work that has been done. Where the branch name is the name of the story. And every commit message is a sentence that builds the story. The frequency of commits and the content of commit messages should make sense in the context of the story you are trying to tell and should somewhat follow one another. Writing a commit message should be an intentional process, not a side-effect of using Git.&lt;/p&gt;

&lt;p&gt;📌 Commit process must be seamless. Try to eliminate all possible obstacles.&lt;br&gt;
Make sure you can commit from your IDE, and memorise the shortcut. Remove all unnecessary commit hooks, especially long-running ones.&lt;br&gt;
Commit should not feel like a burden, it should feel like saving a file.&lt;/p&gt;
&lt;h3&gt;
  
  
  Size
&lt;/h3&gt;

&lt;p&gt;You should commit often, therefore the size of each commit must be reasonably small. Base your commits around logical units of change. As long as you do that, the commit message will be accurate and obvious. Make sure you don’t get carried away as commit messages must stay concise, remember it is just a sentence in the story, not the story on its own.&lt;/p&gt;
&lt;h2&gt;
  
  
  Commit History
&lt;/h2&gt;

&lt;p&gt;We have slightly touched base on the commit history before. Depending on the scope and the context we will be perceiving and using commit history differently.&lt;/p&gt;

&lt;p&gt;ℹ️ To avoid any confusion I will call &lt;em&gt;main branch&lt;/em&gt; that all the work is based on &lt;em&gt;trunk branch.&lt;/em&gt; And any branch that is based from the &lt;em&gt;trunk branch&lt;/em&gt; but not yet merged back in: &lt;em&gt;Work in Progress branch&lt;/em&gt; or &lt;em&gt;WIP branch&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the context of the &lt;em&gt;WIP branch&lt;/em&gt; (e.g. if you are reviewing someone's work) we are interested in work that has been done in the scope of a given ticket/task/story, hence the more details provided the better.&lt;/p&gt;

&lt;p&gt;However, when we are looking at the &lt;em&gt;trunk branch&lt;/em&gt; we are looking at the history in the scope of the project as a whole. And hardly there will be much value in a very granular view.&lt;/p&gt;
&lt;h3&gt;
  
  
  WIP Branch History
&lt;/h3&gt;

&lt;p&gt;Generally ambiguous commit history on this level is a side-effect of poorly planned work. You must know at least in broad strokes how you are planning to tackle the task. As long as the work is reasonably planned using commits to craft a well-written story will be a natural and effortless act.&lt;/p&gt;

&lt;p&gt;Take a look at &lt;code&gt;12332-uplifting-checkout-form&lt;/code&gt; branch history&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;12332-uplifting-checkout-form
- introduced a theme provider
- updated buttons to use the theme provider
- updated text fields to use theme provider
- removed redundant info banner
- fixed confirmation text typo
- addressed review comments
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It tells a story, isn’t it? By looking at the branch and commit messages you can see what has happened, if you require more details you can get down to the code level. Try to avoid any code specifics in the commit message, variable names, classes, etc., anything that will be anyway visible on the code level.&lt;/p&gt;

&lt;p&gt;Ideally, you should be able to review what has been done by only looking at the commit history, although I would not recommend doing so.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trunk Branch History
&lt;/h3&gt;

&lt;p&gt;The most often use case for commit history on this level is during the process of figuring out wtf have happened with this code…&lt;/p&gt;

&lt;p&gt;🙃 &lt;code&gt;git blame&lt;/code&gt; ruining friendships since 2005&lt;/p&gt;

&lt;p&gt;I think this will sound familiar to you... You are working on a ticket and you stumble across a piece of code that you need to use/change/refactor. It works somehow but looks rather confusing and illogical. The code has been there for months or perhaps years. It has been written by someone who left the company ages ago... And yet there you are one on one with it…&lt;/p&gt;

&lt;p&gt;💡 What is worse than no documentation? Wrong documentation.&lt;br&gt;
Comments explaining how code works are no better than documentation. Both get stale very fast. However, comments not only are rarely updated but often get copied all over the code base, completely losing even remote value.&lt;/p&gt;

&lt;p&gt;The biggest advantage of having fluent and articulative history is the ability to time travel and answer the very important question of &lt;strong&gt;&lt;em&gt;why?&lt;/em&gt;&lt;/strong&gt; something has been done in a certain way. You can go to “day 1” and see how this whole space ended up where you found it. If you are lucky enough you will find ticket numbers attached to merge commits, so you’ll be able to get even more context.&lt;/p&gt;

&lt;p&gt;💡 Mark important events (such as releases and versions) in the history with tags. You can use &lt;a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging" rel="noopener noreferrer"&gt;annotated tags&lt;/a&gt; to store some extra metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merge Strategy
&lt;/h3&gt;

&lt;p&gt;In most cases, I’d suggest using Squash Merge as a &lt;em&gt;trunk branch&lt;/em&gt; default merge strategy. Squash Merges will clean the &lt;em&gt;trunk branch&lt;/em&gt; history from unnecessary noise that otherwise will leak from &lt;em&gt;WIP branches&lt;/em&gt; history. Squash Merges will protect &lt;em&gt;trunk branch&lt;/em&gt; integrity and concision. It will keep the history linear, which is much easier to read and rebase on.&lt;/p&gt;

&lt;p&gt;When all the work has been done and changes have been reviewed. You are one click away from the merge, it is hard to find a good reason to preserve the &lt;em&gt;WIP branch&lt;/em&gt; history anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merge Conflicts
&lt;/h3&gt;

&lt;p&gt;While you are working on your &lt;em&gt;WIP branch&lt;/em&gt; you shouldn’t be overwhelmed with conflicts. If you are, it is typically a consequence of sloppy work planning and mediocre orchestration. The &lt;em&gt;WIP branch&lt;/em&gt; lifetime should be short.&lt;/p&gt;

&lt;p&gt;However, if you encountered merge conflicts… Rebase. As said before linear history is much easier to read and comprehend. Hence much easier to traverse while traversing the history through the &lt;code&gt;git blame&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;💡 Before rebasing make sure you know what has changed since you started your work or bring someone who knows. Otherwise, there’s a high chance you will end up with a broken &lt;em&gt;WIP branch&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line ___
&lt;/h2&gt;

&lt;p&gt;I have tried to distill recommendations and keep them as generic as possible, avoiding any specifics related to the Git VCS provider, automation tools, or company processes. Said that given any specific tool, any of these practices or recommendations can be (and should be) improved significantly.&lt;/p&gt;

&lt;p&gt;Hence the final advice: don’t keep your process agnostic to tools, rely on them and use them to the maximum extent.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>productivity</category>
      <category>git</category>
    </item>
    <item>
      <title>Domain-Driven Design: building the Right thing Right</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Wed, 12 Apr 2023 22:27:31 +0000</pubDate>
      <link>https://forem.com/vudodov/domain-driven-design-building-the-right-thing-right-5aki</link>
      <guid>https://forem.com/vudodov/domain-driven-design-building-the-right-thing-right-5aki</guid>
      <description>&lt;p&gt;The success of any given software project can be distilled to a rather simple definition or rule: &lt;em&gt;we need to build the right thing, and we need to build this thing right&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It is a very abstract and simple if not primitive definition. Nevertheless, it is the one that is hard to argue with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the right thing
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Building the right thing…&lt;/em&gt; I don’t think it is necessary to emphasise the importance of this claim. But who knows what does the &lt;em&gt;right thing&lt;/em&gt; look like?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Domain experts&lt;/em&gt;. The domain expert is not a real position, it is rather a title that derives from a solid background in the industry. It might come from the direct experience, gained by actually working in the field (e.g. doctors, pilots, accountants). Or indirect, gained by working with other domain experts for an extensive period (designers, developers, business analysts).&lt;/p&gt;

&lt;p&gt;Domain experts might or even will have unrelated roles and responsibilities, but one thing they all have in common… Domain knowledge.&lt;/p&gt;

&lt;p&gt;💡 If you are not a geologist, oceanologist, or marine biologist there’s a low chance you know what good ocean bed surface exploration software must do…&lt;/p&gt;

&lt;p&gt;In high-complexity domains, we can discover another layer of people with the sole purpose of helping in interfacing with domain experts' experience and expectations. Unavoidably these people will become domain experts on their own, gaining a lot of indirect experience.&lt;/p&gt;

&lt;p&gt;You can distinguish domain experts by the language they use. It might sound rather confusing at first. Overflown with terminology, rich in acronyms and double-meaning words.&lt;/p&gt;

&lt;p&gt;💡 Domain experts will use domain language (professional slang). Be careful, it will often camouflage the true meaning and mislead you into a false perception of understanding it. Don’t hesitate to clarify any obscure detail as it might open a whole new level of meaning and understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the thing right
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Building the thing right…&lt;/em&gt; Speaks to itself. No one appreciates broken software…&lt;/p&gt;

&lt;p&gt;There are always numerous ways to solve a problem, hence to build an application. It is a well-known problem among developers, the attention gets easily carried away from the end goal of the project to the end tech.&lt;/p&gt;

&lt;p&gt;💡 The choice of technology must be driven by the architecture. And architecture must be driven and enhanced by the composition of the company and project tactical and strategic goals.&lt;/p&gt;

&lt;p&gt;When starting a greenfield project every developer feels like a kid in a candy shop.&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%2Fgjrmql14682kcxvdcr45.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%2Fgjrmql14682kcxvdcr45.png" alt="50 cents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Balanced, constantly refined architecture that focuses on the project goals is a key to &lt;em&gt;building the thing right&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;💡 The architecture should be constantly revisited throughout the entire lifetime of the project. However, the early stages are especially critical.&lt;/p&gt;

&lt;p&gt;Depending on the scale of the project, there might be a mixture of different roles and positions that will keep an eye on the architecture and tech-stack integrity and alignment. Solution architects, tech leads, CTOs, you name them. No doubt, you will find domain experts among them, usually they will have a long history with a company or in the given industry. And of course they will use distinguishable (domain) language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the right thing right
&lt;/h2&gt;

&lt;p&gt;Appears, most of the time we know &lt;em&gt;how to build the right thing&lt;/em&gt; and we have domain experts who can provide all the necessary support for it. And we know &lt;em&gt;how to build the thing right&lt;/em&gt; and we have the software engineering forces to facilitate it. So why it is so hard &lt;em&gt;to build the right thing right&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;I think no surprises will be here, communication is hard…&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Any organization that designs a system will produce a design whose structure is a copy of the organization's communication structure.&lt;br&gt;
— Melvin E. Conway&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A so-called Conway’s law states that communication significantly impacts the architecture, design, and code base. In the complex domain where a lot of convoluted logic resides around every corner, even initial unintentional miscommunication can derail the project. Any misinterpretation, if not addressed in time, starts a mismatch snowball effect. It grows fast, creates confusion and frustration, and degrades code-base quality which quickly becomes unmaintainable and error-prone. Even if the original miscommunication is fixed, usually it happens too late and the project is doomed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Communication gap
&lt;/h3&gt;

&lt;p&gt;Original miscommunication often appears from both the domain expert’s bias and the developer’s unwillingness to clarify details.&lt;/p&gt;

&lt;p&gt;Because of the domain expert's vast experience in a certain area a lot of the important details are obvious, certain aspects are given and don’t require clarification, if not mentioning. The language is overflown with opaque acronyms and words that convey an indelicate meaning. This is expected and unavoidable. The domain language is a habit that domain experts develop with years of experience. It is a framework they use for efficient communication. Medicine, mathematics, accounting, industrial design any professional area will be rich in terminology. Academical or specialised books, can’t guarantee the definition of the domain language, although they are likely to embody its essence; what you will hear from domain experts is what domain language is…&lt;/p&gt;

&lt;p&gt;Communication in general and clarification specifically is a very laborious process that requires decent self-effort. Cognitive work reduction and mental-resource preservation are part of human nature. Unmotivated developers don’t try to clarify the terminology or suspicious words, or address ambiguity in definitions. Instead, we subconsciously try to self-explain any logical flaw or uncertainty, ignore unclear acronyms, and don’t question obscure logic or abrupt conclusions.&lt;/p&gt;

&lt;p&gt;🙅 It is typically a red flag if the conversation with the domain expert goes one way rather than actively involving all parties. Everyone must make evident their level of domain expertise. It will signal to the domain expert how carefully the domain language must be used.&lt;/p&gt;

&lt;p&gt;💡 Often a visual artifact, such as a diagram of a domain model becomes extremely helpful during domain expert conversation. It gives a clear visual representation and helps align everyone’s understanding. It can start simple, but it will grow and improve over time.&lt;br&gt;
We’ll talk about the domain model a bit later…&lt;/p&gt;

&lt;p&gt;Unfortunately, experienced and reliable domain experts together with talented software engineers don’t guarantee the success of the project.&lt;/p&gt;
&lt;h2&gt;
  
  
  Domain-Driven Design
&lt;/h2&gt;

&lt;p&gt;DDD can be perceived differently from different perspectives. It is a philosophy, a framework, a set of architectural patterns, and many more things with the ultimate purpose of &lt;em&gt;building the right thing right.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Domain-Driven Design is an approach to software development that centers the development on programming a domain model that has a rich understanding of the processes and rules of a domain.&lt;br&gt;
-- &lt;a href="https://martinfowler.com/bliki/DomainDrivenDesign.html" rel="noopener noreferrer"&gt;Martin Fowler article Domain-Driven Design&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Domain-Driven Design (DDD) suppose to bridge the gap between the domain, its model, and implementation. It supposes to tide over misapprehension between those who can &lt;em&gt;build&lt;/em&gt; &lt;em&gt;the right thing&lt;/em&gt; and those who can &lt;em&gt;build the thing right&lt;/em&gt; by making the &lt;em&gt;Domain Model&lt;/em&gt; a centerpiece of the communication and implementation process.&lt;/p&gt;
&lt;h3&gt;
  
  
  Holistic Domain Model
&lt;/h3&gt;

&lt;p&gt;The &lt;em&gt;Domain Model&lt;/em&gt; is a root element of the Domain-Driven Design, everything spins around it. However, it is often confused to be one big diagram that encapsulates everything. Although nothing is wrong with having a big diagram, we all like big diagrams; except maybe we don’t like to keep them up to date, but that is a different story I suppose.&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%2Fhe597euzxayu9z4lx1qr.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%2Fhe597euzxayu9z4lx1qr.png" alt="domain model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The truth is the diagram is a vital piece of the Domain Model, but so are the ubiquitous language, the code base, and even your and your colleagues' mental model. Which ideally should all match and represent Holistic Domain Model.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Model-Driven Design&lt;/em&gt; discards the dichotomy of analysis model and design to search out a single model that serves both purposes. Setting aside purely technical issues, each object in the design plays a conceptual role described in the model. This requires us to be more demanding of the chosen model since it must fulfill two quite different objectives.&lt;br&gt;
— &lt;a href="https://www.goodreads.com/book/show/179133.Domain_Driven_Design" rel="noopener noreferrer"&gt;Domain Driven Design: Tackling Complexity in the Heart of Software by Eric Evans&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having a Holistic Domain Model can lead to rather unexpected outcomes. With a minimum support domain experts should be able to read the code and understand it. Because variable names, classes, and abstractions are part of the Domain Model, therefore meaningful to everyone involved.&lt;/p&gt;

&lt;p&gt;Consider this example where we are committing a backlog item to the sprint&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;backlogItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSprintId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sprintId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;backlogItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;BacklogItemStatusType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;COMMITTED&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Versus this example, where we are doing the same thing, but we match the ubiquitous language and preserve our Holistic Domain Model integrity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;backlogItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commitTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sprint&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Few words about the code…
&lt;/h3&gt;

&lt;p&gt;Since we touched on this topic, I’d like to add a few short words about the code and architecture. I won’t go into the depth of it, as quite a few books doing it better than I would. And I might share my thoughts about it in further articles. Anyhow…&lt;/p&gt;

&lt;p&gt;DDD is heavily relying on object-oriented concepts, it builds enriched object abstraction on top of the classical object model. DDD introduces a certain object classification, such as Entities and Value Objects. Provides isolation tools and interaction interfaces such as Aggregates and Aggregate Roots.&lt;/p&gt;

&lt;p&gt;Unlike many modern approaches, DDD does not appreciate Anemic Model and defines it as an anti-pattern. It emphasises the importance of keeping domain objects together with domain logic. So classes know what they are and what they can do instead of being data transfer objects.&lt;/p&gt;

&lt;p&gt;DDD recognises the complexity of every domain and hence does not attempt to fit everything in one bowl. It emphasises the importance of segregation and boundaries between different contexts and introduces a set of patterns to construct anti-corruption layers.&lt;/p&gt;

&lt;p&gt;DDD works very well with Event Sourcing and Event-Driven Architecture in general.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;The idea of importance mature and well-developed domain and its model was around for a while. And intuitively recognised by almost anyone involved in the implementation process, yet somehow it fades and gets lost in the daily development routine.&lt;/p&gt;

&lt;p&gt;The DDD is something anyone can start applying and practicing today on any project. The more sophisticated the project, the more beneficial it will be, nevertheless even lighter projects can benefit from it&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%2F1vl10mlhyhg9tlhgprkl.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%2F1vl10mlhyhg9tlhgprkl.png" alt="domain model"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would highly recommend familiarising yourself with it, as it will guarantee a change in your approach to design and development.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/11468377-thinking-fast-and-slow" rel="noopener noreferrer"&gt;Thinking, Fast and Slow by Daniel Kahneman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/3828902-thinking-in-systems" rel="noopener noreferrer"&gt;Thinking in Systems by Donella H. Meadows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/179133.Domain_Driven_Design" rel="noopener noreferrer"&gt;Domain Driven Design: Tackling Complexity in the Heart of Software by Eric Evans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/15756865-implementing-domain-driven-design?ac=1&amp;amp;from_search=true&amp;amp;qid=bhD8NM2sNM&amp;amp;rank=2" rel="noopener noreferrer"&gt;Implementing Domain Driven Design by Vaugh Vernon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.goodreads.com/book/show/57573212-learning-domain-driven-design" rel="noopener noreferrer"&gt;Learning Domain-Driven Design: Aligning Software Architecture and Business Strategy by Vladik Khononov&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://leanpub.com/design-and-reality" rel="noopener noreferrer"&gt;Design and Reality: Essays on Software Design by Rebecca Wirfs-Brock and Mathias Verraes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>watercooler</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>HTTP/3. All you need to know</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Wed, 22 Jun 2022 11:39:53 +0000</pubDate>
      <link>https://forem.com/vudodov/http3-all-you-need-to-know-bmk</link>
      <guid>https://forem.com/vudodov/http3-all-you-need-to-know-bmk</guid>
      <description>&lt;p&gt;HTTP/3 is a long overdue change in the way the Internet works. Surprisingly, though, it does not impact us as protocol consumers much... Moreover, the transition will be barely noticeable. Eventually, we will notice that port &lt;code&gt;443&lt;/code&gt; is gone. And we won't need to type &lt;code&gt;https://&lt;/code&gt; anymore. We will be getting back to &lt;code&gt;http://&lt;/code&gt;...&lt;br&gt;
We'll talk more about it later.&lt;/p&gt;




&lt;p&gt;ℹ️ Port &lt;code&gt;443&lt;/code&gt; is the one that is used for secure HTTP (aka HTTPS connection).&lt;/p&gt;




&lt;p&gt;So hmmm... What is it all about?&lt;br&gt;
It is all about TCP, really. Or should I say it's retirement? TCP has been around for astonishing 😲 30+ years. It is obsolete by any, even most conservative IT standards. So it was decided to replace it with a more modern transport layer protocol- QUIC.&lt;/p&gt;




&lt;p&gt;ℹ️ HTTP is an application layer protocol that sits on top of the transport layer protocol, like TCP.&lt;/p&gt;




&lt;p&gt;HTTP/3 uses QUIC instead of TCP. QUIC is the main driver for the new version of HTTP. And that's pretty much everything that changes from an HTTP perspective. Semantics stays the same. Hence all we know about HTTP as consumers stay the same. It will only be riding new wheels.&lt;/p&gt;

&lt;p&gt;Why to change it? Why now? It seems like internet is working fine, isn't it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Speed
&lt;/h2&gt;

&lt;p&gt;Connection reliability is a given, thanks to TCP. Thus, the ultimate connection measurement is its speed. And obviously, there's no way to sell a new protocol without improving it.&lt;/p&gt;

&lt;p&gt;Three factors dramatically improve QUIC data transition speed compared to TCP&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real Streams&lt;/strong&gt;: is actual direct data transition speed improvement;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved handshake&lt;/strong&gt;: is an improvement in connection establishment speed;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Connection Migration&lt;/strong&gt;: reduces the number of necessary re-connections, hence fewer connection establishments and data losses between sessions, hence even more speed;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real Streams
&lt;/h3&gt;

&lt;p&gt;Because in the TCP all packets are transitioned in a "line", if one packet is slow or lost, the whole "line" has to wait for the slow/lost packet to get back to its place and move on. Even though TCP has a concept of streams, those are not real streams but rather an abstraction to simulate them. Multiple files are broken down into packets, and packets are grouped in small frames, but anyway go through a single stream in "line".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8_8HU-xd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a63572zsi7z6kz0r5zp4.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8_8HU-xd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a63572zsi7z6kz0r5zp4.jpeg" alt="TCP Stream" width="880" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;QUIC implements streams, I mean real streams, so the data will flow truly simultaneously via a single connection but through multiple streams. E.g. the JS bundle file might be a stream and markup another stream.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kZRecLRG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yqvt9fb3vhdph5noxfxd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kZRecLRG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yqvt9fb3vhdph5noxfxd.jpeg" alt="QUIC Stream" width="880" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Apart from speed gain by truly parallelizing the packet transition, there's an annoying problem that has been solved. The Head Of Line Blocking.&lt;/p&gt;

&lt;p&gt;You know, when you are in a rush and get in the line at your grocery store. And there's this super slow person in front that just slows the whole line down. Well, that's the HoL Blocking.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When a single (slow) object prevents other/following objects from making progress&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All versions of HTTP, in one way or another suffered from the &lt;a href="https://calendar.perfplanet.com/2020/head-of-line-blocking-in-quic-and-http-3-the-details/"&gt;Head Of Line Blocking (HoL)&lt;/a&gt; on different levels. In HTTP/2, it was TCP HoL blocking because of a single-stream nature.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tWCGj92s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bossg26o3flyf8sa9ize.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tWCGj92s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bossg26o3flyf8sa9ize.jpeg" alt="TCP HoL Blocking" width="880" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;QUIC doesn't really solve the HoL blocking problem, it rather moves it to a different place. Although it does not completely solve the problem, nevertheless this shift significantly improves the performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WE7EJ0vn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14pp88gj7udljbxgjmif.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WE7EJ0vn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/14pp88gj7udljbxgjmif.jpeg" alt="QUIC HoL Blocking" width="880" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The HoL Blocking can occur at the stream level. Because stream order is still important, you can't reorder or lose packets. Hence, if there's a slow fellow in the stream, the stream can't proceed and have to wait... But in this case it won't block other streams. And once the issue with the annoying packet is solved, the stream will resume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Handshake
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Handshaking"&gt;Handshake&lt;/a&gt; is a procedure of establishing a connection between client and server. It ensures that both parties ready and know how to communicate.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Handshaking"&gt;TCP handshake&lt;/a&gt; is a necessary procedure occurring before any data can be sent over TCP. It requires a client to send a request and receive a response/acknowledgment from the server. Time spent waiting is called round trip time (RTT).&lt;/p&gt;




&lt;p&gt;ℹ️ Nowadays, we use HTTPS most of the time. HTTPS is an HTTP over TLS. Older versions of TLS (1.2 and lower) will require an extra handshake. So in the worst-case scenario, there's another RTT on top of all other handshakes.&lt;/p&gt;




&lt;p&gt;QUIC will require at least one handshake less. It will require exactly one handshake for a new connection and no handshake for resumed connection. Which makes QUIC 1RTT for a new connection and 0RTT for resumed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pVdVobUM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbji2kgoxa626962hpt8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pVdVobUM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sbji2kgoxa626962hpt8.png" alt="handshaking" width="880" height="583"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Image is borrowed from &lt;a href="https://techcommunity.microsoft.com/t5/itops-talk-blog/smb-over-quic-files-without-the-vpn/ba-p/1183449"&gt;SMB over QUIC: Without the VPN by Ned Pyle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Image (a) shows required handshakes for a new connection. As you could expect TCP with old TLS version will have 3RTT, TCP with modern TLS 2RTT, while QUIC only 1RTT.&lt;br&gt;
Image (b) shows required handshakes for existing connection. Once again, TCP with old TLS will require 2RTT, TCP with modern TLS 1RTT, while QUIC 0RTT&lt;/p&gt;

&lt;p&gt;I vacuum (completely identical circumstances): the lesser handshakes the faster connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection Migration
&lt;/h3&gt;

&lt;p&gt;The way we use the Internet has significantly changed over the past decade. Nowadays, a large portion of the internet traffic is consumed while we are on the go. Walking, commuting on public transport, or driving a car.&lt;br&gt;
Imagine you live within 30 mins walking distance from your work. And you decide to enjoy a walk to work today. There'll be at least 3 guaranteed network changes on your way, home wifi -&amp;gt; cell network (4G/5G) -&amp;gt; work wifi. However, in reality, during your walk (while you are connected to a cell network), you will be changing a network every 5-10 minutes, depending on the nearby cell tower range and how urban is the area you live/work in.&lt;/p&gt;

&lt;p&gt;On every new connection, unavoidably, at least one new handshake will be happening. Any active data downloading/uploading will be lost. Your endpoints will think that connection just has been lost or terminated unexpectedly.&lt;br&gt;
Have you ever experienced troubles with downloads/uploads while you were on the go? Well, there you have it.&lt;/p&gt;




&lt;p&gt;ℹ️ All large files nowadays downloaded and uploaded in segments, so if the large file will be uploading or downloading, you won't loose the whole file, but rather a last segment.&lt;/p&gt;




&lt;p&gt;TCP was not built, nor was it optimized for such a usage...&lt;/p&gt;




&lt;p&gt;ℹ️ The way TCP identifies a connection is pretty straightforward. Each connection between two endpoints (client and server) is identified by 4 parameters (4-tuple). Client IP address, client port number, server IP address, and server port number. If any one of the 4-tuple changes, TCP thinks it is a new connection. And the old one will be lost, it won't be even closed properly.&lt;br&gt;
Every time the network changes, the client will receive a new IP, hence the whole connection 4-tuple will be changed.&lt;/p&gt;




&lt;p&gt;The Connection Identifier (CID) allows the QUIC server and client to identify that what they see is not a new connection, but rather an existing connection migrated from another network. Therefore no need for a handshake and the download/upload process can keep on going.&lt;/p&gt;




&lt;p&gt;ℹ️ It is a bit more involved process. However, there's one more aspect to it. CID won't be encrypted. However, after every successful migration CID will be updated, so the connection (and your route) won't be traceable by CID.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;HTTP is a plain-text protocol. It simply sends a text over the wire (or radio waves). S in the HTTPS stands for Secure. By using HTTPS, we instruct a browser on a TLS protocol involvement in the communication. TLS protocol will encrypt our data using advanced mathematical algorithms. This ensures that even though the data might be intercepted by a third-party, it is useless. Nowadays, most web resources on the Internet use HTTPS.&lt;br&gt;
Even though modern browsers insist on HTTPS usage, we can still avoid it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5gdUMnDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w01bozegz7f8rprh3gnv.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5gdUMnDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w01bozegz7f8rprh3gnv.jpeg" alt="HTTP2 vs HTTP3" width="880" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With QUIC, it is unavoidable. Because TLS is built in the QUIC. Hence with HTTP/3, there won't be a need for &lt;code&gt;https://&lt;/code&gt; and port &lt;code&gt;433&lt;/code&gt;. Everything will be encrypted out of the box. And there's no way to turn encryption off.&lt;/p&gt;

&lt;h2&gt;
  
  
  There's one small thing... 🫠
&lt;/h2&gt;

&lt;p&gt;How do you go about upgrading the whole Internet? All devices, all routers, everything that uses TCP? 🤔&lt;/p&gt;

&lt;p&gt;And to give you a scale of the problem, have you ever tried to trace any random request? If not, try with something like &lt;a href="https://tools.keycdn.com/traceroute"&gt;this online tracer&lt;/a&gt;, and you will see how many nodes are involved in your request delivery. These are middle-boxes. My google.com trace shows 11 middle-boxes between me and the server 😮... And all of them use TCP 😳... And all of them probably don't run the latest version of Network Firmware...&lt;/p&gt;




&lt;p&gt;When was the last time you updated your router firmware? Exactly 🙃...&lt;/p&gt;

&lt;p&gt;And this was the exact reason why a new protocol was required. Because there's no way to update all devices in the world.&lt;/p&gt;




&lt;p&gt;As you can tell, simply adding a new protocol wouldn't work for the same reasons as updating TCP. So what do you do?&lt;br&gt;
The answer is &lt;a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol"&gt;User Datagram Protocol aka UDP&lt;/a&gt;. It can provide a platform for the QUIC protocol. It is broadly available and has been used as a base for many other protocols, such as &lt;a href="https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol"&gt;DHCP&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Simple_Network_Management_Protocol"&gt;SMTP&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Routing_Information_Protocol"&gt;RIP&lt;/a&gt;. QUIC is built on top of UDP, which makes it possible to deploy QUIC on the Internet scale.&lt;br&gt;
Over 73% of browsers support HTTP/3 as I'm writing this article. It is only a matter of time before all browsers and the majority of modern app servers will switch to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caveats
&lt;/h3&gt;

&lt;p&gt;There are a few things worth calling out.&lt;/p&gt;

&lt;p&gt;QUIC protocol requires more processing power. It has significantly improved since its first iterations. Nevertheless, compared to TCP, QUIC will consume more resources.&lt;/p&gt;

&lt;p&gt;And the other thing, even though it is relatively easily deployable because it is built on top of UDP. For the same reason, initially companies will block it as it will open a backdoor of UDP Flood DDoS attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;Hopefully, this article builds a picture of what we can expect from HTTP/3 and QUIC.&lt;/p&gt;

&lt;p&gt;I'm keen to see how the world will adopt the new protocol and what will be the future strategy for enabling it. I reckon there are industries that might want to adopt it ASAP. Gaming, video streaming, online communication, meta to name a few.&lt;/p&gt;

&lt;p&gt;I'm glad that TCP is getting well-deserved retirement. I'm still surprised at how long it worked on a global scale. It set the bar high.&lt;/p&gt;

&lt;p&gt;QUIC is already here. As I mentioned, majority of modern browsers support (to a different extend) HTTP/3, hence QUIC. I'm waiting with anticipation to see if our hopes for a new internet evolution step will be justified.&lt;/p&gt;

</description>
      <category>http</category>
      <category>webdev</category>
      <category>quic</category>
      <category>tcp</category>
    </item>
    <item>
      <title>Data Consistency in the Microservice Architecture</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Tue, 14 Jun 2022 09:07:47 +0000</pubDate>
      <link>https://forem.com/vudodov/data-consistency-in-the-microservice-architecture-41mg</link>
      <guid>https://forem.com/vudodov/data-consistency-in-the-microservice-architecture-41mg</guid>
      <description>&lt;p&gt;Data Consistency is an enigma of Distributed Architecture. It is a rather poetic way to say that something is a pain in the ass.&lt;/p&gt;

&lt;p&gt;It might not be that obvious at the first glance, but Data Consistency never exists in isolation. It is heavily bonded with Availability and Partition Tolerance. &lt;em&gt;If they sound alien, don't worry. We will closely look at them and their friendship in a moment&lt;/em&gt;&lt;br&gt;
Because of the close bond, the change in one will silently trigger a change in another, and so forth. In its turn, this change train 🚆 will replace one set of problems with another. And there you have it, change on one end, brought problems on the other.&lt;/p&gt;

&lt;p&gt;An interdependency between Consistency, Availability and Partition Tolerance in the distributed system has been described by the &lt;a href="https://en.wikipedia.org/wiki/CAP_theorem#cite_note-Gilbert_Lynch-1" rel="noopener noreferrer"&gt;CAP Theorem&lt;/a&gt;. Originally it was formulated by Eric A. Brewer for distributed data stores. But it is applicable for any distributed stateful architecture, hence Microservice Architecture.&lt;/p&gt;




&lt;p&gt;I think its applicability is worth explaining.&lt;/p&gt;

&lt;p&gt;We will star with Microservice Architecture definition. Here's a very concise definition&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;loosely coupled service-oriented architecture with bounded contexts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.slideshare.net/adriancockcroft/dockercon-state-of-the-art-in-microservices" rel="noopener noreferrer"&gt;Adrian Cockcroft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;If we'll elaborate on it...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Microservice Architecture is an approach where the application is built with a set of independently deployable services. The separation of concerns (SoC) is used to set service boundaries. Hence each service has its own well-defined purpose. And is either stateless or owns its data.&lt;br&gt;
&lt;a href="https://valerii-udodov.com/posts/monolithic-architecture/#distributed-monolith" rel="noopener noreferrer"&gt;Me in my previous article&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is not uncommon for a cluster of services to have an interest in the same subset of data. Because each stateful service is supposed to own its data, a cluster like this is a distributed storage for that subset of data. This means we can apply a CAP Theorem to it.&lt;/p&gt;




&lt;h2&gt;
  
  
  CAP Theorem
&lt;/h2&gt;

&lt;p&gt;The theorem states that, though it's desirable to have Consistency, Availability, and Partition Tolerance, unfortunately, no system can achieve all three simultaneously.&lt;br&gt;
In other words, we can choose at most two from given three characteristics.&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%2Fn98dl8yusxs3usg5c3tb.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%2Fn98dl8yusxs3usg5c3tb.png" alt="CAP Theorem"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before refining this theorem for Microservices let's define C, A, and P...&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistency
&lt;/h3&gt;

&lt;p&gt;Data Consistency comes in two flavors: Strongly Consistent or Eventually Consistent.&lt;br&gt;
The data is Strongly Consistent if any two arbitrary services in the cluster that share a subset of data have the same version of the data at any given moment.&lt;br&gt;
The data is Eventually Consistent if any two arbitrary services in the cluster share a subset of data but don't necessarily have the same version of the data at any given moment. But they guaranteed to have the same version eventually.&lt;/p&gt;

&lt;p&gt;This theorem implies Strong Consistency by this characteristic. In other words, if your architecture has this characteristic, the data within is strongly consistent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Availability
&lt;/h3&gt;

&lt;p&gt;Availability means that any arbitrary service is not blocked/locked at any given moment. Note, it is not an "availability" from an uptime perspective (aka &lt;a href="https://en.wikipedia.org/wiki/High_availability" rel="noopener noreferrer"&gt;High-Availability&lt;/a&gt;), but rather from a serving perspective. The service is &lt;strong&gt;available&lt;/strong&gt; for request processing even though it might not have the latest version of the data at any given moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Partition Tolerance
&lt;/h3&gt;

&lt;p&gt;In the context of Microservice Architecture, this characteristic is not really an optional one, it is a given one.&lt;br&gt;
Partition is a break or delay in the communication between services. Having partition tolerance means you are confident in the glue between your services and the underlying infrastructure. Given modern infrastructure, cloud providers and most (all?) modern message brokers guarantee "at least once" message delivery. This is a rather given and non-negotiable for Microservice Architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refined CAP Theorem (CA Theorem)
&lt;/h3&gt;

&lt;p&gt;Said that let's refine the general definition of CAP Theorem and turn it into a Microservice Architecture edition. Because Partition Tolerance is a given, we will dismiss it from the definition.&lt;/p&gt;

&lt;p&gt;In Microservice Architecture, for any given cluster of services, we can guarantee either Strong Consistency or Availability.&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%2F3x7w5el6be28pkgx2wm6.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%2F3x7w5el6be28pkgx2wm6.png" alt="CA"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Consistency vs Availability
&lt;/h2&gt;

&lt;p&gt;Let's look at how we can guarantee one or another characteristic in Microservice Architecture. And at what cost.&lt;br&gt;
Spoiler Alert: as we go, we will observe that for Microservice Architecture the choice is pretty much predefined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two-Phase Commit (2PC)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://martinfowler.com/articles/patterns-of-distributed-systems/two-phase-commit.html" rel="noopener noreferrer"&gt;Two Phase Commit&lt;/a&gt; (aka Distributed Transaction) is an attempt to commit/write/update a shared piece of information for each service in the cluster in (thanks, captain obvious) two phases. This approach will require a coordinator service that will control the execution of both phases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Phase 1: The coordinator checks each service in the cluster on readiness to perform the transaction. This phase locks each service right after service response. The lock is necessary to ensure that when we are going to carry on with the actual operation (phase 2), services will remain in the same state as we leave them in this phase. If any service is not ready, we cancel the whole transaction and unlock all services.&lt;/li&gt;
&lt;li&gt;Phase 2: Actually perform an update operation for each service in the cluster. Once this phase is over, all services are unlocked.&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%2Fbt23eshaul62yhwvkwua.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%2Fbt23eshaul62yhwvkwua.png" alt="2PC"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Evidently, this approach guarantees Consistency over Availability (CA Theorem). All services in the cluster will maintain strongly consistent data after every 2PC transaction. However, they will be locked during the whole process, hence unavailable.&lt;/p&gt;

&lt;p&gt;If you decide to use this approach in the Microservice Architecture, I'd strongly recommend reconsidering the boundaries of all services included in the cluster. This approach strongly couples all services in the cluster and goes against the definition of Microservice Architecture. And fits well in the definition of the &lt;a href="https://valerii-udodov.com/posts/monolithic-architecture/#distributed-monolith" rel="noopener noreferrer"&gt;Distributed Monolith&lt;/a&gt;.&lt;br&gt;
On top of that, I don't believe any modern message broker provides 2PC as an option, hence you will have to build and maintain your own Coordinator.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sagas
&lt;/h3&gt;

&lt;p&gt;In opposition to Two-Phase Commit, &lt;a href="https://microservices.io/patterns/data/saga.html" rel="noopener noreferrer"&gt;Saga&lt;/a&gt; guarantees Availability over Consistency. Meaning that data will be eventually consistent.&lt;br&gt;
It is the most common approach to enforcing data consistency in Microservice Architecture.&lt;/p&gt;

&lt;p&gt;Saga represents a controlled sequence of independent transactions executed by each service in the cluster. If one of the services fails to execute the necessary transaction, the rollback is performed by a sequence of compensative transactions.&lt;/p&gt;

&lt;p&gt;The saga comes in two flavors. Depending on who coordinates its execution. It can be either service choreographed or service orchestrated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Service Choreography
&lt;/h4&gt;

&lt;p&gt;Service Choreography is a model of decentralized service composition. Knowledge of Saga and how to execute it is spread among services that participate in Saga.&lt;br&gt;
Each service knows which service it needs to send a message to if it successfully executes a local transaction. And it also knows how to construct (and where to send) a compensative message in case a local transaction fails or a successive service sends a compensative transaction.&lt;br&gt;
We wouldn't necessarily use direct communication between services (like RPC), but rather a queue.&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%2F9koi4ip7boz9gj6pgy11.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%2F9koi4ip7boz9gj6pgy11.png" alt="Saga Choreography"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Service Orchestration
&lt;/h4&gt;

&lt;p&gt;Service Orchestration is a model of centralized service composition. Saga is coordinated by orchestration service. The main role of the orchestrator is to deliver the message from the sender to all other Saga participants (aka message subscribers). Often a message broker is employed as an orchestrator. Both general and compensation messages are coordinated by the orchestrator.&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%2Fs9dnc0hydkr6l7w188ac.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%2Fs9dnc0hydkr6l7w188ac.png" alt="saga orchestration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;I'd recommend using Service Orchestrated Sagas with a modern Message Broker as an orchestrator for implementing data consistency in the Microservice Architecture.&lt;br&gt;
The message broker will decouple services in the cluster. It will reduce friction surfaces between services, and in opposition to Service Choreographed Sagas, it will remove unnecessary awareness from each service about its Saga predecessor and successor.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>microservices</category>
      <category>distributedsystems</category>
    </item>
    <item>
      <title>Monolithic Architecture</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Tue, 07 Jun 2022 10:03:51 +0000</pubDate>
      <link>https://forem.com/vudodov/monolithic-architecture-4p27</link>
      <guid>https://forem.com/vudodov/monolithic-architecture-4p27</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--28f4U2w5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cblssoxknys6ldhtug7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--28f4U2w5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cblssoxknys6ldhtug7z.png" alt="Stonehenge" width="880" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nowadays, Monolithic Architecture carries this exaggerated ill fame. I personally worked with a few monolithic architectures in the past. And there's something shameful in admitting that you work or have been working with a monolith. Imagine going to the interview and saying that you have deliberately built a monolith... Without supervising this claim with a context, you probably better not wait for an offer.&lt;/p&gt;

&lt;p&gt;Surprisingly, as we'll reveal a bit later, such a bad reputation was not caused by an architecture itself, or should I say solely by it.&lt;br&gt;
So why does this revolting feeling occur every time someone mentions Monolithic Architecture? And why do organizations keep building monoliths nowadays?&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Monolith?
&lt;/h2&gt;

&lt;p&gt;I'd like to draw a bold line 🖍️ between monolithic architecture and &lt;a href="https://en.wikipedia.org/wiki/Big_ball_of_mud#:~:text=A%20big%20ball%20of%20mud,type%20of%20design%20anti%2Dpattern."&gt;a big ball of mud&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Monolithic Architecture suggests that the application is a single unit, single logical executable, and single whole. Thus application is stored, developed, built, executed, and deployed as a single unit. The Monolithic Architecture is self-contained application architecture.&lt;/p&gt;

&lt;p&gt;Monolithic Architecture itself does not suggest any specific implementation practices or patterns. Underneath it might have a good separation of concerns (SoC), follow SOLID principles or implement event-sourcing, built within functional or object-oriented paradigm, etc.&lt;/p&gt;

&lt;p&gt;I'd like to emphasize that the Monolithic Architecture is not a bad practice or an anti-pattern. As well as the monolithic application is not necessarily a poorly designed one, and internally employs the worst available practices.&lt;/p&gt;

&lt;p&gt;So what's the catch? 🤨&lt;/p&gt;

&lt;h2&gt;
  
  
  Conway's Law
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Any organization that designs a system will produce a design whose structure is a copy of the organization's communication structure.&lt;br&gt;
— Melvin E. Conway&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An application and thus an architecture is a permanently evolving organism. It changes and adapts to an ever-changing environment. To survive it has to react to the most critical factors of the environment. Those factors usually include (but are not limited to) business needs and/or market opportunities, technical limitations and scalability requirements, financial aspects, etc. Therefore any architectural decision must be always viewed in the context of the time, phase of the product, and business targets at the time.&lt;/p&gt;

&lt;p&gt;Most of the time Monolithic Architecture is an unavoidable first step in the solution lifetime and the first stage of the application architecture evolution. And there are a few good reasons for that. First and foremost it is the easiest and fastest way to build an MVP (minimum viable product). Whereas time is an essential factor, especially if an organization adopts Lean Design and Agile practices.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---NbG8hT---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdgy41qr88kag8dzs89r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---NbG8hT---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bdgy41qr88kag8dzs89r.png" alt="Conway's law" width="880" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Often MVP is produced by a rather small organization or unit within the organization. Where communication between all members is efficient and effective. Given all that, this design fits well with Conway's law.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pivotal point 📉
&lt;/h2&gt;

&lt;p&gt;Of course, Monolithic Architecture has its own limitations (we will look closely on them in a few moments).&lt;br&gt;
And the first time when business bumps into them, it is rather a good sign. It signifies that the business took advantage of the market opportunity and successfully passed early adopters' validation. This is a pivotal point.&lt;/p&gt;

&lt;p&gt;It is crucial to recognize achieved milestones. And gently start shifting from strategic to tactical thinking. With business moving into the transition phase, it is a perfect moment for architecture limitations assessment and its re-consideration.&lt;/p&gt;

&lt;p&gt;Neglecting architecture evolution will unavoidably trigger fast-paced technical debt accumulation. And the dark side of Monolithic Architecture will start to show off. A rapidly growing business will most likely observe a snowball effect vividly, where overall development efficiency and application availability will degrade exponentially with respect to the business growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;All limitations we discuss below become evident after the MVP milestone. Where application enters the rapid growth phase. Focus transitions from the validation to the market growth (increase in active users) and new feature development become the main focus. This usually comes hand in hand with the development forces count increase.&lt;br&gt;
However, the longer the application architecture stays unchanged after the MVP the more emerging effect these limitations will have.&lt;/p&gt;

&lt;p&gt;This is where the bad reputation for Monolithic Architecture is originating from.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contributors
&lt;/h3&gt;

&lt;p&gt;The Monolithic Architecture suggests a single shared code base. And a single source of truth for the application's data.&lt;br&gt;
A growing amount of contributors will increase the effort required for new feature development. At first any significant and later almost any change will require a series of meetings between teams and extra orchestration.&lt;br&gt;
Obviously, it will unavoidably increase development time. And as a side-effect, it will also build up developers' reluctance to change shared parts of the application, especially the data-access layer. Which will lead to mixed separation of concerns (SoC) and ultimately degrade code quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Release
&lt;/h3&gt;

&lt;p&gt;The growing amount of contributors and teams entails a growing amount of integration/friction points. Any small change requires the re-deployment of the whole application. Deployments and especially releases now feel like a burden&lt;br&gt;
Continuous Deployment quickly goes out of the question.&lt;/p&gt;

&lt;p&gt;The release process becomes convoluted, shattered with bottlenecks and various box-ticking exercises.&lt;br&gt;
Every release will require some involvement from at least one representative from each team. Release of any size must be planned in advance. Often organizations introduce gatekeepers to control the process.&lt;/p&gt;

&lt;p&gt;Often each team will have its own dedicated testing environment to ensure that the development and feature testing process is isolated from constant interruptions by other teams' changes. This in its turn will introduce a certain level of testing redundancy in the release process, as now changes must be double-checked in the scope of release changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability 🆙
&lt;/h3&gt;

&lt;p&gt;Monolithic solutions have only one way of meeting growing demands. Scaling up, aka vertical scaling strategy. In other words, grow machine resources. This approach has multiple well-known disadvantages compared to scaling out (horizontal scaling strategy). And typically considered as a poor choice for scaling strategy.&lt;/p&gt;

&lt;p&gt;Compared to scaling out. It has a close hard limit. It is not flexible and poorly handling spike loads. Finally, it has lower failure tolerance and unavoidably longer downtimes. Should I say it is way more expensive?&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology
&lt;/h3&gt;

&lt;p&gt;Monolithic Architecture is usually constrained by technologies selected in the early stages.&lt;br&gt;
However, things are not necessarily smooth even with the existing tech stack. Any change in the framework or language will impact the whole application.&lt;br&gt;
Version upgrades are a risky and laborious process. Usually postponed for as long as possible. And as you can guess only stimulates technical debt accumulation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Distributed Monolith
&lt;/h2&gt;

&lt;p&gt;As an alternative to the Monolithic Architecture community came up with a Microservice Architecture (aka Microservices). However, often developers unintentionally introduce Distributed Monolith instead of (or within) Microservice Architecture.&lt;/p&gt;

&lt;p&gt;A common delusion is that a Microservice Architecture is an approach where some business process or application is built from a set of services (preferably small) as opposed to a Monolithic Architecture where everything is self-contained in a single whole.&lt;/p&gt;

&lt;p&gt;This is somewhat true. Although the definition above is leaking a few critical details.&lt;/p&gt;

&lt;p&gt;A Microservice Architecture is an approach where the application is built with a set of independently deployable services. The separation of concerns (SoC) is used to decide what concludes an individual service. Hence each service has its own business flow, well-defined purpose and boundaries. Each service is either stateless or owns its data.&lt;/p&gt;

&lt;p&gt;The Distributed Monolith is an application that does satisfy the first definition but does not satisfy the second one. Or...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e4hovIJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h0chcicugu1yr9vu5h7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e4hovIJi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6h0chcicugu1yr9vu5h7.png" alt="Distributed Monolith" width="880" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Distributed Monolith is an approach where the application is built with a set of services and at least one of the points below is true:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;some services can't be deployed independently&lt;/li&gt;
&lt;li&gt;some services are very chatty&lt;/li&gt;
&lt;li&gt;some services share data source&lt;/li&gt;
&lt;li&gt;some services don't scale dynamically (independent scaling)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Nowadays Monolithic Architecture is still a good tactical architecture for building an MVP. However, it is very risky to follow a monolithic approach after the initial phases of the product.&lt;/p&gt;

&lt;p&gt;Amazon, Netflix, and many others started with Monolithic Architecture. Of course, at that time they didn't have much choice as Monolithic Architecture was considered a traditional architecture, there were no cloud providers, etc.&lt;br&gt;
Nevertheless, nowadays a lot of organizations prefer to start with a Monolithic Architecture. Some of them wisely left the door open for further architectural evolutions. And more importantly, use it when the time comes. Others don't and as a result their development process ends up in a stagnation and solution falls into the tech debt spiral.&lt;br&gt;
In the latter case ultimately everyone agrees to blame Monolithic Architecture and promise "never again".&lt;/p&gt;

&lt;p&gt;I think Monolithic Architecture is undeservingly carries bad reputation. Even nowadays Monolithic Architecture has its own place and purpose in business automation and application development.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>microservices</category>
      <category>distributedsystems</category>
      <category>monolith</category>
    </item>
    <item>
      <title>JavaScript. Memory. Architecture and Lifecycle.</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Tue, 19 Oct 2021 07:13:38 +0000</pubDate>
      <link>https://forem.com/vudodov/javascript-memory-architecture-and-lifecycle-ae9</link>
      <guid>https://forem.com/vudodov/javascript-memory-architecture-and-lifecycle-ae9</guid>
      <description>&lt;p&gt;I'll start this article with a quote that changed the way I think of memory. The way I perceive memory lifecycle in major modern languages (those that have automatic memory release aka garbage collection).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Garbage collection is simulating a computer with an infinite amount of memory.&lt;br&gt;
-- &lt;a href="https://twitter.com/ChenCravat" rel="noopener noreferrer"&gt;Raymond Chen&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is exactly how we think of memory in JavaScript. We don't...&lt;/p&gt;

&lt;p&gt;Indeed, since I stopped writing C++ code I forgot about memory management. And I couldn't be bothered. Why would I? I mean it just works. Here's a variable, here's another one, no worries at all... Nowadays memory leak is rarely an issue. Most of the time you need to put an effort to create a one...&lt;/p&gt;

&lt;p&gt;But it wouldn't be JavaScript if there were no interesting quirks and features hidden behind this area...&lt;/p&gt;

&lt;p&gt;Further, we'll explore JavaScript memory architecture, main concepts and organization. And memory lifecycle, from allocation to release.&lt;br&gt;
Also, we'll look through some common memory leaks and how to avoid them.&lt;/p&gt;
&lt;h2&gt;
  
  
  Memory
&lt;/h2&gt;

&lt;p&gt;In programming everything requires space. Number, string, object, function. Even in the abstract Computer Science algorithmic department, there's a measurement for a space complexity.&lt;/p&gt;
&lt;h3&gt;
  
  
  Memory is different
&lt;/h3&gt;

&lt;p&gt;In JavaScript (similarly to many other languages) there are two main types of memory &lt;strong&gt;Stack&lt;/strong&gt; and &lt;strong&gt;Heap&lt;/strong&gt;. Both are managed by the &lt;a href="https://valerii-udodov.com/posts/run-javascript-run/#the-engine" rel="noopener noreferrer"&gt;JavaScript Engine&lt;/a&gt;, both are for storing runtime data.&lt;br&gt;
The difference lays in speed and size. Heap is bigger and slower, Stack is smaller and faster.&lt;/p&gt;

&lt;p&gt;How does the engine know which one to use? The rule of thumbs is: &lt;em&gt;if the engine is not sure about the size it uses Heap. If the engine can calculate the size beforehand, it uses Stack&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;All the primitives like &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;boolean&lt;/code&gt;, &lt;code&gt;string&lt;/code&gt;, &lt;code&gt;Symbol&lt;/code&gt;, &lt;code&gt;BigInt&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; always go to the Stack. Also, references are stored there, we'll talk about references in a minute.&lt;br&gt;
What's left will end up in the Heap. This includes arbitrary objects and functions.&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%2F5wjza3ht1gplz7yko7l5.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%2F5wjza3ht1gplz7yko7l5.jpg" alt="two jars"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 &lt;em&gt;The data that goes in the Stack is usually called static because it has a static size that won't change, hence it is allocated at the compile-time.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;The data that goes in the Heap is usually called dynamic because it has unpredictable size (and potentially can change throughout the program execution) and is allocated dynamically at the runtime.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;ℹ️ &lt;em&gt;Have you heard of the term &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting" rel="noopener noreferrer"&gt;Hoisting&lt;/a&gt;?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Memory allocation in the Stack (aka static memory allocation) happening right before the code (next lexical scope) execution. References are stored in the Stack, thus they are allocated before the code is executed. Hence if we declare the variable it will be available even before the actual declaration in the code. Although value will be &lt;code&gt;undefined&lt;/code&gt; because it doesn't have value to point to yet...&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;yolo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;yolo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Variables declared with &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;var&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; are hoisted, although &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt; won't return &lt;code&gt;undefined&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;The referencing concept is a major pillar of the JavaScript memory organization. It indirectly impacts how most of the key operations (such as assignment and equation) work.&lt;br&gt;
However often it is poorly understood and thus results in occasional surprises and confusions.&lt;/p&gt;

&lt;p&gt;Imagine a big bookshelf with multiple compartments. Each compartment has a label with a unique number on it. Every time you place something in the compartment you take a piece of paper and write down the number of the compartment and a short description of what is stored there.&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%2Fhsftlris7gute9h3d3y5.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%2Fhsftlris7gute9h3d3y5.jpg" alt="bookshelf"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the gist of how references work. The short description is a variable name, the shelf number is a memory address. The address is stored in the variable, which is stored in the Stack. And the actual object on the shelf is an object stored in the Heap, referenced by the variable...&lt;/p&gt;

&lt;p&gt;Every time we use the assign (=) operator we are &lt;strong&gt;not&lt;/strong&gt; assigning the value... We are creating a pointer to the memory where the value is stored. Your variable storing the address, that pointing to the memory where the actual value is stored.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Some personal opinion here...🤪&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I think the language we use matters. Therefore I think the word "assign" and operator &lt;code&gt;=&lt;/code&gt; is &lt;del&gt;evil&lt;/del&gt; misleading and creates cognitive confusion and unnecessary simplification. I think a huge amount of bugs came from such confusion.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I'd personally prefer to be more explicit about what is happening and suggest using a term like "pointing" or "referencing" instead of "assigning" and operator like &lt;code&gt;-&amp;gt;&lt;/code&gt; instead of &lt;code&gt;=&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But we have what we have 🤷&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now that we have an idea of memory organization, let's reinforce it with some examples. We will start with primitive values and gradually move toward objects...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&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%2F0dc7ixdskpuihrg07if1.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%2F0dc7ixdskpuihrg07if1.jpg" alt="42"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we figured before we are not setting value we are pointing to it... Pretty straightforward so far, let's make it a bit more complicated...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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;true_answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;answer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;43&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 43&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;true_answer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 42&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%2Fdgc206iyc1fjecvbmmos.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%2Fdgc206iyc1fjecvbmmos.gif" alt="42 43"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Same principle here. First both &lt;code&gt;answer&lt;/code&gt; and &lt;code&gt;trueAnswer&lt;/code&gt; point to the same address where value &lt;code&gt;42&lt;/code&gt; is stored. Once we do &lt;code&gt;answer = 43&lt;/code&gt; we change not the value, but memory where we pointing...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Primitives are immutable. It kinda becomes obvious and almost redundant to mention if we talk it through. If we try to change &lt;code&gt;42&lt;/code&gt; (e.g. add &lt;code&gt;1&lt;/code&gt; to it), we will simply get another number, which is not &lt;code&gt;42&lt;/code&gt;...we won't change &lt;code&gt;42&lt;/code&gt; (&lt;code&gt;42&lt;/code&gt; will still exist)... Hence it is immutable.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Nor we can extend it. E.g. &lt;code&gt;42.value = 22&lt;/code&gt; won't work, although it will if &lt;code&gt;42&lt;/code&gt; would be an object...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hope it all made sense lol 😅&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's do another example with primitives... &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; are primitives. What does that mean? They act like all primitives...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;null1&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;null2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;null1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;null2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;undefined1&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;undefined2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;undefined1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;undefined2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&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%2F1bgpct13q5s4p4djcyd6.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%2F1bgpct13q5s4p4djcyd6.gif" alt="null and undefined"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we see why both values are strictly equal, pointing to the same value.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Funny fact&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// object&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;It is not true, &lt;code&gt;null&lt;/code&gt; is not an object. It is &lt;a href="https://2ality.com/2013/10/typeof-null.html?ck_subscriber_id=727966771" rel="noopener noreferrer"&gt;a bug&lt;/a&gt; that can't and won't be fixed...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's do the last one on primitives...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&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%2Fkilut1zuzfb6kbn2gg1v.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%2Fkilut1zuzfb6kbn2gg1v.jpg" alt="boolean"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything looks very familiar.&lt;/p&gt;

&lt;p&gt;Now let's try something new. Objects. Objects are different, they represent a more complex tree-structure 🌳. And unlike primitives, objects are mutable. This property produces some interesting effects.&lt;br&gt;
This is where the &lt;code&gt;=&lt;/code&gt; operator will reveal its full evilness 😈.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catzilla&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Catzilla&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bengal Cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;peanut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;catzilla&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peanut&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catzilla&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { name: "Peanut", breed: "Bengal Cat" }&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { name: "Peanut", breed: "Bengal Cat" }&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%2Fn1c8k9es38zkncf0yn20.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%2Fn1c8k9es38zkncf0yn20.gif" alt="catzilla"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Probably not what was intended...&lt;br&gt;
Remember that the &lt;code&gt;=&lt;/code&gt; actually points to the data. We are just routing pointers here.&lt;/p&gt;

&lt;p&gt;Luckily we can fix it easily...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catzilla&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Catzilla&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bengal Cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;peanut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;catzilla&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peanut&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catzilla&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { name: "Catzilla", breed: "Bengal Cat" }&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { name: "Peanut", breed: "Bengal Cat" }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a help of &lt;code&gt;...&lt;/code&gt; (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax" rel="noopener noreferrer"&gt;spread operator&lt;/a&gt;) we managed to clone whatever &lt;code&gt;catzilla&lt;/code&gt; was pointing to in the new address and made &lt;code&gt;peanut&lt;/code&gt; point to it. This is not the original intention, how this operator should be used. But (as it usually happens with JavaScript) this side-effect was warmly accepted by the JavaScript community as a way to perform shallow cloning.&lt;/p&gt;

&lt;p&gt;Things start to get really messy with more complicated objects...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;breed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bengal Cat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;origin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;United States&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;spotted&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;brown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;catzilla&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Catzilla&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;breed&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;peanut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;catzilla&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peanut&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;marble&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catzilla&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*
  {
    name: "Catzilla",
    breed: {
      name: "Bengal Cat",
      origin: "United States,
      color: {
        pattern: "spotted",
        name: "marble"
      }
    }
  }
*/&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;peanut&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*
  {
    name: "Peanut",
    breed: {
      name: "Bengal Cat",
      origin: "United States,
      color: {
        pattern: "spotted",
        name: "marble"
      }
    }
  }
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It happened again... Both cats have the same color, although it wasn't the intention...&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%2F5sc125nmsris3oxzwe6a.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%2F5sc125nmsris3oxzwe6a.gif" alt="catzilla again"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are performing the so-called shallow clone only top layer (first level of the tree), to make it work properly we need to perform so-called deep cloning. The easiest way would be doing something like...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;peanut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;catzilla&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ugly, but does the job. It forces the engine to allocate a new chunk of memory and fill it with object data.&lt;br&gt;
Unfortunately, JavaScript does not provide a good cloning mechanism out of the box. Hence this is the approach to clone the object without employing extra tools.&lt;br&gt;
If you are after a more elegant and efficient solution, I'd recommend using something like &lt;a href="https://underscorejs.org/" rel="noopener noreferrer"&gt;underscore.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Alright, here's a curly one ⚾... Can you guess why this happening?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({}&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Surprised?&lt;br&gt;
Let's try to re-write this example a bit...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;value1&lt;/span&gt; &lt;span class="o"&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;value2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;value2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Does it make more sense?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;To understand it completely we need to understand how the equals &lt;code&gt;==&lt;/code&gt; and the strictly equals &lt;code&gt;===&lt;/code&gt; operators work, unfortunately, it is not very trivial. However, to prevent this article from bloating, let's just say that comparison happening by actual value in the variable. As we know now it is an address of the object, rather than value. Because we are pointing to two different objects, located by two different addresses. Values are not equal...&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6wmat4zyz993n3k4lart.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%2F6wmat4zyz993n3k4lart.jpg" alt="two objects"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Garbage Collection
&lt;/h2&gt;

&lt;p&gt;The concept of reference (which we just discussed) is what the process of memory releasing/cleaning (aka garbage collection) is based on. Using references garbage collector can determine what is "garbage" and requires a collection and what is not yet.&lt;/p&gt;

&lt;p&gt;There are two main algorithms used for that matter.&lt;br&gt;
The "new" one: its variation is used in all modern browsers&lt;br&gt;
And "old" one: nowadays its variation is rarely used anywhere, because of its built-in flaws (we'll talk about them further)&lt;/p&gt;
&lt;h3&gt;
  
  
  New: Mark And Sweep
&lt;/h3&gt;

&lt;p&gt;Principle lays in finding &lt;strong&gt;unreachable&lt;/strong&gt; objects...&lt;br&gt;
The unreachable object is any object that can't be reached via traversal through references from the so-called &lt;em&gt;root&lt;/em&gt;. In browser-world &lt;em&gt;root&lt;/em&gt; is represented by the &lt;code&gt;window&lt;/code&gt; object (aka Global Scope).&lt;/p&gt;

&lt;p&gt;📝 &lt;em&gt;Just a side-note, that all global variables in JavaScript are not hanging in the air, they are rather attached with references to the &lt;code&gt;window&lt;/code&gt; object...&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every now and then, garbage collector starts. And follows these phases&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start phase: Once started, it assumes that all objects are unreachable.&lt;/li&gt;
&lt;li&gt;Mark phase: Then the actual tree traversal from the &lt;em&gt;root&lt;/em&gt; (through references) starts. Every object found on the way is marked as reachable.&lt;/li&gt;
&lt;li&gt;Sweep phase: Once traversal is finished all unreachable objects are eliminated.&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%2Fq039crkb9qkgu4i14t9h.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%2Fq039crkb9qkgu4i14t9h.gif" alt="garbage collection diagram"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Optimization
&lt;/h4&gt;

&lt;p&gt;Mark and Sweep algorithm belong to the &lt;a href="https://en.wikipedia.org/wiki/Tracing_garbage_collection" rel="noopener noreferrer"&gt;Tracing Garbage Collection&lt;/a&gt; family. There are few family-dedicated optimizations (like tri-color marking). These are low-hanging fruits 🍐.&lt;/p&gt;

&lt;p&gt;Nevertheless, most JavaScript Engines will perform some additional optimizations that are usually borrowed from other garbage-collected languages.&lt;/p&gt;

&lt;p&gt;One such classic optimization is the so-called garbage collection based on generations.&lt;br&gt;
The principle is based on one observation. Old objects are less likely to be garbage-collected. They proved it by surviving multiple garbage collections. Thus statistically we can assume these objects will be kept in use.&lt;br&gt;
With this knowledge, we can improve the garbage collection time significantly by simply rarely bothering old objects 👴.&lt;/p&gt;

&lt;p&gt;Here is how it works. Each object is assigned to a generation. All objects start at the zero generation. If an object survives garbage collection it moves up, to the next generation. The garbage collection is happening on the young generations more frequently than on old ones.&lt;br&gt;
The more garbage collections object survive the older generation it is assigned to and the less likely it will be collected.&lt;br&gt;
Ultimately this approach reduces traversals through statistically "low-chance-collection" candidates. And focus on those who statistically have higher chances to be collected...&lt;/p&gt;
&lt;h3&gt;
  
  
  Old: Reference Counting
&lt;/h3&gt;

&lt;p&gt;This algorithm was last used in IE 7 and deprecated since 2012. So this section serves purely historical purposes.&lt;/p&gt;

&lt;p&gt;Unlike the Mark and Sweep, this one will try to find unreferenced objects instead of unreachable...&lt;br&gt;
This algorithm does not try to determine whether the object is still needed (in the previous example reachable from the &lt;em&gt;root&lt;/em&gt;). Instead, it only checks if anything references the object.&lt;/p&gt;

&lt;p&gt;This might not look like a big difference, but this approach is less restrictive. And due to this fact comes with a major flaw.&lt;/p&gt;
&lt;h4&gt;
  
  
  Major flaw
&lt;/h4&gt;

&lt;p&gt;The major flaw is circular references. Two objects might not be reachable, but as long as they reference each other they won't be collected.&lt;/p&gt;

&lt;p&gt;Let's look at the following example...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;catdog&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

  &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;catdog&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code (if used with the current algorithm) creates a memory leak. Because memory allocated for variables &lt;code&gt;cat&lt;/code&gt; and &lt;code&gt;dog&lt;/code&gt; will never be collected, even though it never used in outer scope...🐱🐶&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory Leaks
&lt;/h2&gt;

&lt;p&gt;🤔 &lt;em&gt;Why do memory leaks still exist?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Because the process of determining whether a certain piece of memory is used or not is a so-called &lt;a href="https://en.wikipedia.org/wiki/List_of_undecidable_problems" rel="noopener noreferrer"&gt;undecidable problem&lt;/a&gt;. Sounds scary, but it means that there's no good way to program a machine to determine if memory can be safely released. Thus only a human can make a real complete judgment about it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While we were exploring the old garbage collection algorithm we saw an example of a memory leak. It appears that a memory leak is just an accidentally forgotten reference to an object. An object that never going to be garbage-collected. And will keep uselessly occupy memory as long as the application is running. There are quite a few ways to create a memory leak.&lt;br&gt;
Since we know how the memory is allocated and garbage-collected we can look through few most common examples&lt;/p&gt;
&lt;h3&gt;
  
  
  Global variables
&lt;/h3&gt;

&lt;p&gt;Nowadays usage of global variables is a mauvais ton (bad practice). If happens, it is usually accidental. This problem can be easily caught by the linter 👮. Or prevented from happening by adding &lt;code&gt;use strict&lt;/code&gt; at the beginning of the file.&lt;/p&gt;

&lt;p&gt;The leak happens like this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create a global variable (it is automatically referenced by &lt;code&gt;window&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;And it forever stays there...&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  The Fix
&lt;/h4&gt;

&lt;p&gt;Don't use global variables.&lt;br&gt;
It has been recognized as a bad practice for a reason. So the best way to avoid this problem is simply to avoid global variables.&lt;/p&gt;
&lt;h3&gt;
  
  
  Observers or Forgotten interval timers
&lt;/h3&gt;

&lt;p&gt;This one is harder to trace, we forget to release timers once we don't need them.&lt;/p&gt;

&lt;p&gt;This leak happens like this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We create an interval timer with a callback like &lt;code&gt;setInterval(() =&amp;gt; {}, 1000);&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We make sure we referencing something from the outer scope&lt;/li&gt;
&lt;li&gt;The thing we reference will never be garbage-collected
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;memoryLeak&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;massiveData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I am your memory leak!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;memoryLeak&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;memoryLeak&lt;/code&gt; object will never be released even though we might not need the whole object anymore.&lt;/p&gt;
&lt;h4&gt;
  
  
  The Fix
&lt;/h4&gt;

&lt;p&gt;The best way to prevent this from happening is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ...&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;timerId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;memoryLeak&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// do stuff&lt;/span&gt;

&lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A Camouflaged version of the global variable or Detached DOM elements
&lt;/h3&gt;

&lt;p&gt;Another classical one. If you are working with something like React or Angular, there's no reason to worry. Nevertheless, it is an interesting way to lose some memory 🧠...&lt;br&gt;
It is a camouflage version of the global variable memory leak. And it happens even nowadays pretty often, usually in-between the &lt;code&gt;script&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;This leak happens like this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We reference arbitrary DOM elements in the code (e.g. by calling &lt;code&gt;document.getElementById('i-will-leak')&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Even though we delete the element from the DOM it still hangs in the lexical scope or global scope (e.g. by calling &lt;code&gt;document.body.removeChild(document.getElementById('i-will-leak'))&lt;/code&gt;)
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;memoryLeak&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i-will-leak&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;memoryLeak&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;memoryLeak&lt;/code&gt; will never be garbage-collected, the &lt;code&gt;removeChild&lt;/code&gt; here is very misleading, it seems like it will remove the element from everywhere, but it does it only for the DOM tree.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Fix
&lt;/h3&gt;

&lt;p&gt;The fix is the same as for the Global Variables leak. Don't use global variables 😀 Instead, we can use child lexical scope, e.g. function&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doStuff&lt;/span&gt;&lt;span class="p"&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;memoryLeak&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;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i-will-leak&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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;memoryLeak&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is self-executable function will create a local lexical scope and after it will finish execution, all local variables will be garbage-collected.&lt;/p&gt;

&lt;h2&gt;
  
  
  P.S.
&lt;/h2&gt;

&lt;p&gt;If you've read my &lt;a href="https://valerii-udodov.com/tags/javascript-runtime/" rel="noopener noreferrer"&gt;previous JavaScript-Runtime-related articles&lt;/a&gt;, you know that JavaScript Runtime differs between browsers. Therefore the way memory is managed from browser to browser might be different. Although it would be unfair not to mention that in the past decade more and more commonalities appearing. And reduces a headache for us...&lt;br&gt;
Moreover, given the unstoppably growing JavaScript infrastructure, including various linters, module bundlers, and well-matured frameworks for DOM interactions, problems with memory leaks are reduced to a bare minimum.&lt;/p&gt;

&lt;p&gt;But...Garbage collection is still listed as an &lt;a href="https://en.wikipedia.org/wiki/List_of_undecidable_problems" rel="noopener noreferrer"&gt;undecidable problem&lt;/a&gt;, hence there's always a way to make a boo-boo. Understanding the way JavaScript organizes the memory and how references are managed might save you hours and hours of debugging.&lt;/p&gt;

&lt;p&gt;Anyhow, hope you enjoyed the read and found something new for yourself 😀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>memory</category>
      <category>garbagecollector</category>
    </item>
    <item>
      <title>Run, JavaScript, Run</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Thu, 09 Sep 2021 02:09:10 +0000</pubDate>
      <link>https://forem.com/vudodov/run-javascript-run-3lf4</link>
      <guid>https://forem.com/vudodov/run-javascript-run-3lf4</guid>
      <description>&lt;h2&gt;
  
  
  Preamble
&lt;/h2&gt;

&lt;p&gt;Let's admit. JavaScript is not the most predictable language out there. It might get pretty quirky very easily.&lt;br&gt;
Let's look at the following example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1. timeout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2. console&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3. promise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// prints&lt;/span&gt;
&lt;span class="c1"&gt;// 2. console&lt;/span&gt;
&lt;span class="c1"&gt;// 3. promise&lt;/span&gt;
&lt;span class="c1"&gt;// 1. timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if we will change the order of instructions, it won't impact the final result 🤨&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1. promise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2. timeout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3. console&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// prints&lt;/span&gt;
&lt;span class="c1"&gt;// 3. console&lt;/span&gt;
&lt;span class="c1"&gt;// 1. promise&lt;/span&gt;
&lt;span class="c1"&gt;// 2. timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't matter how we will shuffle these three lines, they will always end up executed in the same order &lt;code&gt;console, promise, timeout&lt;/code&gt; 😐&lt;/p&gt;

&lt;p&gt;Why? Well, you know...&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%2Fontw129r4wu5zgworoy0.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%2Fuploads%2Farticles%2Fontw129r4wu5zgworoy0.jpeg" alt="javascript"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, there is a good (enough) reason for that. And we'll get to it shortly. But first, we need to clarify a thing or two.&lt;br&gt;
Put on your JavaScript hat and let's go! 🎩&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We are going to focus on the Web Browser JavaScript, nonetheless most of the things we are going to discuss can be correlated to other agents, such as NodeJS.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;em&gt;Worth mentioning&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;code&gt;setTimeout(() =&amp;gt; {})&lt;/code&gt; is equal to calling &lt;code&gt;setTimeout(() =&amp;gt; {}, 0)&lt;/code&gt;.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Although neither will guaranty immediate execution as the timeout value (&lt;code&gt;0&lt;/code&gt;) is used to set the minimum wait period, not the exact period.&lt;br&gt;
Anyhow example above is completely legit in a given context.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  One thing at a time
&lt;/h3&gt;

&lt;p&gt;There's one important aspect of JavaScript we need to call out from the start. The single-threaded nature of the environment it runs in. It is hard to overstate the impact of this fact on the language, web browsers, and ultimately anything that runs JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;one thread === one call stack === one thing at a time&lt;/strong&gt;&lt;br&gt;
Pause here for a sec... One thing at a time...&lt;/p&gt;

&lt;p&gt;Even when it seems like multiple things are happening simultaneously, in reality, there's only one single task that gets executed at every given moment, just really fast.&lt;/p&gt;

&lt;p&gt;The single thread we were talking about is called &lt;em&gt;browser main thread&lt;/em&gt; (nowadays more accurate name would be a tab main thread 🙃)... Thus &lt;strong&gt;everything&lt;/strong&gt; that happening on the page is happening in one single thread.&lt;br&gt;
It is easy to underestimate the scale. While our gorgeous code is running, meantime the web browser is rendering page content, receiving and dispatching all sorts of events, doing garbage collection, distributing future work, and much more...&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;em&gt;What about JavaScript Console, that thing we all use in the Browser Dev Tools?&lt;/em&gt;&lt;br&gt;
&lt;em&gt;It depends, but most likely it will be a different process, hence a different thread.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;❗Exception...&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The "single thread" thing is the default behavior, however, we can branch from the main thread and run our JavaScript code in the separate thread with a help of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API" rel="noopener noreferrer"&gt;Web Workers API&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;A single thread is not a mistake or a bad design. Make JavaScript single-threaded was a conscious decision... Years ago, the average computer had a single core and was less powerful than any mid-range phone today. Websites were not really interactive (if at all), hence didn't really need any JavaScript magic.&lt;br&gt;
Who could foresee where it is going to end up...&lt;/p&gt;
&lt;h2&gt;
  
  
  That thing that runs your JavaScript
&lt;/h2&gt;

&lt;p&gt;Often terms JavaScript Runtime and JavaScript Engine are used interchangeably. Nevertheless, they are like salt 🧂 and green 🟩. Two completely different things. Let me explain what I mean.&lt;/p&gt;

&lt;p&gt;Three main pieces constitute the JavaScript Runtime. They are conceptually separated. And most likely developed by different people/teams/companies, and represent independent pieces of software. However, they work in close collaboration.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;JavaScript Engine&lt;/em&gt;: compiles, optimizes, and executes code, handles memory allocation and garbage collection&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Event Loop&lt;/em&gt;: orchestrates and distributes the work, enables asynchronicity.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Browser Web API&lt;/em&gt;: allows communication with things located outside of the Runtime (e.g system timers, file system, HTTP, address bar, DOM, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Big 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjtq5cffeiuq49uyufknm.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%2Fjtq5cffeiuq49uyufknm.jpg" alt="runtime"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Engine
&lt;/h2&gt;

&lt;p&gt;The JavaScript Engine... does not run JavaScript...It runs ECMAScript.&lt;br&gt;
Isn't it the same thing? Appears no, I'll explain.&lt;/p&gt;

&lt;p&gt;If we will look through the source code of an arbitrary JavaScript engine (you know, cuz it is a casual thing we do lol 🤪), we will find an implementation of the &lt;a href="https://tc39.es/ecma262/" rel="noopener noreferrer"&gt;ECMAScript declaration&lt;/a&gt;. This will include all sorts of base objects (including &lt;code&gt;Object&lt;/code&gt;) such as &lt;code&gt;Date&lt;/code&gt; and &lt;code&gt;String&lt;/code&gt;, key language constructions like loops, conditions, and so forth.&lt;br&gt;
However, if we will look for say &lt;code&gt;setTimer&lt;/code&gt; or &lt;code&gt;fetch&lt;/code&gt;, we won't find much. Because they are not part of ECMAScript. They are part of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API" rel="noopener noreferrer"&gt;Browser Web API&lt;/a&gt; (nothing to do with Web itself really, more like Browser API 🙃, but you'll find it going under Web API, Web Browser API, Browser API and simply API).&lt;/p&gt;

&lt;p&gt;The JavaScript Engine will be managing memory and controlling the execution of our fabulous code. Which will never be executed in its original shape, the engine will keep modifying it all the time. Most of the engines are pretty smart, they will keep optimizing the code throughout the page lifetime in the constant chase for performance improvements.&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%2Frqci8n6yrtfytqt853pc.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%2Frqci8n6yrtfytqt853pc.jpg" alt="engine"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Important though is that the engine &lt;strong&gt;only executes the code&lt;/strong&gt; that it finds in the Stack of Frames (or Call Stack or simply the Stack). Each frame represents a function call. While the engine is running the code, it might discover a new function call (not to be confused with function declaration) and push it to the Call Stack as a new frame. Once a new frame has been added, the engine pauses the execution of the current frame and focuses on the new one. After Engine finishes frame(function) execution it pops it from the stack and continues where it left, assuming it is not the last frame.&lt;br&gt;
Every function call will end up as a new item on the Call Stack. Worth mentioning that Engine does not own exclusive rights on pushes to the Call Stack, new work might be pushed from the outside of the engine boundaries (we'll talk about it next).&lt;br&gt;
The Call Stack controls the execution sequence inside Engine. Engine won't stop popping frames from the Call Stack until it is empty. And it won't allow any interruptions from outside until it is done.&lt;/p&gt;

&lt;p&gt;⏪ &lt;em&gt;In the previous article &lt;a href="https://valerii-udodov.com/posts/web-browser-anatomy/#the-javascript-engine" rel="noopener noreferrer"&gt;Web Browser Anatomy&lt;/a&gt; we've already discussed some of the key JavaScript engine aspects (parsing, pre-parsing, compilation, and optimization/de-optimization). With a deeper focus on the &lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8&lt;/a&gt; Compilation Pipeline.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;The article is more focused on the code processing itself and slightly touches Browser Engine (not to be confused with JavaScript Engine) and basic rendering concepts, so if it sounds interesting, don't forget to check it out after.&lt;/em&gt; 😏&lt;/p&gt;
&lt;h2&gt;
  
  
  The Loop
&lt;/h2&gt;

&lt;p&gt;The Event Loop is an orchestrator and the main distributor of the work. It does not perform the work itself, but it ensures that the work is distributed in the expected manner (which may vary from browser to browser).&lt;/p&gt;

&lt;p&gt;It is literally an infinite loop ♾️ which constantly keeps checking if there's any work it can schedule for execution.&lt;br&gt;
A simplified version would look like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;while &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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;allDone&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;thingsToDo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getThingsToDo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;doThings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;thingsToDo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ℹ️ &lt;em&gt;On each iteration, the Event Loop performs an ordered series of jobs defined in the &lt;a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model" rel="noopener noreferrer"&gt;processing model documentation&lt;/a&gt;. We will be getting back to it through the course of the article.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Event Loop and event loops
&lt;/h2&gt;

&lt;p&gt;The Event Loop we usually refer to in the context of the web browser is a &lt;em&gt;Window Event Loop&lt;/em&gt;. Every &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Origin" rel="noopener noreferrer"&gt;origin&lt;/a&gt; will get one. However, sometimes few tabs/windows from the same origin might share a single loop. Especially when one tab is opened from another. (This is where we can exploit multiple tabs/pages at once)&lt;/p&gt;

&lt;p&gt;Anyhow, &lt;em&gt;Window Event Loop&lt;/em&gt; is not the only one event loop running in the browser. Web workers (and other workers) will use its own &lt;em&gt;Worker Event Loop&lt;/em&gt;. Sometimes it will be shared across all workers. And &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Worklet" rel="noopener noreferrer"&gt;worklets&lt;/a&gt; will have its own &lt;em&gt;Worklet Event Loop&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;But hereafter when we refer to Event Loop we will actually be referring to the &lt;em&gt;Window Event Loop&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tasks, Microtasks and Macrotasks
&lt;/h3&gt;

&lt;p&gt;Given the single-threaded nature of the language, it is hard to overstate the importance of asynchronicity.&lt;br&gt;
The async behavior is implemented by a set of queues (FIFO).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a very common approach. Queues are very comfortable for implementing asynchronicity in software (and beyond its boundaries).&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Think of a cloud architecture. With a high probability in its heart, there will be some sort of queue that will be dispatching messages all over the place.&lt;br&gt;
Anyway, back to JavaScript.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7tfc80b3km6fvyjf369.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%2Fa7tfc80b3km6fvyjf369.jpg" alt="loop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two (not three...) main types of queues, task queue, and microtask queue. At the first glance, it might look like they are identical. And it is true to some degree, they have the same role: postpone code execution for later. The difference lies in how Event Loop uses them.&lt;/p&gt;

&lt;p&gt;❔&lt;em&gt;You probably wondering where did macrotasks go...&lt;br&gt;
Macrotask is just a V8 name for the task. So thereafter we will use the term task and everything we say for the task can be applied to macrotask&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Task queue
&lt;/h4&gt;

&lt;p&gt;The task queue is what keeps the whole thing spinning. This is where most of our code gets scheduled for execution. Event the initial code (the one that we place in-between the &lt;code&gt;&amp;lt;script&amp;gt;...&amp;lt;/script&amp;gt;&lt;/code&gt; tags) gets to the Call Stack through the Task Queue.&lt;/p&gt;

&lt;p&gt;Often our code looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;do this on button click
do that when the server responds
call the server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, we define callbacks (what to do) and assign them to events (when to do) that suppose to trigger them. When the event happens it does not execute the callback immediately, instead, it creates and enqueues a task in the Task Queue, which in its turn will be eventually processed (in other words pushed to the Call Stack).&lt;/p&gt;

&lt;p&gt;The queue is out of our direct reach. Dequeueing is happening inside the event loop. Most of the tasks are enqueued through so-called generic task sources. This includes &lt;a href="https://w3c.github.io/uievents/#event-types" rel="noopener noreferrer"&gt;user interactions&lt;/a&gt;, &lt;a href="https://dom.spec.whatwg.org/#events" rel="noopener noreferrer"&gt;DOM manipulation&lt;/a&gt;, &lt;a href="https://xhr.spec.whatwg.org/#interface-xmlhttprequest" rel="noopener noreferrer"&gt;network activity&lt;/a&gt; and &lt;a href="https://html.spec.whatwg.org/multipage/history.html#history-3" rel="noopener noreferrer"&gt;history&lt;/a&gt;. Although we obviously have a way to impact what and when will get to the Task Queue (e.g through event handling).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ok, that's gonna be a tough sentence, so bear with me here... Dequeueing process happening once per iteration and it will least (keep dequeuing) until the newest task from the previous iteration (that have been in the queue at the moment of the beginning iteration) is still in the queue. Keep in mind that the newest tasks will be in the tail of the queue, due to FIFO (First In First Out) concept.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;In other words, all new tasks we are adding will be executed in the next iteration, all current/old tasks will be executed in this iteration.&lt;br&gt;
As per &lt;a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model" rel="noopener noreferrer"&gt;processing model documentation&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;😮 &lt;em&gt;The task queue is not really a queue, but an ordered set. However, it is not very important as its behavior in this context is equivalent to the queue.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There might be (and probably will be) multiple task queues in a single event loop. The most common reason for that is task priority management. E.g. there might be a separate task queue for user interactions and another queue for everything else. This way we can give user interactions higher priority and handle them before anything else.&lt;/p&gt;
&lt;h4&gt;
  
  
  Microtask queue
&lt;/h4&gt;

&lt;p&gt;Promises, asynchronous functions all this goodness is empowered by the microtask queue. It is very similar to the task queue, except for three major differences.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Microtasks are processed at different phases in the Event Loop iteration. We mentioned above that each Event Loop iteration following strict order known as &lt;a href="https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model" rel="noopener noreferrer"&gt;processing model&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Microtasks can schedule other microtasks and the new iteration of the Event Loop won't begin until we reach the end of the queue;&lt;/li&gt;
&lt;li&gt;We can directly enqueue a microtask with &lt;a href="https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing" rel="noopener noreferrer"&gt;queueMicrotask&lt;/a&gt;;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rest is pretty much the same, once a task is dequeued and a callback is extracted, it will be pushed to the Call Stack for immediate execution.&lt;/p&gt;
&lt;h2&gt;
  
  
  Browser Web API
&lt;/h2&gt;

&lt;p&gt;The final piece in the puzzle is an API, the Browser API. The connection bridge between the code and everything outside of the runtime.&lt;/p&gt;

&lt;p&gt;Communication with a file system or remote service calls. Various event subscriptions. Interactions with the address bar and history. And more. Is facilitated by Browser API.&lt;/p&gt;

&lt;p&gt;Browser API allows us to define event handlers. And this is the most common way for developers to pass callbacks (event handlers) to the Task Queue.&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%2Fyv5949pclzakvdgaooyt.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%2Fyv5949pclzakvdgaooyt.jpg" alt="api"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Browser API are browser-specific. Each browser implements them separately. Hence they work differently, although probably will have the same effect.&lt;br&gt;
Hence every now and then you might bump into a cool new feature that won't be supported by &lt;del&gt;Internet Explorer&lt;/del&gt; Browser X. And the most common reason, the API is not implemented in the Browser X.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;At least nowadays the naming is kinda conventional and no one tries to show uniqueness...&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Imagine writing code when all browsers would name things differently and everything would produce different effects... That would be a nightmare, wouldn't it?&lt;br&gt;
Well, it used to be like that. And it is kinda like this nowadays lol. Fortunately, we have many tools like &lt;a href="https://babeljs.io/" rel="noopener noreferrer"&gt;BabelJS&lt;/a&gt; and a huge community behind that helps mitigate this problem for us.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I still remember 👴 how you had to implement ajax calls (XMLHTTPRequest) for all possible browsers in your code until the &lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt; appeared. That was a game-changer.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Bringing things together
&lt;/h2&gt;

&lt;p&gt;We've discussed quite a few things thus far. Let's bring them all together in a single list. And go over it in the same order as Event Loop will.&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%2Fsgd2sr9azw5sb65w9nu7.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%2Fsgd2sr9azw5sb65w9nu7.jpg" alt="ordered runtime"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Remember that once some code gets in the Call Stack, the Engine will hijack control and start popping, executing, and pushing the code until finally, the Call Stack is empty. Once reached the end of the stack it returns control to the same point where it hijacked it.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The browser will find some JavaScript either in-between the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags or in the DevTools Console. And ultimately it will push it to the Task Queue...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Loop keeps checking the Task Queue. Once it finds the initial code the Loop will move it to the Call Stack. The Engine immediately takes over and doing its job until it empties the Call Stack.&lt;/li&gt;
&lt;li&gt;The Loop will check microtask queue(s). It will keep dequeuing tasks from the queue and pushing them (one item at a time) to the Call Stack (and it will keep executing until empty) from the microtask queue until the microtask queue is empty. Remember that microtask code can push another microtask in the queue and it will be executed during the same iteration (right here).&lt;/li&gt;
&lt;li&gt;Both Engine Call Stack and Microtask Queue are now empty.&lt;/li&gt;
&lt;li&gt;Finally the Loop gets back to the Task Queue. Keep in mind that events were emitting all the time, either in the code or outside of it. The Loop will mark the newest task (the one in the tail of the queue) in the queue and start dequeuing tasks from oldest to newest (head to tail) and pushing code to the Engine Call Stack until it reaches marked task.&lt;/li&gt;
&lt;li&gt;Next it will do some other unrelated to the runtime work, like rendering.&lt;/li&gt;
&lt;li&gt;Once all is done the new iteration starts from point 1&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  The example
&lt;/h3&gt;

&lt;p&gt;Let's revisit the example from the beginning of the article...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1. timeout&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2. console&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3. promise&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// prints&lt;/span&gt;
&lt;span class="c1"&gt;// 2. console&lt;/span&gt;
&lt;span class="c1"&gt;// 3. promise&lt;/span&gt;
&lt;span class="c1"&gt;// 1. timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doesn't matter how we would shuffle instruction, the produced result will stay the same&lt;/p&gt;

&lt;p&gt;Actually now it makes much more sense, check it out.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, all this code is sent to the Call Stack and executed sequentially.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; almost immediately sends a callback to the Task Queue.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log&lt;/code&gt; prints string in the console (this is our first line &lt;code&gt;2. console&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Promise.resolve(...).then(...)&lt;/code&gt; is immediately resolved promise, thus it sends the callback to the Microtask Queue the same moment it is executed.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Stack finishes execution, it is empty and it passes control back to the Event Loop.&lt;/li&gt;

&lt;li&gt;Event Loop checks Microtask Queue and finds there callback from the resolved promise and sends it to the Call Stack (this is our second line &lt;code&gt;3. promise&lt;/code&gt;)&lt;/li&gt;

&lt;li&gt;Microtask Queue is empty, Call Stack is empty, it is Task Queue turn now.&lt;/li&gt;

&lt;li&gt;The Event Loop finds a timeout callback in the Task Queue and sends it to the Call Stack (this is our third and last line &lt;code&gt;1. timeout&lt;/code&gt;).&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;And we are done, the stack is empty along with all queues.&lt;br&gt;
That wasn't too bad, was it?&lt;/p&gt;
&lt;h2&gt;
  
  
  Recursion Examples
&lt;/h2&gt;

&lt;p&gt;Alright, it is time to have some fun! 🤓&lt;br&gt;
Given we already know how to interact and what to expect from both queues and a stack. We will try to implement three different infinite recursion examples. Each will utilize one given mechanism.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It will be more fun if you'd open a console and try to run code examples on your own. Just don't use this page's console lol.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;I'd also advise preparing Browser Task Manager to keep an eye on changes in memory and CPU consumption. Most of the modern browsers will have one somewhere in settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's start with classics.&lt;/p&gt;
&lt;h3&gt;
  
  
  Call Stack
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recursive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;span class="nf"&gt;recursive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;span class="cm"&gt;/*
stack
stack
stack
...

Uncaught RangeError: Maximum call stack size exceeded
    at recursive (&amp;lt;anonymous&amp;gt;:2:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
    at recursive (&amp;lt;anonymous&amp;gt;:3:1)
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The infinite recursion and its good old buddy Stack Overflow Exception. I bet you've seen a few of these before...&lt;br&gt;
The Stack Overflow Exception is about reaching the max size of the Call Stack. Once we exceed the max size it will blow up with a &lt;code&gt;Maximum call stack size exceeded&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that there are a few &lt;code&gt;console.log&lt;/code&gt; that will never get printed.&lt;br&gt;
Remember that every time we push a new item on the Call Stack, the Engine will immediately switch to it, since we are just pushing new items and never popping. The stack keeps growing until we reach its maximum...&lt;/p&gt;
&lt;h3&gt;
  
  
  Task Queue
&lt;/h3&gt;

&lt;p&gt;Let's try the Task Queue now. This one won't blow up immediately, it will run much longer util the browser propose you kill the page (or wait if you are insistent).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recursiveTask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;task queue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recursiveTask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;span class="nf"&gt;recursiveTask&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;span class="cm"&gt;/*
reachable code 2
task queue
reachable code 1
task queue
reachable code 1
task queue
reachable code 1
task queue
reachable code 1
...
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that both extra &lt;code&gt;console.log&lt;/code&gt; statements are printed. Because all the time we are adding a new task to the Task Queue, we add it for the next iteration and not for immediate execution. Hence all code in this example is processed before starting a new iteration.&lt;br&gt;
Keep an eye on the memory footprint. It will be growing fairly fast together with CPU usage. Under a minute my tab went over 1 Gig of memory.&lt;/p&gt;
&lt;h3&gt;
  
  
  Microtask Queue
&lt;/h3&gt;

&lt;p&gt;Ok, the final one, we'll do the same stuff, infinite recursion, but this time for the microtask queue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;recursiveMicrotask&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;microtask queue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;queueMicrotask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;recursiveMicrotask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reachable code 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unreachable code 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;recursiveMicrotask&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;reachable code 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unreachable code 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="cm"&gt;/*
reachable code 2
microtask queue
reachable code 1
microtask queue
reachable code 1
microtask queue
reachable code 1
microtask queue
reachable code 1
...
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note how tasks from the Task Queue are never executed ("unreachable code"). This is happening because we never end up current Event Loop iteration, we keep adding microtasks to the Microtask Queue and it prevents the iteration from finishing.&lt;br&gt;
If you will leave it for long enough you'll notice that the page (including the address bar) becomes less responsive. Until it completely dies.&lt;br&gt;
Of course, the memory footprint (and CPU usage) will keep growing much faster, since we polluting the Task Queue, but if we will remove both &lt;code&gt;setTimeout&lt;/code&gt; it will reduce the pace of memory footprint growth.&lt;/p&gt;



&lt;p&gt;📝 &lt;em&gt;Side note&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Recursion might be dangerous for infinity simulation. I'd recommend looking into generator functions for such matters. We won't get under the boot of generator functions. At least for now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;But here's a small example of an infinite number generator, which shows the gist of it.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;generateNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;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="k"&gt;while &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="k"&gt;yield&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;numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateNumbers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 1&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="c1"&gt;// 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  That's it.
&lt;/h2&gt;

&lt;p&gt;Of course, everything we looked at is a simplified representation. However, it illustrates in enough detail how the Runtime functions. It is accurate enough to explain the true nature of asynchronicity and code execution sequences in JavaScript. As well as hopefully reveal some "odd" behavior and "unexpected" race conditions.&lt;/p&gt;

&lt;p&gt;JavaScript has an extremely low entrance barrier. And often it is confused with being unstable.&lt;br&gt;
However, some of its behavior is a trade-off of some sort and payment for such a low entrance barrier. Although few bugs are left there for backward compatibility lol...&lt;/p&gt;

&lt;p&gt;If you enjoyed the read, don't forget to check out another related article &lt;a href="https://valerii-udodov.com/posts/web-browser-anatomy" rel="noopener noreferrer"&gt;Web Browser Anatomy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>web</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Clean Event-Driven Architecture</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Thu, 15 Jul 2021 12:13:25 +0000</pubDate>
      <link>https://forem.com/vudodov/clean-event-driven-architecture-lbh</link>
      <guid>https://forem.com/vudodov/clean-event-driven-architecture-lbh</guid>
      <description>&lt;p&gt;In general clean architecture is a pretty bold statement. However, at the same time, it is a hollow and opaque thing to say. &lt;br&gt;
How do you measure the cleanness of the architecture? By the number of components in the system? Nope... Whether it is cloud-first or not? 🤷. By the number of rectangles on the whiteboard? Probably not. Does your source code suppose to look good? It supposes to, but you know... Test coverage? Easiness of writing tests? Extensibility? Is 10-year-old clean architecture is still considered clean nowadays?&lt;/p&gt;

&lt;p&gt;You will find million of clean architectures online. Whenever someone says "clean architecture" both my subconsciousness and google search pulling out the same thing. The book  &lt;a href="https://www.amazon.com.au/dp/0134494164/ref=cm_sw_r_tw_dp_E9M2EVMXTPFVRW229MJ0?_encoding=UTF8&amp;amp;psc=1"&gt;"Clean Architecture: A Craftsman's Guide to Software Structure and Design"&lt;/a&gt; by &lt;a href="https://twitter.com/unclebobmartin"&gt;Uncle Bob Martin&lt;/a&gt;. The main pillar, or to be more precise 5 pillars are &lt;a href="https://en.wikipedia.org/wiki/SOLID"&gt;S.O.L.I.D. principles&lt;/a&gt;. You can even find it on Wikipedia. I mean you know the thing is serious when you can find it there...&lt;br&gt;
Once something gets popular it immediately starts the flame of rage. Like Linux vs Windows, Android vs iOS, C# vs Java, Angular vs React, you name it... &lt;br&gt;
Well S.O.L.I.D is no exception. There are many people in opposition to ole' Uncle Bob. One that (IMHO) outstands is &lt;a href="https://twitter.com/tastapod"&gt;Dan North&lt;/a&gt;. You might have heard of him as one of the originators of Behavior-Driven Development (aka BDD). This guy deserves some credit. Anyway, he came up with his own Clean Architecture &lt;a href="https://dannorth.net/2021/03/16/cupid-the-back-story/"&gt;principles CUPID&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;What I'm saying here is that the principle acronym must form a catchy word! Oh and that any principle is not a silver bullet, even following SOLID principles you might end up with a big ball of mud. But there are a bunch of valuable guidances, following which might reduce the probability of 🦆ucking things up.&lt;/p&gt;

&lt;p&gt;I think of Clean Architecture as a philosophy of some sort. It is not completely about the system today, but about the system today and tomorrow. It is not an arbitrary set of patterns, approaches, or coding technics. Clean Architecture is a product of system thinking that enables system evolution through continuous refactoring without ruining the integrity of the system (in any way you can think of it).&lt;br&gt;
There is no such a thing as a complete code or finished software. There is abandoned or deprecated software. Everything else is a "work in progress".&lt;br&gt;
Unfortunately, we can't forecast the future, but we can make sure that however, we decide to build the application today won't bite us in the future. The design must be sustainable, robust for changes. It should be built with refactoring in mind.&lt;/p&gt;

&lt;p&gt;Of course, a nice diagram is a must too 🙃&lt;/p&gt;
&lt;h2&gt;
  
  
  The Triangle 📐
&lt;/h2&gt;

&lt;p&gt;So here we go, let's start with the diagram...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JiZL68rH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sx3w6mbo8h5r7uw1zutl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JiZL68rH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sx3w6mbo8h5r7uw1zutl.jpg" alt="triangle diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is pretty much 3 triangles, one overlaying another forming three levels. All together it represents a visual representation of the architecture. We will go over all of the levels from the inside out.&lt;/p&gt;
&lt;h3&gt;
  
  
  Inspirations and ideas
&lt;/h3&gt;

&lt;p&gt;At the high level, this architecture represents a mixture of &lt;a href="https://alistair.cockburn.us/hexagonal-architecture/"&gt;hexagonal architecture (aka ports and adaptors)&lt;/a&gt; and its close buddy &lt;a href="https://jeffreypalermo.com/2008/07/the-onion-architecture-part-1/"&gt;onion architecture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here are few things worth highlighting at the start&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coupling.&lt;/strong&gt; The coupling goes inwards and only one level deep. There should be no outward dependencies and hops or bypasses between triangles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Levels.&lt;/strong&gt; Every triangle/level bounds together concepts that have a similar rate of change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sides&lt;/strong&gt; Sides are these named trapezoids. There are three sides on each level. Each side can communicate with its level neighbors. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direction.&lt;/strong&gt; Every side has a strictly defined direction of data flow and communicational purpose.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the first glance, all these concepts might feel a bit convoluted, but by the end of the article, they should make more sense. So without further ado, let's begin.&lt;/p&gt;
&lt;h3&gt;
  
  
  Core Triangle. Level 1. Events. Storage.
&lt;/h3&gt;

&lt;p&gt;In the heart of the architecture are events. It kinda makes sense, given we are talking about event-driven architecture 🙃.&lt;br&gt;
This means that the source of truth for the system state is stored as event streams. In the... wait for it... event store. You might know this pattern as &lt;a href="https://valerii-udodov.com/posts/event-sourcing/different-flavours-of-events/#database"&gt;Event Sourcing&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself.&lt;br&gt;
-- &lt;a href="https://martinfowler.com/eaaDev/EventSourcing.html"&gt;Martin Fowler, Event Sourcing&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Event Sourcing is not new, it has been around for decades. I believe one of the reasons for its gaining popularity is that it fits really well in the Domain-Driven Design. In fact, one of the key elements of Domain-Driven Design is so-called Domain Events. Which will be a one-to-one map to what we will be stored in our "clean" Event Store. &lt;em&gt;More on DDD coming further&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This architecture is not database-centered, following the advice from onion architecture, the database is infrastructural detailed. And as per this diagram, it lays in another dimension.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These events are what we would call &lt;a href="https://valerii-udodov.com/posts/event-sourcing/different-flavours-of-events/#public-and-private-events"&gt;private events&lt;/a&gt;. Events that will never leave boundaries of this application. Or event level 2. Hence is the name private events.&lt;/p&gt;
&lt;h4&gt;
  
  
  Key takeaways
&lt;/h4&gt;

&lt;p&gt;Events are a source of truth for the system. They are hidden from the outside and never leave application boundaries.&lt;/p&gt;
&lt;h3&gt;
  
  
  Middle Triangle. Level 2. The Logic.
&lt;/h3&gt;

&lt;p&gt;This is the place where a lot of things will be going on. Business logic, data mapping, and exposure, and much more...&lt;/p&gt;
&lt;h4&gt;
  
  
  Domain
&lt;/h4&gt;

&lt;p&gt;Let's start with the Domain. I'm a &lt;a href="https://en.wikipedia.org/wiki/Domain-driven_design"&gt;Domain Driven Design&lt;/a&gt; evangelist. Thus here under Domain I imply what Eric Evans implies by Domain in &lt;a href="https://www.amazon.com.au/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=asc_df_0321125215/?tag=googleshopdsk-22&amp;amp;linkCode=df0&amp;amp;hvadid=341793124241&amp;amp;hvpos=&amp;amp;hvnetw=g&amp;amp;hvrand=16188885297378658410&amp;amp;hvpone=&amp;amp;hvptwo=&amp;amp;hvqmt=&amp;amp;hvdev=c&amp;amp;hvdvcmdl=&amp;amp;hvlocint=&amp;amp;hvlocphy=9071391&amp;amp;hvtargid=pla-449269547899&amp;amp;psc=1"&gt;the Blue Bible of Domain-Driven Design&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Domain-Driven Design is an approach to software development that centers the development on programming a domain model that has a rich understanding of the processes and rules of a domain.&lt;br&gt;
-- &lt;a href="https://martinfowler.com/bliki/DomainDrivenDesign.html"&gt;"Domain Driven Design" Martin Fowler&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key thought is -&amp;gt; Without a well-crafted, religiously modeled domain, there's no way we can produce &lt;em&gt;clean&lt;/em&gt; architecture. That's a given. We must understand, not guess, but understand what we are building. Which business problem we are solving. DDD is a great tool for that.&lt;/p&gt;

&lt;p&gt;There's a bit of color-coding going on on the diagram. If you look closely, you can see that domain and commands are in different colors. The color indicates the direction of the data flow in the system. The domain belongs to the writing layer. &lt;br&gt;
Domain encapsulates all invariants and emits events. The role of the Domain is to validate whether the system in its current state can satisfy the incoming request (aka command) or not.&lt;/p&gt;
&lt;h4&gt;
  
  
  Notifications ✉️
&lt;/h4&gt;

&lt;p&gt;Notifications aka public events. These are events that are often constructed from private events. Their only responsibility is to notify the outside world that something important has happened. These events are used nowhere internally, they always go outside. Think of public events as public APIs. Hence the name public events.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Segregation of private and public events is not a new thing. It is quite easy to get into &lt;a href="https://valerii-udodov.com/posts/event-sourcing/different-flavours-of-events/#boundary-trap-"&gt;the boundary trap&lt;/a&gt; that exists between event-sourced application and outside.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Keep in mind, it is not necessary one-to-one mapping with private events. Different strategies might be employed here to reach the expected outcome. Some time ago &lt;a href="https://valerii-udodov.com/posts/event-sourcing/different-flavours-of-events/#public-and-private-events"&gt;I wrote about accumulator pattern&lt;/a&gt;. That helps the system to produce good quality public events, and not broadcast everything that is happening internally.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Events might be as lean as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user-added"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fd4d6b2a-7079-4898-9624-3d2b1558b452"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This event basically notifies the outside world about the fact that the user has been added and provides a piece of minimal viable information for anyone to go and pull any extra required information.&lt;/p&gt;

&lt;p&gt;Or an event might be beefier like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user-added"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fd4d6b2a-7079-4898-9624-3d2b1558b452"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"firstName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"lastName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sex"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"male"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dob"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"12/12/1980"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shoeSize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This event transmits everything the system knows about the new user.&lt;/p&gt;

&lt;p&gt;Which one to use is dependent on how generic and re-usable your public event should be. Do you want to serve extra information on-demand or broadcast all the changes once they occur?&lt;/p&gt;

&lt;h4&gt;
  
  
  Projections
&lt;/h4&gt;

&lt;p&gt;Projections or projected views serve &lt;a href="https://valerii-udodov.com/posts/event-sourcing/different-flavours-of-events/#reads-"&gt;purely read purposes&lt;/a&gt;. They usually represent a &lt;a href="https://en.wikipedia.org/wiki/Denormalization"&gt;denormalized&lt;/a&gt; representation of the data stored in the event store. Denormalization of the data is necessary to tune its shape to a specific query. Therefore provide a cheap and easy way to query the information.&lt;br&gt;
It is a great way to serve general-purpose queries, e.g. "give me a list of all users in the system". Another way of looking at it is as a long-living cache.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Denormalization of data is a sort of anti-DRY principle. Data duplication is natural for this approach. The key driver is to make the read layer as efficient as possible, by reducing time-waste on data construction. The data is not constructed on demand, it is prepared upfront for the easiest digestion. Moreover, the data might be preformatted, to reduce the load from the UI (or any other consuming system).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rsVrl31B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2qcfftq2769s5smskwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rsVrl31B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2qcfftq2769s5smskwk.png" alt="projecting"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Projections are filled during the application runtime. Usually, it depends on whether data have to be strongly consistent or not, the projection process will be either synchronous or asynchronous.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key takeaways
&lt;/h4&gt;

&lt;p&gt;The only way to mutate the system state is through the Domain. A well-crafted Domain is crucial. The domain is responsible for validation and events emission.&lt;br&gt;
Notifications are public events that are targeted outside of the application boundary, keeping external systems up to date with important updates.&lt;br&gt;
Projections are denormalized views of the event store. Projections are filled by projecting private events during the runtime. Data is always shaped in the most comfortable way for query execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Outer Triangle. Level 3. The Exterior.
&lt;/h3&gt;

&lt;p&gt;The outer layer is exposed to the outside world and defines communication contracts. Disregard any particular technology or communication protocol. We are all about abstractions and fancy diagrams here :D&lt;/p&gt;

&lt;p&gt;💡 &lt;em&gt;Key patterns used here are &lt;a href="https://valerii-udodov.com/posts/cqrs/cqrs-querying-via-http/"&gt;Command Query Responsibility Segregation (aka CQRS)&lt;/a&gt; and &lt;a href="https://microservices.io/patterns/data/transactional-outbox.html"&gt;Outbox&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We'll start with a traditional &lt;a href="https://valerii-udodov.com/tags/cqrs/"&gt;CQRS&lt;/a&gt;, that will cover two corresponding sides of the triangle. I'm sure you guessed, but anyway 🥁... commands and queries.&lt;/p&gt;

&lt;h4&gt;
  
  
  Commands
&lt;/h4&gt;

&lt;p&gt;The only way to mutate the system state is by issuing a command. If the client wants to perform an action that supposes to end up with a state update, it has to go through the commanding part of the layer. A command is an intention, not a fact. It might be rejected as well as accepted. If the Domain from Level 2 says "no" to a command it is marked as rejected.&lt;/p&gt;

&lt;h4&gt;
  
  
  Queries
&lt;/h4&gt;

&lt;p&gt;On the other hand, if the client wants to read the state, the inquiry has to go through the querying part of the triangle. The query must ask a well-defined, expected question. The projections (from Level 2) will provide well-formatted sufficient data, that will be propagated all the way to the client.&lt;/p&gt;

&lt;p&gt;🎈 &lt;em&gt;A while ago, I wrote a few articles dedicated to CQRS. &lt;a href="https://valerii-udodov.com/posts/cqrs/cqrs-intro/"&gt;The introduction into CQRS&lt;/a&gt; and &lt;a href="https://valerii-udodov.com/series/cqrs-via-http/"&gt;series that explains how to implement CQRS via HTTP&lt;/a&gt;. So if you are keen, check it out&lt;/em&gt; ;)&lt;/p&gt;

&lt;h4&gt;
  
  
  Outbox 📤
&lt;/h4&gt;

&lt;p&gt;Last, but not least is the Outbox. It consumes so-called public events (aka notifications) and ensures they are dispatched outside with an "at least once" delivery guarantee and respecting the order. This is the main channel for public events to get outside.&lt;br&gt;
The concept of public events and outbox eliminates the boundary trap.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key takeaways
&lt;/h4&gt;

&lt;p&gt;This level defines clean mechanisms for communication with the system. There's only a single way to impact the system state, through Commands. There's the only way to read state, through Queries. And finally, there's the only way to subscribe to the latest updates from the system, through the Outbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom Line
&lt;/h2&gt;

&lt;p&gt;That's how I envision clean event-driven architecture. Each moving part has a well-defined responsibility and direction of data flow. And this way each part can evolve, scale, be replaced, or re-factored independently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6Hnb8kDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/589og0klxknkb2fnwc7b.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6Hnb8kDr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/589og0klxknkb2fnwc7b.jpg" alt="cartoon triangle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope it all makes sense, let me know if it doesn't.&lt;br&gt;
Keen to hear your thoughts and arguments 🧠 💭&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>eventdriven</category>
      <category>eventsourcing</category>
    </item>
    <item>
      <title>Event Sourcing: Events Evolution, Versioning, and Migration</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Sun, 20 Jun 2021 09:32:07 +0000</pubDate>
      <link>https://forem.com/vudodov/event-sourcing-events-evolution-versioning-and-migration-3h0e</link>
      <guid>https://forem.com/vudodov/event-sourcing-events-evolution-versioning-and-migration-3h0e</guid>
      <description>&lt;h2&gt;
  
  
  Before we begin
&lt;/h2&gt;

&lt;p&gt;There are few things worth noting before we kick things off...&lt;/p&gt;

&lt;h3&gt;
  
  
  First thing
&lt;/h3&gt;

&lt;p&gt;Let's clarify what do we mean by the term Event Sourcing. Event Sourcing is an approach for storing and restoring system state in/from a series of strictly ordered events, grouped into streams.. Ultimately it is a way of communication with the database or wherever events are stored.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The fundamental idea of Event Sourcing is that of ensuring every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself.&lt;br&gt;
-- &lt;a href="https://martinfowler.com/eaaDev/EventSourcing.html"&gt;Martin Fowler, Event Sourcing&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;If you'd like to get a more in-depth definition of the term Event and look at different technical contexts that utilize events, check out my previous article &lt;a href="https://valerii-udodov.com/posts/event-sourcing/different-flavours-of-events/"&gt;"Different Flavours of Events"&lt;/a&gt;. Where I go over major event-driven architectures, including Event Sourcing.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Anyhow all the definitions above miss one important aspect. Events are not arbitrary blobs of data or objects. Each event has a name (or we can call it a type) that captures its meaning for the system and often some extra data to enrich the cognitive value of itself. &lt;br&gt;
Another way of looking at events is as a contract. In Event Sourcing, it is a contract between something that uses events and something that stores events. Let's keep it in mind for later.&lt;/p&gt;
&lt;h3&gt;
  
  
  Second thing
&lt;/h3&gt;

&lt;p&gt;Few more terms that often have a vague meaning. Sometimes event versioning and event migration are used as synonyms or substitutional terms to define the actual process of event evolution. However, it is two separate, although dependent problems that need to be tackled independently. Thus I emphasize attention on segregation, versioning goes left, migration goes right.&lt;/p&gt;
&lt;h3&gt;
  
  
  Third thing
&lt;/h3&gt;

&lt;p&gt;You probably heard of it. Event Store is immutable. And it is not completely true. Hold your tomatoes 🍅 for a minute. I'll try to explain what I mean, without going too far in-depth...&lt;br&gt;
The data in the Event Store is immutable or should be treated as immutable only from the business perspective. In other words, during the routine application work, the only allowed actions are new stream creation and new event emission. And any sort of reading actions.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Imagine a banking application where each bank transaction ultimately becomes an event. If the user mistakenly transfers money from one account to another and wants to revert the faulty transaction. The revert action should not eliminate the original (faulty) transaction, instead, the revert transaction should happen, which will compensate for the original faulty action.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;In the end, we will have the original balance and two events, one compensating another.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Out of routine application work, there are a lot of reasons to merge, split, update, remove streams of events, events, or even event data. &lt;br&gt;
The most common reason is optimization. If the data in the Event Store becomes a historical artefact that does not tell anything about the current state of the system and won't be used for audit purposes, archive it and eventually hard delete it. It is just useless.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Evolution
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Evolution is change in the heritable characteristics of biological populations over successive generations. These characteristics are the expressions of genes that are passed on from parent to offspring during reproduction.&lt;br&gt;
-- &lt;a href="https://en.wikipedia.org/wiki/Evolution#:~:text=Evolution%20is%20change%20in%20the,parent%20to%20offspring%20during%20reproduction."&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's talk about evolution in the context of Event Sourcing. There is no such thing as a finished application. Systems do evolve with time. Most of the time it is either business requirements evolution or bugs that stimulate this process. Both of these occasions don't require an extra introduction. However, they will unavoidably impact events.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TPJHdwIO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a47m5ty4t8b81j5eiyi1.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TPJHdwIO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a47m5ty4t8b81j5eiyi1.jpeg" alt="evolution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are two ways how event can evolve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the event might become a new version of itself &lt;/li&gt;
&lt;li&gt;or become a new event (or set of new events). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What determines the direction of the change? When does an event evolve into a new version and when it evolves into a new event? &lt;br&gt;
The event will evolve into a new incarnation (version) of itself when evolved requirement does not change the event's meaning, but rather schema. Hence a new version of an event must be convertible from the original one (old version). Therefore the name/type, which represents the essence of the event must not change.&lt;/p&gt;

&lt;p&gt;If an event's meaning changed and one-to-one conversion is impossible, that's a sign to introduce a new event (or events) that carries new meaning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A new version of an event must be convertible from the old version of the event. If not, it is not a new version of the event but rather a new event.&lt;br&gt;
-- &lt;a href="https://leanpub.com/esversioning"&gt;"Versioning in an Event Sourced System" Greg Young&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can use this as a rule of thumb: if you are struggling with a conversion of the old version of an event into a new one, most likely you are dealing with the new event, not with a new version.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's look at the example below.&lt;br&gt;
Imagine there's a comment system where users can delete comments. Every time user deletes a comment new event is emitted&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"comment-deleted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"comment-id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"user-id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Time passed and new requirement arrives. "All users must specify the reason for the deletion". Sounds reasonable, so from now on the event should look as follows...&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"comment-deleted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"comment-id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"user-id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I didn't like it"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This is a simple example of event evolution forced by requirement change. The meaning of the event did not change. However, the payload did.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Breaking Change
&lt;/h3&gt;

&lt;p&gt;We mentioned that event also represents a contract. The contract between the event store and the system/application. &lt;br&gt;
If we look at events through this lense the biggest driver to introduce a new version would be a breaking change in the existing event schema. A breaking change is any non-backward compatible change. In other words, something will break if we change the event's schema this way. We'll get back to this topic in more detail later.&lt;/p&gt;

&lt;p&gt;In real life, events do not always evolve from one version to another by expansion. Sometimes they shrink.&lt;br&gt;
When a new version of an event loses some of the payload without gaining, it is not a breaking change. Hence we don't really need a new version of an event, we can just ignore the data that we don't need.&lt;/p&gt;

&lt;p&gt;I use the following table as a decision navigator.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Do we need a new version?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;all data exists on the old version and required in the new version&lt;/td&gt;
&lt;td&gt;should be copied&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;data exists on the old version, but not all of it required in the new version&lt;/td&gt;
&lt;td&gt;ignore obsolete data&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a new version has some new fields, but they are nullable&lt;/td&gt;
&lt;td&gt;set null&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a new version has some new fields, but they are not nullable&lt;/td&gt;
&lt;td&gt;conversion required&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;data exists on the old version and on the new, but the schema of data changed (e.g. type changed or field name)&lt;/td&gt;
&lt;td&gt;conversion required&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Long story short. Unless it is a breaking change, there's no necessity for a new version of the event. Unless you want to capture all schema permutations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where's the catch? 🎣
&lt;/h3&gt;

&lt;p&gt;With the new event, it is pretty straightforward. Follow the regular routine, how you'd introduce a new event on any other occasion.&lt;/p&gt;

&lt;p&gt;With the new version, it is a bit more tricky. Once you introduced a new version, now you have two events that carry different data but have the same meaning. Moreover you probably already accumulated some old events in your event store. Looks ambiguous, isn't it?&lt;br&gt;
The original reason behind the introduction of a new version of the event is a new/evolved requirement (or bug). The same reason makes the old version of the event obsolete. &lt;/p&gt;

&lt;p&gt;What does it mean from the system perspective? The system should only see a single version of the event, the latest one.&lt;br&gt;
From now on, the new event version is the only legit representation. Any old version should be simply invisible. It's like it never existed before.&lt;/p&gt;

&lt;p&gt;Getting back to one of our initial claims: the event store is immutable. And it is not a problem when we introduce a new event or deprecate an old event. But what should happen when we introduce a new version of the event?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's try to visualize what we've just said.&lt;br&gt;
Imagine there's an event stream. Where different color represents different events. It has been going on from 2:00 o'clock. Somewhere between 3:00 and 4:00 we introduced a new version of the light blueish event (v2).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mO1G1aE---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usuhugv6rkbzznvpxyji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mO1G1aE---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/usuhugv6rkbzznvpxyji.png" alt="expectation vs reality"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On the left is reality, what we will end up within the Event Store. On the right is what our system should expect. Notice the difference? On the right-side, all events are of the latest version.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Distillation
&lt;/h3&gt;

&lt;p&gt;Event evolution is a natural process of any active event-sourced application.&lt;br&gt;
The event might evolve into a new version of itself or into a new event. You can determine the direction by validating whether you can easily convert an old event into a new one. If you do, you are dealing with a new version, if not a new event...&lt;br&gt;
The main driver behind the event's version-to-version evolution is a breaking change in the event's payload schema. Use a table from the above to determine whether you are dealing with the one.&lt;br&gt;
Last, but not least, the system must "see" only a single version of the event, the latest one.&lt;/p&gt;

&lt;p&gt;Further down we will focus on the version-to-version evolution and possible ways of dealing with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Event Versioning
&lt;/h2&gt;

&lt;p&gt;First and foremost let's find a good data structure to describe the event version, given what we know so far about it.&lt;br&gt;
Let's go over key aspects of versioning.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;old version must be convertible to the new one;&lt;/li&gt;
&lt;li&gt;we don't have any limits on the number of versions, our system might well have any arbitrary number of versions for any particular event;&lt;/li&gt;
&lt;li&gt;given our system "forgets" about old versions we can only operate with the current version and future version (the one we are introducing) at any given point in time;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What if we will represent every version of an event as a node. And the ability to convert the old version into the new one as a directional connection. Boom and we are getting a &lt;em&gt;Linked List&lt;/em&gt;.&lt;br&gt;
Let's try to visualize it really quick.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QZjUsrC6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8re2xmnli1hz8wg8yf2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QZjUsrC6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8re2xmnli1hz8wg8yf2h.png" alt="linked list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looks very nice and elegant. Responsibility boundaries are well defined. Any given version will know how to convert itself to the next one and only the next one. And the tail will always represent the latest version. The one that our system is actually interested in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conversion/Migration
&lt;/h2&gt;

&lt;p&gt;Given we came up with a linked list to describe the relationship between versions, the conversion from any given version to the next one and ultimately to the latest becomes very trivial. All we need is traversal from the current version to the tail. And tail will always be the last available version.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SGIlwjun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xbn7qv64sfvvybqhdux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SGIlwjun--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4xbn7qv64sfvvybqhdux.png" alt="traversal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  When?
&lt;/h3&gt;

&lt;p&gt;Seems like we have a good way forward. We have a way to define a version, we have a good understanding of how to get from any given version to the last one. So when should we do it? And the answer is "it depends..."&lt;/p&gt;

&lt;p&gt;It depends on whether you can afford to have a down-time, on the average active lifetime of arbitrary stream in your system, and your snapshotting strategy.&lt;/p&gt;

&lt;p&gt;I have only my own experience at my disposal so I'll use it to define the median case.&lt;/p&gt;

&lt;h4&gt;
  
  
  In-store migration
&lt;/h4&gt;

&lt;p&gt;This is when you update data in the event store itself. I don't like this approach as it kinda violates the integrity of the data. You are mutating the Holy Grail of the Event Sourcing... Events.&lt;/p&gt;

&lt;p&gt;Additionally performing something like &lt;a href="https://martinfowler.com/bliki/BlueGreenDeployment.html"&gt;blue-green deployment&lt;/a&gt; or &lt;a href="https://martinfowler.com/bliki/CanaryRelease.html"&gt;canary deployment&lt;/a&gt; without downtime is possible, but might appear painful :). Keep in mind you will have to compensate accumulated delta between releases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Out of the store migration
&lt;/h4&gt;

&lt;p&gt;More common and in my opinion more reasonable way of dealing with it is covert on demand. This means we will leave the event store untouched, instead, our state reconstitution process will be responsible for event conversion.&lt;/p&gt;

&lt;p&gt;Let's get look at the reality vs. expectation example, but now with conversion in-between.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cpAq9haP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xf5aj6e3c2cb3ym9m7nn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cpAq9haP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xf5aj6e3c2cb3ym9m7nn.png" alt="out of store"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is particularly useful when the active stream lifetime is not very long and you know that ultimately every stream will be either archived or serve only for audit purposes. It means that eventually your Event Store will be constituted of streams with predominantly new versions of events. And those with old events will get less and less usage.&lt;/p&gt;

&lt;p&gt;On the other hand, if your streams have a fairly long active lifetime you probably will employ snapshotting strategy at some point in time. This will reduce the usage of old events as they will be processed during snapshot construction. However, it will require us to re-build the snapshot whenever we introduce a new version of the event as it will impact the snapshot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom Line _______
&lt;/h2&gt;

&lt;p&gt;Applications evolve and unavoidably impact the shape of the data in the data storage. If you are using event sourcing, it means your shape of events will be evolving making some events in the event store stale.&lt;/p&gt;

&lt;p&gt;Generally speaking, an event has two main responsibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signalize about a change that has happened &lt;/li&gt;
&lt;li&gt;and carry information to enrich the value of the signal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If evolution changes what the event should signalize about it is a new event, if it changes underlying payload schema it is a new version of the event.&lt;/p&gt;

&lt;p&gt;Event versioning is nicely fitted into the Linked List data structure.&lt;/p&gt;

&lt;p&gt;The system uses only the latest versions of events. And to facilitate it we have two ways of dealing with old events. The in-store and out-of-store migration/conversion. I'm personally in favor of the last one, but presumably, there might be better cases for the first one.&lt;/p&gt;

&lt;p&gt;Keep in mind that there are other strategies for dealing with event versioning, such as double push, etc. I think they are rather more applicable to asynchronous services than to event-sourced systems. But don't take my word for it, there's no silver bullet in the software engineering ;)&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>eventdriven</category>
      <category>eventsourcing</category>
    </item>
    <item>
      <title>Server-side Redux. Part III. The Code.</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Mon, 14 Jun 2021 05:46:01 +0000</pubDate>
      <link>https://forem.com/vudodov/server-side-redux-part-iii-the-code-2183</link>
      <guid>https://forem.com/vudodov/server-side-redux-part-iii-the-code-2183</guid>
      <description>&lt;h2&gt;
  
  
  The State Management Goes Wild
&lt;/h2&gt;

&lt;p&gt;his is the final article of the series where we explore Redux and its boundaries. In the previous articles, we &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-1-the-redux/"&gt;first dived into the main principles of the Redux&lt;/a&gt;, then we &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-2-the-design/"&gt;tried to move things around&lt;/a&gt; and conceptually move Redux from one side to another.&lt;/p&gt;

&lt;p&gt;This article is all about hands-on experience, and by the end of it, we will have a working application that will follow the design we settled before.&lt;/p&gt;

&lt;p&gt;Enough talking let's get down to business.&lt;/p&gt;

&lt;p&gt;Feel free to pull &lt;a href="https://github.com/vudodov/tic-tac-toe-redux-example"&gt;complete application code from Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Given
&lt;/h2&gt;

&lt;p&gt;Let's quickly go over the design. The main connection points are Redux and React, they will talk via WebSocket. React components will dispatch actions, those will be processed by Redux, which in its order will push the updated state back to the React.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gyl4X4TJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qk3rspggismdo8kon6hu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gyl4X4TJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qk3rspggismdo8kon6hu.png" alt="Application Design"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Client-side
&lt;/h3&gt;

&lt;p&gt;Well, you know it, it will be React. We will try to consume &lt;a href="https://create-react-app.dev/docs/getting-started/"&gt;create-react-script&lt;/a&gt; to quickly set up everything we need and don't waste time configuring Webpack, Babel and other 1001 libraries we need to make those two work together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-side
&lt;/h3&gt;

&lt;p&gt;Since Redux is a JavaScript library, it makes sense to take a JavaScript-based backend environment. You got it again, it will be NodeJS.&lt;/p&gt;




&lt;p&gt;ℹ️ &lt;em&gt;At the time I'm writing this article NodeJS &lt;a href="https://nodejs.org/docs/latest-v13.x/api/esm.html#esm_enabling"&gt;just included experimental support for ECMAScript modules&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We will configure it globally for the whole back-end application with setting &lt;code&gt;"type": "module"&lt;/code&gt; in the root of the server-side &lt;code&gt;package.json&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This feature is available starting from version &lt;strong&gt;13&lt;/strong&gt;, so try to run &lt;code&gt;node -v&lt;/code&gt; in your terminal, and if it is lower make sure to update it.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;We spoke about the mythical immutability by convention, mythical because it is not a real thing 🦄🙃. Therefore we will use &lt;a href="https://immutable-js.github.io/immutable-js/"&gt;immutable.js&lt;/a&gt; to keep our state truly immutable.&lt;/p&gt;

&lt;h3&gt;
  
  
  In between
&lt;/h3&gt;

&lt;p&gt;We will be using WebSocket as a communication protocol between client and server. Probably the most popular library for that matter is &lt;a href="https://socket.io/"&gt;socket.io&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We figured out all the main tech choices. Let's look at how &lt;code&gt;dependencies&lt;/code&gt; sections from both &lt;code&gt;package.json&lt;/code&gt; files will look alike&lt;/p&gt;

&lt;p&gt;back-end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"immutable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.0.0-rc.12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"redux"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.0.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"socket.io"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.3.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;front-end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"dependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.13.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.13.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.9.x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"socket.io-client"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.3.0"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Plan
&lt;/h2&gt;

&lt;p&gt;We will kick things off by implementing a Tic Tac Toe game in pure React. It will be based on &lt;a href="https://reactjs.org/tutorial/tutorial.html"&gt;the React tutorial&lt;/a&gt;. The first iteration won't support a multi-browser multiplayer. Two players will be able to play, but in the same browser window, since the state will be local for the browser window.&lt;/p&gt;

&lt;p&gt;After we will add back-end with Redux Store and move logic from the front-end components to back-end reducing functions. With all the logic gone, we will do a bit of housekeeping and make sure that all components are stateless/pure.&lt;/p&gt;

&lt;p&gt;And finally, we will connect front-end and back-end with socket.io and enjoy a multi-browser multiplayer 🎮.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step I. Pure React Implementation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TLDR;&lt;/strong&gt; You can find complete code for this step &lt;a href="https://github.com/vudodov/tic-tac-toe-redux-example/commit/d6575c1b5e876e600b3206d4efc748dca33aafe9"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This example is based on the &lt;a href="https://reactjs.org/tutorial/tutorial.html#completing-the-game"&gt;react intro tutorial&lt;/a&gt;, so if you'd like to go through the step-by-step process, feel free to jump there. We'll go through the most important bits here.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The whole application is assembled from three main components, which are &lt;code&gt;Game&lt;/code&gt;, &lt;code&gt;Board&lt;/code&gt;, and &lt;code&gt;Square&lt;/code&gt;. As you can imagine the &lt;code&gt;Game&lt;/code&gt; contains one &lt;code&gt;Board&lt;/code&gt; and the &lt;code&gt;Board&lt;/code&gt; contains nine &lt;code&gt;Square&lt;/code&gt;'s. The state floats from the root &lt;code&gt;Game&lt;/code&gt; component through the &lt;code&gt;Board&lt;/code&gt; props down to the &lt;code&gt;Square&lt;/code&gt;'s props.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cY5maCMc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6e7q9qny00anhsksg6s0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cY5maCMc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6e7q9qny00anhsksg6s0.png" alt="Pure React Design"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each &lt;code&gt;Square&lt;/code&gt; is a &lt;a href="https://reactjs.org/docs/react-api.html"&gt;pure component&lt;/a&gt;, it knows how to render itself based on the incoming props/data. Concept is very similar to &lt;a href="https://valerii-udodov.com/server-side-redux-the-redux/"&gt;pure functions&lt;/a&gt;. As a matter of fact, some components are pure functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\front-end\index.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"square"&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&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="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Board&lt;/code&gt; is also pure component, it knows how to render squares and pass state down there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\front-end\index.js&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Board&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;renderSquare&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Square&lt;/span&gt; 
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;squares&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="si"&gt;}&lt;/span&gt; 
        &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onClick&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="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;span class="nx"&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;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"board-row"&lt;/span&gt;&lt;span class="p"&gt;&amp;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;renderSquare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          /* ... render 8 more squares */
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally the state orchestrator, the &lt;code&gt;Game&lt;/code&gt; component. It holds the state, it calculates the winner, it defines what will happen, when user clicks on the square.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\front-end\index.js&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Game&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fill&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="p"&gt;}],&lt;/span&gt;
      &lt;span class="na"&gt;stepNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;xIsNext&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="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;jumpTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* jump to step */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* reset */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;handleClick&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="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* handle click on the square */&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cm"&gt;/* check if we have a winner and update the history */&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"game"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"game-board"&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;Board&lt;/span&gt;
            &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;squares&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleClick&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="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step II. Adding Server-Side and Redux
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TLDR;&lt;/strong&gt; You can find complete code for this step &lt;a href="https://github.com/vudodov/tic-tac-toe-redux-example/commit/bad78149aec1efbae5f98ba72ec0ac4230bc2750"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, I guess this is it, the moment we've all been waiting for. The moment when we will marry the Redux and NodeJS app 🙌.&lt;/p&gt;

&lt;h3&gt;
  
  
  The State 🌳
&lt;/h3&gt;

&lt;p&gt;We will follow the Redux best practices and first define how the state tree will look alike. We will base it on the state model which we used in the previous step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uXExbZgr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iimeq6lrli33k4p8hvpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uXExbZgr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iimeq6lrli33k4p8hvpi.png" alt="State Tree"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the first level, we have  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the turn indicator "is X next?", which determines whether it is X or O turn;
&lt;/li&gt;
&lt;li&gt;the step #, which is essentially a move counter, showing current step
&lt;/li&gt;
&lt;li&gt;the winner, true if the winner was identified
&lt;/li&gt;
&lt;li&gt;the history, snapshot of Squares on each move&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each node in the History represents a collection of Squares, each Square has an index and one of three states "_", "X" and "O".&lt;/p&gt;

&lt;p&gt;Let's try to model how initial state might look like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;INITIAL_STATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
        &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fill&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="p"&gt;}],&lt;/span&gt;
      &lt;span class="na"&gt;stepNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;xIsNext&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://dev.toposts/server-side-redux/server-side-redux-1-the-redux/"&gt;In the first article&lt;/a&gt;, we spoke about immutability and particularly about &lt;a href="https://immutable-js.github.io/immutable-js/"&gt;immutable.js&lt;/a&gt;. This is the place we are going to utilize it. We will mostly use &lt;a href="https://immutable-js.github.io/immutable-js/docs/#/List"&gt;List&lt;/a&gt; and &lt;a href="https://immutable-js.github.io/immutable-js/docs/#/Map"&gt;Map&lt;/a&gt; objects, for the sake of this example. Now let's compare to how the state initialization will look like after we applied immutable.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;INITIAL_STATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; 
    &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;List&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="kc"&gt;null&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="kc"&gt;null&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="kc"&gt;null&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="kc"&gt;null&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="p"&gt;})]),&lt;/span&gt;
  &lt;span class="na"&gt;stepNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;xIsNext&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;winner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A bit more code, yet it is a fair trade, taking into account that all operations will automatically produce a new immutable instance of the state in the most efficient manner.&lt;br&gt;&lt;br&gt;
Something like &lt;code&gt;const newState = state.set('winner', true);&lt;/code&gt; will produce new state object. How cool is that?&lt;/p&gt;
&lt;h3&gt;
  
  
  Actions
&lt;/h3&gt;

&lt;p&gt;Now that we know the shape of the state, we can define allowed operations. And no surprises here either. We will re-use the same operations we used in the front-end and transfer them into actions. Hence there will be three main actions  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PERFORM_MOVE&lt;/code&gt; to perform a move, action will carry a box index that move was made for
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;JUMP_TO_STEP&lt;/code&gt; to enable time-traveling, this action will carry step number to which the user wants to jump to
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RESET&lt;/code&gt; resets the whole game progress to the initial empty board&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Reducers
&lt;/h3&gt;

&lt;p&gt;We have actions, we have a state...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sb45f9hO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwjw1x479bn885qhvsat.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sb45f9hO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rwjw1x479bn885qhvsat.jpg" alt="PPAP"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we need to connect them.&lt;br&gt;&lt;br&gt;
Before we start it is worth mentioning that Reducer is responsible for setting the initial state, we will use the initial state we defined before. And just set it if nothing was passed (this is handled for us)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\back-end\src\reducer.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;INITIAL_STATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;history&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; 
    &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;List&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="kc"&gt;null&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="kc"&gt;null&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="kc"&gt;null&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="kc"&gt;null&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="p"&gt;})]),&lt;/span&gt;
  &lt;span class="na"&gt;stepNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;xIsNext&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;winner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;INITIAL_STATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PERFORM_MOVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="cm"&gt;/* todo */&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JUMP_TO_STEP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="cm"&gt;/* todo */&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="cm"&gt;/* todo */&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;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;Let's go over reducing functions one by one.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PREFORM_MOVE&lt;/code&gt; On every move we will first check if the move is legit, meaning that we might already have a winner and the game is over or the user tries to hit filled box. If any of these happens we will return the same state with no modifications.&lt;br&gt;&lt;br&gt;
Checks are done, the move is legit, we perform actual move depending on whether it should be "X" or "O". After we made a move we need to check whether it was a winning move or not.&lt;br&gt;&lt;br&gt;
And finally update state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\back-end\src\reducer.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;performMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;boxIndex&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;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;last&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;squares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;squares&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;winner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;winner&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;boxIndex&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;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;squares&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;boxIndex&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xIsNext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;winner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;calculateWinner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;squares&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;state&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;squares&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stepNumber&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xIsNext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xIsNext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;winner&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;JUMP_TO_STEP&lt;/code&gt; To perform a time-travel we need to reverse the history to the step we want to move to and update current step number with a new value. And of course return new state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\back-end\src\reducer.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;jumpToStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;step&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;state&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stepNumber&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xIsNext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;RESET&lt;/code&gt; Reset is pretty much like a &lt;code&gt;JUMP_TO_STEP&lt;/code&gt;, with only difference that we are jumping back to the very first step. After we are done, we return a new state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\back-end\src\reducer.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reset&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;history&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;take&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="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;stepNumber&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;xIsNext&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winner&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we constructed all necessary reducing functions, we can put together the reducer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\back-end\src\reducer.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;INITIAL_STATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PERFORM_MOVE&lt;/span&gt;&lt;span class="dl"&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;performMove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;boxIndex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JUMP_TO_STEP&lt;/span&gt;&lt;span class="dl"&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;jumpToStep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESET&lt;/span&gt;&lt;span class="dl"&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;reset&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="k"&gt;return&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;h3&gt;
  
  
  Create Store
&lt;/h3&gt;

&lt;p&gt;We have everything we need and it is time to create a new redux store based on the freshly created reducer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\back-end\index.js&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;redux&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;redux&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;server&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;./src/server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;reducer&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;./src/reducer.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;redux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step III. Connecting client and server
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TLDR;&lt;/strong&gt; You can find complete code for this step &lt;a href="https://github.com/vudodov/tic-tac-toe-redux-example/commit/69c5f5aee180caef448183fad4c6f7d6d59f6f6f"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is the last step. It is mostly about connecting two points, client-server and deduplicate the logic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection
&lt;/h3&gt;

&lt;p&gt;First, we will configure the connection on both ends. Before performing any configuration let's figure out &lt;a href="https://socket.io/docs/#Sending-and-getting-data-acknowledgements"&gt;how does socket.io works&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The first-class citizens in the socket.io library are events. You can emit or subscribe to event on both sides.&lt;/p&gt;

&lt;p&gt;Which kind of events we need? I think we already have an answer to this question. Let's get back to our design diagram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FRpJjwrT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xl6v4f0cp7x4juvc2jdu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FRpJjwrT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xl6v4f0cp7x4juvc2jdu.png" alt="Application Design"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to push &lt;em&gt;state&lt;/em&gt; from the server to clients and &lt;em&gt;actions&lt;/em&gt; from the clients to the server. Translating it to socket.io language we need to have a &lt;code&gt;state-changed&lt;/code&gt; event that we will emit on the server and subscribe to on the client. And we need to have an &lt;code&gt;action&lt;/code&gt; event that we will emit on the client and subscribe to it on the server.&lt;/p&gt;

&lt;p&gt;So far so good, the only bit missing is the connection. We need to pass the current state to any new socket connection to our server. Luckily this is built-in functionality. We have a &lt;code&gt;connection&lt;/code&gt; event that will be triggered every time a new connection appears. So all we need is subscribe to it.&lt;/p&gt;

&lt;p&gt;This should do for our design and data transition needs.&lt;/p&gt;

&lt;p&gt;Now let's do actual configuration. We'll start with the server. First, we will subscribe to any new connection, after connection happens we immediately emit a &lt;code&gt;state-change&lt;/code&gt; event on that socket to transfer the latest state from the Redux Store. Then we will also subscribe to an &lt;code&gt;action&lt;/code&gt; event from the same socket and once an event will arrive we will dispatch the whole object into the Redux Store. That'll provide a complete setup for the new socket connection.&lt;/p&gt;

&lt;p&gt;To maintain the rest of the connections up to date we will subscribe to the Redux Store changes, using Listener callback. Every time the change will appear we will broadcast a &lt;code&gt;state-change&lt;/code&gt; event to all connected sockets&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ..\back-end\src\server.js&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Let the Game begin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;attach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8090&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;state-change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toJS&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New Connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;state-change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toJS&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
      &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;action&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="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;Moving to the client-side, first thing we need to set up a way to receive fresh state. We will subscribe to the &lt;code&gt;state-changed&lt;/code&gt; event for that matter and pass received state execute the &lt;code&gt;ReactDOM.render(&amp;lt;Game gameState={newState} /&amp;gt;, ...);&lt;/code&gt;. Don't worry, calling &lt;a href="https://reactjs.org/docs/react-dom.html#render"&gt;ReactDOM.render()&lt;/a&gt; multiple times, absolutely fine from the performance perspective, it will have the same performance implication as calling &lt;code&gt;setState&lt;/code&gt; inside the component.&lt;/p&gt;

&lt;p&gt;Finally, we define the &lt;code&gt;dispatch&lt;/code&gt; callback which takes &lt;code&gt;action&lt;/code&gt; object as a parameter and emit an &lt;code&gt;action&lt;/code&gt; event through the socket connection.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\front-end\index.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:8090&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;state-change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Game&lt;/span&gt; 
      &lt;span class="na"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;action&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;gameState&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, that'll be our communication framework. Now we need to pull the right string in the right moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cleanup
&lt;/h3&gt;

&lt;p&gt;The logic moved to the back-end reducing functions. This fact allows us to make our front-end completely stateless and pure. All our react components are now only data-containers. The state itself and the interaction rules (reducing functions) are stored on the back-end.&lt;/p&gt;

&lt;p&gt;If we look back on the data-transition diagram we can notice that in reality &lt;code&gt;Square&lt;/code&gt; and &lt;code&gt;Board&lt;/code&gt; components were already pure, now it is just a matter of making the root component, &lt;code&gt;Game&lt;/code&gt; pure as well.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qfEHOxSa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7iwvl5xef9ko437kum4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qfEHOxSa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7iwvl5xef9ko437kum4.png" alt="Redux Design"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a bit of refactoring the code will look as following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// .\front-end\index.js&lt;/span&gt;

&lt;span class="cm"&gt;/* Square and Board were not changed */&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Game&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PureComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;jumpTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;)&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JUMP_TO_STEP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RESET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;boxIndex&lt;/span&gt;&lt;span class="p"&gt;)&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PERFORM_MOVE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;boxIndex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boxIndex&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stepNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;xIsNext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;winner&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameState&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;stepNumber&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;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;winner&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Winner: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;winner&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Next player: &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="nx"&gt;xIsNext&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;O&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;moves&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;step&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;move&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="cm"&gt;/* time travelling */&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"game"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"game-board"&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;Board&lt;/span&gt;
            &lt;span class="na"&gt;squares&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;squares&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleClick&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="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"game-info"&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;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reset&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;Reset the Game&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ol&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;moves&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ol&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;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's all folks
&lt;/h2&gt;

&lt;p&gt;Please find the complete code example in &lt;a href="https://github.com/vudodov/tic-tac-toe-redux-example"&gt;my GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In a course of three articles, we have proposed a hypothesis, that Redux might be used as a state management tool on the back-end and distribute the state across multiple front-ends, we've built a design prototype to facilitate the experiment. And finally, we've built a proof of concept tic-tac-toe application that proved our design prototype hence proved that the hypothesis was correct.&lt;/p&gt;

&lt;p&gt;There are multiple ways to optimize and improve this code example, we mentioned a few.&lt;/p&gt;

&lt;p&gt;You are more than welcome to express your thoughts in a form of comments or commits.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Server-side Redux. Part II. The Design.</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Thu, 03 Jun 2021 05:02:05 +0000</pubDate>
      <link>https://forem.com/vudodov/server-side-redux-part-ii-the-design-4c59</link>
      <guid>https://forem.com/vudodov/server-side-redux-part-ii-the-design-4c59</guid>
      <description>&lt;h2&gt;
  
  
  The State Management Goes Wild
&lt;/h2&gt;

&lt;p&gt;This is the second article of the series where we will try to find out if there’s a place for Redux on the other side of the fence.&lt;/p&gt;

&lt;p&gt;Even though this series is base on the assumption that you are more or less familiar with what is Redux, don’t worry if not, as we covered all necessary concepts in &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-1-the-redux/"&gt;the previous article&lt;/a&gt;. Take your time and make yourself comfortable with Redux.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-1-the-redux/"&gt;In the previous article,&lt;/a&gt; we witnessed, how Redux can drag responsibility of being a source of truth for the state, manage its distribution and help multiple independent components stay in sync. A good example would be a scenario that forced Facebook to come up with something like Flux in the first place: &lt;a href="https://youtu.be/nYkdrAPrdcw?t=753"&gt;a large facebook message view&lt;/a&gt;, where you can have three independent components depend on whether you read a message or not. Main view, compact view in the right corner and icon-counters on the top.&lt;/p&gt;

&lt;p&gt;With the help of Redux, the state distribution in this sort of application will look as following&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xTpzg5Kk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gflvb6p6ddn8lunwrvcn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xTpzg5Kk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gflvb6p6ddn8lunwrvcn.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Front-end Redux state distribution&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving things around
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Whys
&lt;/h3&gt;

&lt;p&gt;Now, finally, we are reaching the important point of this series, where we will answer the question: &lt;em&gt;why would the one possibly want to use Redux somewhere away from the front-end?&lt;/em&gt; 🤯&lt;br&gt;&lt;br&gt;
Pretty much for the same reason why you would use it in the front-end... Single source of truth for the state, its distribution, and centralized management. Even though the idea might make sense, the scenario is not very clear yet.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Scenario
&lt;/h4&gt;

&lt;p&gt;Let's get back to the Facebook case study first. The root cause of the problem there was the data synchronization between components without a direct connection. The more dependent nodes appeared, the more convoluted distribution tree became. Complexity was growing exponentially.&lt;/p&gt;

&lt;p&gt;Imagine replacing components with front-ends. Front-ends that are simultaneously working and interacting with the same state. It might be the same client-side application in different browser windows as well as absolutely different front-end applications. Main criterion: they need to interact with the same state.&lt;/p&gt;

&lt;p&gt;The following diagram represents a conceptual state distribution graph for such an application. The left side and right side are separate React front-ends with a Redux-equipped server in the middle. One of the right-side front-end components performs a change in the state (green circle), change (action) delivered to the server where it is dispatched to the Redux Store. The reducing function performs all necessary state changes and finally, the new state got delivered back to the front-ends. In this case, we are using the top-level component distribution model in both front-ends to deliver the state to the dependent components (yellow circles).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eodmkBi8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zvdbw9n4e7425wrkbbo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eodmkBi8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zvdbw9n4e7425wrkbbo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Back-end Redux state distribution&lt;/p&gt;

&lt;h3&gt;
  
  
  The Hows
&lt;/h3&gt;

&lt;p&gt;So far so good, it makes sense and everything seems to logically fit. However, the vague point here is state exchange.&lt;br&gt;&lt;br&gt;
In a regular React application, everything is happening inside the browser in the same JavaScript runtime, allowing real-time bidirectional communication between Redux and React. Moving Redux to the back-end introduces physical segregation between the React root component and Redux Store. The black dashed line on the diagram above illustrates the physical segregation of those two. To get Redux to work as we expect it to, we must make the communication as seamless as it is in its native habitat.&lt;/p&gt;

&lt;h4&gt;
  
  
  The Challenge
&lt;/h4&gt;

&lt;p&gt;The first thing that comes to my mind when I look at the border between the front-end and back-end is HTTP. But will it do the job here? To answer this question let's first figure out what problem we are trying to solve.&lt;/p&gt;

&lt;p&gt;We need to establish real-time, bidirectional communication between the Redux Store and root node of each and every React front-end. It means that both the client and server should have the ability to push information equally.&lt;/p&gt;

&lt;h4&gt;
  
  
  HTTP vs WebSocket
&lt;/h4&gt;

&lt;p&gt;This topic on its own deserves a separate article. To save some time and not lose the focus, I'll say that HTTP out of the box supports server-push approach with Server-Sent Events (SSE) and client JS has &lt;a href="https://www.w3.org/TR/2015/REC-eventsource-20150203/#the-eventsource-interface"&gt;built-in support for it&lt;/a&gt;, thanks to HTML5. On top of it, HTTP/2 can utilize a single TCP connection to deliver multiple messages in both directions, making it a full-duplex, bidirectional connection.&lt;/p&gt;

&lt;p&gt;However moving forward I chose WebSocket as a protocol that was specifically built for this sort of communication, it does not bring unnecessary data overhead, that HTTP brings (e.g. Headers). Additionally, WebSocket is a more generally known way of solving this sort of task.&lt;/p&gt;

&lt;p&gt;Now all what is left is to connect right dots with right lines.&lt;/p&gt;

&lt;h4&gt;
  
  
  Client
&lt;/h4&gt;

&lt;p&gt;As we discussed, we will take the root-node data distribution approach. This means that the root node will receive the whole state and propagate it all the way down through the &lt;code&gt;props&lt;/code&gt;. It should happen every time the "push" event arrives from the server.&lt;/p&gt;

&lt;p&gt;Now we also need to initiate state updates from the client. We decided on the delivery mechanism, but we did not decide on what we will deliver. Actually Redux already solved this problem for us. &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-1-the-redux/"&gt;As we know&lt;/a&gt; Redux uses actions to operate on its state tree. There's no reason for us to change that, even though we increased the distance slightly. All we need to do is to define a &lt;code&gt;dispatch(action)&lt;/code&gt; callback which will push actions back to the server. So that any component in the tree can push actions to the server (remember the green circle).&lt;/p&gt;

&lt;h4&gt;
  
  
  Server
&lt;/h4&gt;

&lt;p&gt;To consume "push" events on the client we first need to produce them. Every time a new state is produced by the reducing function, the server must initiate a "push" event. And finally, we need to handle incoming actions from the client.&lt;/p&gt;

&lt;p&gt;To push state we can use Redux listener callbacks, which will be executed on every attempt to change state, disregards whether it was changed or not. At any point in time, we can request a new state and utilize WebSocket to deliver it to the client.&lt;/p&gt;

&lt;p&gt;Process actions is dead simple. Once we receive an action, we directly dispatch it with Redux Store.&lt;/p&gt;

&lt;h4&gt;
  
  
  Final Design
&lt;/h4&gt;

&lt;p&gt;This is it. We have everything on its places, we have a way to deliver actions to the Redux Store as well as a subscription mechanism to update all front-ends on every state change.&lt;/p&gt;

&lt;p&gt;The final design looks as following&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4QF5ZpsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b07hlqsrzbpmjvgxosay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4QF5ZpsM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b07hlqsrzbpmjvgxosay.png" alt="Final Design"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What's next?
&lt;/h3&gt;

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

&lt;p&gt;You might think that sending state every time to all the clients is not the most efficient approach. And you are right. But is it a problem? Wether it is or not, it really depends how big is your state tree. If it is reasonably small, I would not bother. If it is big enough and you are worried about some clients' latency, you can decrease the data noise, e.g. by sending only state delta.&lt;/p&gt;

&lt;h4&gt;
  
  
  Redux everywhere
&lt;/h4&gt;

&lt;p&gt;As another possible design iteration, nothing stops you from having Redux on the front-end if you feel like it is required, this will change your state distribution diagram to something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4U73hvB---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ckagpb557fyec0ycvdig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4U73hvB---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ckagpb557fyec0ycvdig.png" alt="Back-end state distribution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The state source of truth still stays on the server, but client-server communication happening between server-side Redux and client-side Redux and now client-side state propagation lays on the shoulders of the client-side Redux.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uVSsA1k8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zp66mvezpq36hoh5xbyx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uVSsA1k8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zp66mvezpq36hoh5xbyx.jpg" alt="Unicorn"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redux on the backend is not a magical unicorn, not just a theory and we will prove it in practice.&lt;/p&gt;

&lt;p&gt;This kind of architecture is not for the "daily use", but it is not just for fun either. It will work very well in most of the real-time applications, particularly for things like chat apps or online games.&lt;/p&gt;

&lt;p&gt;It absolutely agnostic to the front-end complexity and can work well with simple state-waterfall applications as well as complex front-ends with Redux as a state manager.&lt;/p&gt;

&lt;p&gt;Anyhow, it is time to get hands dirty and &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-3-the-code/"&gt;try discussed architecture in practice&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Server-side Redux. Part I. The Redux.</title>
      <dc:creator>Valerii Udodov</dc:creator>
      <pubDate>Thu, 13 May 2021 09:58:26 +0000</pubDate>
      <link>https://forem.com/vudodov/server-side-redux-part-i-the-redux-296i</link>
      <guid>https://forem.com/vudodov/server-side-redux-part-i-the-redux-296i</guid>
      <description>&lt;h2&gt;
  
  
  The State Management Goes Wild
&lt;/h2&gt;

&lt;p&gt;This is the first article of the series where we will try to find out if there's a place for the Redux on the other side of the fence.&lt;/p&gt;

&lt;p&gt;Even though this series is base on the assumption that you are more or less familiar with the Redux, don't worry if not, as we will go over necessary concepts first. And this is what this article is about...&lt;/p&gt;

&lt;p&gt;Once we are confident with the Redux as a React state manager, &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-2-the-design/" rel="noopener noreferrer"&gt;we will be exploring&lt;/a&gt; how we can use it as a back-end state management and state distribution tool and gradually build the conceptual design. Last, but not least we will get our hands dirty and &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-3-the-code/" rel="noopener noreferrer"&gt;build application with Redux on the back-end&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you are super-comfortable with Redux, feel free to start &lt;a href="https://valerii-udodov.com/posts/server-side-redux/server-side-redux-2-the-design/" rel="noopener noreferrer"&gt;with the desert&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Very brief History
&lt;/h2&gt;

&lt;p&gt;Redux appeared as a proof of concept during preparation for the React Europe conference, back in 2015.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I was trying to make a proof of concept of Flux where I could change the logic. And it would let me time travel. And it would let me reapply the future actions on the code change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/dan_abramov" rel="noopener noreferrer"&gt;Dan Abramov&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Very soon Redux got huge popularity in the front-end community, it is simple, easy to follow library for the state management. Redux makes a lot of complicated tasks trivial.&lt;/p&gt;

&lt;h2&gt;
  
  
  State Management
&lt;/h2&gt;

&lt;p&gt;To understand what Redux can bring to the table we'll start by looking at what pure React can offer first.&lt;/p&gt;

&lt;p&gt;React doesn't come with the Redux out of the box, and there's a reason for that. Most of the time you probably won't need it. There is a React way of managing state distribution and state dependency. In React you can propagate state up to the top-level components and make it in charge of distribution and dependency management. The state flow is single-directional and easy to manage.&lt;/p&gt;

&lt;p&gt;Think of the React application as of simple water-filter. Where the state is water, each layer is a component. We pure the water in the bottle, water passes through each layer consistently, each layer takes whatever it has to take and letting the water flow to the next 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%2Fuploads%2Farticles%2Fm8ghz0oje1m5pb3f5z8n.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%2Fm8ghz0oje1m5pb3f5z8n.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope the idea is clear, but why and when do we need Redux?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You'll know when you need Flux. If you aren't sure if you need it, you don't need it.&lt;/p&gt;

&lt;p&gt;-- Pete Hunt (one of the first React contributors)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can apply the same rule to the Redux. &lt;em&gt;If you aren't sure if you need it, you don't need it.&lt;/em&gt;&lt;br&gt;&lt;br&gt;
Once you have a lot of data moving here and there and top-level React component state is not enough to distribute it. It is 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvlqfkwt6n0fofcj98nko.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%2Fvlqfkwt6n0fofcj98nko.png" alt="React vs Redux"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Redux allows you to move out the "state source of truth" from the top-level component into a separate object. And the only way to change the current state is to interact with this object. This object called &lt;a href="https://redux.js.org/api/store" rel="noopener noreferrer"&gt;Store&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Immutability
&lt;/h2&gt;

&lt;p&gt;Understanding immutability is very important, for proceeding with the Redux. Because in Redux state is immutable 🌳.&lt;br&gt;&lt;br&gt;
The idea behind the immutable data is simple, you cannot modify it. Like natural numbers. &lt;code&gt;2&lt;/code&gt; is a natural number and whatever you do, it won't change &lt;code&gt;2&lt;/code&gt;. You can operate on it and, let's say, add &lt;code&gt;3&lt;/code&gt; to it, but the result will be another natural number, &lt;code&gt;5&lt;/code&gt;. &lt;code&gt;5&lt;/code&gt; is another natural number.&lt;/p&gt;

&lt;p&gt;Why immutable data is good? Because you can pass it around and not worry it will be changed in a way you don't expect it to. It becomes even handier in the distributed multi-threaded environment, but that's another discussion.&lt;/p&gt;
&lt;h3&gt;
  
  
  Immutable by convention
&lt;/h3&gt;

&lt;p&gt;Immutable data is a key aspect of any Redux-based architecture. Even though it is a key aspect, there's no real enforcement, it is so-called immutability by convention. I think immutability by convention is not a thing… If an object can be mutated, it will be mutated, just a matter of time… I highly recommend stepping away from the immutability by convention once the data-state tracing becomes uncomfortable.&lt;/p&gt;

&lt;p&gt;JavaScript has some data structures provided out of the box. There're an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze" rel="noopener noreferrer"&gt;Object.freeze()&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const" rel="noopener noreferrer"&gt;const&lt;/a&gt; which kinda allow you to have some immutability. Yet using them is not very efficient from the memory perspective, because every operation will require you to copy your data from one place to another. Quite expensive, taking into account the fact that every copy will require extra memory allocation, copying and garbage collection.&lt;/p&gt;

&lt;p&gt;To keep things error-prone we'll need something that will enforce immutability and manage memory efficiently. The &lt;a href="https://immutable-js.github.io/immutable-js/" rel="noopener noreferrer"&gt;immutable.js&lt;/a&gt; does exactly that. It is a library with a collection of immutable data structures. Immutable JS uses &lt;a href="https://hypirion.com/musings/understanding-persistent-vector-pt-1" rel="noopener noreferrer"&gt;persistent vectors&lt;/a&gt; to perform insertions, merges, etc. It removes necessity in copying and caching of the data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pure functions
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Mathematical functions
&lt;/h3&gt;

&lt;p&gt;The immutable data is a key aspect of the Redux design and we need to respect it whether we use it in a conventional manner or by enforcement.&lt;/p&gt;

&lt;p&gt;But how do we deal with immutable data in a way that we can still benefit from it?&lt;br&gt;&lt;br&gt;
Let's get back to the natural numbers example, we agreed that natural numbers are immutable, and we tried to add &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt;, which resulted in &lt;code&gt;5&lt;/code&gt;. This can be written like &lt;code&gt;2 + 3 = 5&lt;/code&gt;. To make it more generic we can describe it as the &lt;a href="https://en.wikipedia.org/wiki/Function_(mathematics)" rel="noopener noreferrer"&gt;mathematical function&lt;/a&gt;, like this &lt;code&gt;f(a, b) = a + b&lt;/code&gt;. It is predictable, it does not introduce any side-effects, for &lt;code&gt;2&lt;/code&gt; and &lt;code&gt;3&lt;/code&gt; it will always return &lt;code&gt;5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pure functions are mathematical functions. And pure functions work very well with immutable data, there's even a whole programming paradigm that takes those two as its foundational platform, you might know it as &lt;a href="https://en.wikipedia.org/wiki/Functional_programming" rel="noopener noreferrer"&gt;functional programming&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%2F5uhsu7texhwso1d65lvg.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%2F5uhsu7texhwso1d65lvg.jpg" alt="different functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We spoke about the state and its immutable nature in the Redux. We also spoke about the Store and how it secures a state from any unauthorised impact. And finally, we found that pure functions are a very convenient way to operate on immutable data, which allows keeping transparency and predictability in place.&lt;/p&gt;
&lt;h3&gt;
  
  
  Reducing functions
&lt;/h3&gt;

&lt;p&gt;The only way Redux Store allows to operate on its state 🌳is with &lt;a href="https://redux.js.org/glossary#action" rel="noopener noreferrer"&gt;actions&lt;/a&gt;. Those are special "instruction" objects, very similar to what &lt;a href="https://valerii-udodov.com/posts/cqrs/cqrs-commanding-via-http/" rel="noopener noreferrer"&gt;Commands are in CQRS&lt;/a&gt; or Events in Event Sourcing. They define an action/operation that intended to be applied to the state and carrying a necessary payload. Add an item to the basket is an action where the item you want to add is a payload.&lt;/p&gt;

&lt;p&gt;Redux uses a special type of &lt;a href="https://en.wikipedia.org/wiki/Fold_(higher-order_function)" rel="noopener noreferrer"&gt;high-order functions&lt;/a&gt; to process actions, the reducing function. The reducing functions &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce" rel="noopener noreferrer"&gt;is not a new concept in the JavaScript&lt;/a&gt;, the array.reduce(reducerCallback, initialValue) function reduces an array to a single value. It uses a &lt;em&gt;special user-defined reducer callback&lt;/em&gt; which is executed recursively. &lt;br&gt;&lt;br&gt;
&lt;code&gt;(accumulator, currentValue) =&amp;gt; nextAccumulator&lt;/code&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%2Fw17x083yb3k1f7bn8qak.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%2Fw17x083yb3k1f7bn8qak.png" alt="State Reducing"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, Redux Store will use a &lt;em&gt;special user-defined &lt;/em&gt;&lt;a href="https://redux.js.org/glossary#reducer" rel="noopener noreferrer"&gt;&lt;em&gt;reducer callback&lt;/em&gt;&lt;/a&gt; which will be executed synchronously when an action will be dispatched. As you might guess, reducer must be a pure function. It takes a state and an action and calculates the next state.&lt;br&gt;&lt;br&gt;
&lt;code&gt;(state, action) =&amp;gt; nextState&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Interception and Subscription
&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%2F1pma2dl8dbrernbokqtw.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%2F1pma2dl8dbrernbokqtw.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
Redux uses Middleware pattern to provide integration points before and after an action is dispatched. You can stack multiple middleware functions. You are in charge of whether the execution chain continues or not. You can control it with the &lt;code&gt;next(action)&lt;/code&gt; function.&lt;br&gt;&lt;br&gt;
Another integration point is Redux Listeners, which located closer to reducer callback than middleware. Listener functions are executed one by one right after reducer. Listeners don't have any control over execution flow.&lt;/p&gt;
&lt;h2&gt;
  
  
  Keep in mind, it is simple
&lt;/h2&gt;

&lt;p&gt;Redux doesn't force you, it empowers you by providing a framework. You can have multiple stores, mutate state, create side-effects in your reducing functions and finally, you don't have to use it as a state source of truth at all.&lt;/p&gt;

&lt;p&gt;Redux is not rocket science 🚀, it is just a &lt;a href="https://github.com/facebook/flux/tree/master/examples/flux-concepts#flow-of-data" rel="noopener noreferrer"&gt;Flux pattern&lt;/a&gt; implementation and if we strip all the error checks, comments extension points from the &lt;a href="https://github.com/reduxjs/redux/blob/master/src/createStore.ts" rel="noopener noreferrer"&gt;createStore.ts&lt;/a&gt; it will fit into 20-30 lines of JavaScript code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;listeners&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;unsubscribe&lt;/span&gt;&lt;span class="p"&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;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;splice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&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="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;reducer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;listeners&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listener&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;listener&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getState&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;Few more things are happening in the Redux and it slightly differs from the Flux, however, we won't go in too deep. We covered just enough to move forward to the next chapter and design the use-case for the Redux on the backend.&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>javascript</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
