<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arpy Vanyan</title>
    <description>The latest articles on DEV Community by Arpy Vanyan (@_arpy).</description>
    <link>https://dev.to/_arpy</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%2F53792%2F75db98e0-7f50-4be7-b5d9-01f341eccbf0.png</url>
      <title>DEV Community: Arpy Vanyan</title>
      <link>https://dev.to/_arpy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_arpy"/>
    <language>en</language>
    <item>
      <title>Being a lead sometimes means you work all day, but no single line of code is committed. Does it mean nothing valuable was done? Well, no... Sometimes, the invisible work we do is much more valuable for the future than you'd think.</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Mon, 14 Apr 2025 14:25:11 +0000</pubDate>
      <link>https://dev.to/_arpy/being-a-lead-sometimes-means-you-work-all-day-but-no-single-line-of-code-is-committed-does-it-4emo</link>
      <guid>https://dev.to/_arpy/being-a-lead-sometimes-means-you-work-all-day-but-no-single-line-of-code-is-committed-does-it-4emo</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5" class="crayons-story__hidden-navigation-link"&gt;The Invisible Work of a Frontend Lead (And Why It Matters)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/_arpy" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53792%2F75db98e0-7f50-4be7-b5d9-01f341eccbf0.png" alt="_arpy profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/_arpy" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Arpy Vanyan
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Arpy Vanyan
                
              
              &lt;div id="story-author-preview-content-2397345" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/_arpy" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53792%2F75db98e0-7f50-4be7-b5d9-01f341eccbf0.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Arpy Vanyan&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 10 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5" id="article-link-2397345"&gt;
          The Invisible Work of a Frontend Lead (And Why It Matters)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/frontend"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;frontend&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/leadership"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;leadership&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mentorship"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mentorship&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/agile"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;agile&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;4&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>frontend</category>
      <category>leadership</category>
      <category>mentorship</category>
      <category>agile</category>
    </item>
    <item>
      <title>The Invisible Work of a Frontend Lead (And Why It Matters)</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Thu, 10 Apr 2025 13:09:06 +0000</pubDate>
      <link>https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5</link>
      <guid>https://dev.to/_arpy/the-invisible-work-of-a-frontend-lead-and-why-it-matters-5d5</guid>
      <description>&lt;p&gt;When I first stepped into a frontend lead role, I thought my biggest contributions would come from writing cleaner code, refactoring smart components, and shaping the architecture.&lt;/p&gt;

&lt;p&gt;And sure, those things mattered.&lt;/p&gt;

&lt;p&gt;But over time, I realized something unexpected: the work that made the biggest difference wasn't visible in Git history. It wasn't in the commits, or even on the JIRA board.&lt;/p&gt;

&lt;p&gt;It was in the quiet things, the moments between coding, that kept the team moving forward.&lt;/p&gt;

&lt;p&gt;This is about that work. The kind that doesn't make it into changelogs but still changes everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 &lt;strong&gt;TL;DR&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Being a frontend lead isn't just about writing better code; it's about &lt;strong&gt;enabling others&lt;/strong&gt; to write better code, too.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Much of the &lt;strong&gt;real work&lt;/strong&gt; happens outside of pull requests: unblocking teammates, guiding architecture decisions, mentoring quietly, and translating between product and dev.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Documentation, process, and internal advocacy often feel thankless, but they compound over time and &lt;strong&gt;keep the team moving&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You become the &lt;strong&gt;calm in the chaos&lt;/strong&gt;: protecting focus, providing clarity, and making sure people have what they need to do their best work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It doesn't always look like leadership from the outside, but the &lt;strong&gt;impact is real&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  You're not just leading code, you're leading clarity
&lt;/h2&gt;

&lt;p&gt;A big part of the job is just helping the team know &lt;strong&gt;what the hell is going on&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Product wants X. Design gives you a Figma file full of "magic." Developers are deep in PRs. Everyone's moving but not always in the &lt;em&gt;same direction&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;🗣️ As a lead, you're the &lt;strong&gt;translator&lt;/strong&gt;. You speak product, design, and dev, and you help each side make sense to the others.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You break vague desires into actionable work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You catch misaligned assumptions before they burn.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You &lt;strong&gt;fill in the gaps&lt;/strong&gt; that everyone assumed someone else would fill in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You explain &lt;em&gt;"why we're doing this now"&lt;/em&gt; five different ways to five different people.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some days, this feels like being the only one who read the manual. Other days, it's more like writing the manual while the game is already in progress.&lt;/p&gt;

&lt;p&gt;📝 &lt;em&gt;Invisible task: maintaining the team wiki or architecture docs that everyone forgets until they're absolutely lost.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture isn't just diagrams, it's social
&lt;/h2&gt;

&lt;p&gt;Yes, architecture is components and state management and API boundaries.&lt;/p&gt;

&lt;p&gt;But it's also culture.&lt;/p&gt;

&lt;p&gt;It's in how people write code when no one's watching. It's in whether developers follow the "good" pattern or the one that got them through the ticket fastest. It's in how much mental resistance a new dev feels when opening a feature folder.&lt;/p&gt;

&lt;p&gt;✍🏻 As a lead, you're nudging the architecture constantly. Not with sweeping rewrites, but with comments like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;"Let's move this to a hook"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"This feels like it belongs in a feature module"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"We should wrap this in our reusable API pattern"&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture decisions are easy. &lt;strong&gt;Getting people to consistently use them is the real work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgflip.com%2F9qd4n9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgflip.com%2F9qd4n9.jpg" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Mentorship hides in the gaps
&lt;/h2&gt;

&lt;p&gt;It's not always about talks or pair-programming (though those help). It's in the extra context you add to a code review comment. The time you take to rewrite a confusing ticket. That moment you decide not to fix something yourself so a junior dev can learn how.&lt;/p&gt;

&lt;p&gt;Sometimes, mentoring means &lt;strong&gt;stepping back&lt;/strong&gt;, even when it would be faster to just do it yourself.&lt;/p&gt;

&lt;p&gt;Other times, it's listening to someone rant about a weird bug just long enough for them to &lt;em&gt;solve it out loud&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;🧠 &lt;em&gt;Invisible work is being the person who makes the team smarter without making them feel smaller.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Documentation is boring until it saves the day
&lt;/h2&gt;

&lt;p&gt;I've spent hours writing internal docs that no one noticed... until the one time someone onboards, or breaks a deployment, or asks "where's the config for that?"&lt;/p&gt;

&lt;p&gt;📖 Maintaining a &lt;em&gt;team wiki&lt;/em&gt; or system overview isn't a perk, but it's the kind of work that &lt;strong&gt;pays off over and over again&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A shared architecture overview&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deployment steps with edge cases included&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clear standards for component structure, file naming, API access&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clear steps of branching and commit messages and git flow&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing it down gives the team fewer reasons to block you and gives you more time to lead, not babysit.&lt;/p&gt;

&lt;p&gt;📚 &lt;em&gt;Bonus points if you actually remember to update the docs after a refactor.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  You become a developer advocate inside your team
&lt;/h2&gt;

&lt;p&gt;👩🏻‍💼 One of the most &lt;em&gt;valuable&lt;/em&gt; (and underestimated) parts of being a frontend lead is &lt;strong&gt;standing up for developer experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That might mean pushing back on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UX decisions that ignore real-world behavior&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Product deadlines that leave no time for testing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Platform or tooling decisions made without frontend in the room&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also means saying: &lt;em&gt;"We need time to clean this up."&lt;/em&gt; Or &lt;em&gt;"This quick fix will become tech debt in a sprint."&lt;/em&gt; Or just: &lt;em&gt;"Let me explain how this impacts DX."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;💬 You end up being the voice that helps non-devs understand why dev things matter and helps devs feel heard.&lt;/p&gt;




&lt;h2&gt;
  
  
  The process isn't sexy, but it scales
&lt;/h2&gt;

&lt;p&gt;When you help shape how the team runs (standups, reviews, deployments, testing), you're not just &lt;em&gt;"keeping things organized."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;🧘🏻‍♀️ You're &lt;strong&gt;reducing cognitive load&lt;/strong&gt;. You're avoiding bugs before they happen. You're letting people &lt;strong&gt;focus&lt;/strong&gt; on their work instead of wondering what's expected.&lt;/p&gt;

&lt;p&gt;Some of the best improvements I've seen came from small process tweaks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Async check-ins instead of daily calls&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using staging deployments for QA&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making Storybook part of the release flow&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automating changelogs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating a checklist for Definition of Done&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🛠️ &lt;em&gt;Process isn't about control. It's about flow.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Defending focus is part of the job
&lt;/h2&gt;

&lt;p&gt;🔔 &lt;strong&gt;Focus is fragile&lt;/strong&gt;. Slack pings, vague priorities, "quick requests" - it all adds up.&lt;/p&gt;

&lt;p&gt;Sometimes, your job as a lead is simply protecting space for others to work. Saying &lt;strong&gt;"not now"&lt;/strong&gt; so someone can finish what they're building. Blocking distractions. Asking the product team to hold off while the devs finish the current release.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsn9fbq5jxdu4ewb7ey55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsn9fbq5jxdu4ewb7ey55.png" alt="When you're trying to block distractions for the team and get pulled into three meetings" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🏅 You might not write a line of code that day, but if your team gets to ship without interruption, &lt;strong&gt;you've done your job&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts: the best work doesn't always have a commit hash
&lt;/h2&gt;

&lt;p&gt;A lot of frontend leadership isn't about bold architecture changes or fancy patterns.&lt;/p&gt;

&lt;p&gt;It's about the dozens of quiet decisions that help the team ship better software.&lt;/p&gt;

&lt;p&gt;It's nudging, guiding, unblocking, translating, listening, writing, and occasionally... just staying out of the way.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This work is &lt;strong&gt;invisible&lt;/strong&gt;. But its impact is &lt;strong&gt;everywhere&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;💬 &lt;em&gt;What kind of "invisible work" do you find yourself doing as a lead?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>leadership</category>
      <category>mentorship</category>
      <category>agile</category>
    </item>
    <item>
      <title>React Performance: Small Fixes That Made a Big Impact</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Mon, 07 Apr 2025 10:49:15 +0000</pubDate>
      <link>https://dev.to/_arpy/react-performance-small-fixes-that-made-a-big-impact-2o30</link>
      <guid>https://dev.to/_arpy/react-performance-small-fixes-that-made-a-big-impact-2o30</guid>
      <description>&lt;p&gt;When you're building the first version of a React app, performance usually isn’t your top concern. Things feel snappy. It’s just React, right?&lt;/p&gt;

&lt;p&gt;Then, the app grows. New features get added, state becomes more complex, components nest deeper, and before you know it, something that used to be smooth starts to feel... sluggish.&lt;/p&gt;

&lt;p&gt;I’ve been there. Below are some of the most practical performance lessons I’ve learned while scaling React apps—things I wish I’d done earlier, and fixes that made a noticeable difference without overcomplicating the codebase.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ Measure Before You Optimize
&lt;/h2&gt;

&lt;p&gt;It sounds obvious, but it’s often skipped. I used to reach for &lt;code&gt;useMemo&lt;/code&gt; or &lt;code&gt;React.memo&lt;/code&gt; way too early without knowing what was actually slowing things down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What actually helps:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;React DevTools Profiler&lt;/strong&gt; – Spot unnecessary re-renders.&lt;/p&gt;

&lt;p&gt;📦 &lt;strong&gt;why-did-you-render&lt;/strong&gt; – Understand what's rendering and why.&lt;/p&gt;

&lt;p&gt;⚙️ &lt;strong&gt;Lighthouse&lt;/strong&gt; – Useful for performance audits and slow paints.&lt;/p&gt;

&lt;p&gt;🧪 &lt;strong&gt;Real user feedback&lt;/strong&gt; – Often the best indicator something’s off.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Takeaway&lt;/strong&gt;: Don’t guess. Measure first, then optimize what’s actually slow.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2️⃣ Too Many Renders? Check Your State
&lt;/h2&gt;

&lt;p&gt;One of the biggest performance drains I’ve seen is over-rendering caused by lifted state. It’s tempting to keep things high up in the tree “just in case” other components need access, but that can end up re-rendering the entire subtree.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What helped:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep state as close to where it’s used as possible.&lt;/li&gt;
&lt;li&gt;Use derived state with memoization.&lt;/li&gt;
&lt;li&gt;Apply &lt;code&gt;React.memo&lt;/code&gt; only where it helps (after profiling).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Takeaway&lt;/strong&gt;: Overlifting state leads to over-rendering. Start local, move it up only if needed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3️⃣ &lt;code&gt;useEffect&lt;/code&gt; Isn't Your Friend (Most of the Time)
&lt;/h2&gt;

&lt;p&gt;In early projects, I used &lt;code&gt;useEffect&lt;/code&gt; for everything: fetching data, syncing state, firing side effects. It worked, but it led to complexity and subtle bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I changed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stopped using effects for things that could be derived or handled declaratively.&lt;/li&gt;
&lt;li&gt;Moved server state logic to State Manager.&lt;/li&gt;
&lt;li&gt;Created custom hooks to isolate repeated logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Takeaway&lt;/strong&gt;: Reach for useEffect only when there's no better alternative.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4️⃣ Initial Load Times Matter More Than You Think
&lt;/h2&gt;

&lt;p&gt;If your app feels slow to open, users notice. I’ve seen apps load the entire dashboard even when the user just needs the login screen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What helped:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✂️ Code splitting routes using dynamic &lt;code&gt;import()&lt;/code&gt; and &lt;code&gt;React.lazy&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;🧹 Tree shaking unused code and libraries.&lt;/li&gt;
&lt;li&gt;⚛️ Breaking up giant components into smaller, focused ones.&lt;/li&gt;
&lt;li&gt;📊 Using tools like &lt;code&gt;webpack-bundle-analyzer&lt;/code&gt; to see what’s in your bundle.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Takeaway&lt;/strong&gt;: Don’t serve the whole app upfront. Load what the user needs, when they need it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5️⃣ Lists Are a Performance Trap
&lt;/h2&gt;

&lt;p&gt;Large lists rendered the wrong way will quietly wreck performance. One project had a simple dropdown with 1000+ items rendered without virtualization—it completely froze the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What helped:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used &lt;code&gt;react-window&lt;/code&gt; to only render visible list items.&lt;/li&gt;
&lt;li&gt;Avoided anonymous functions inside &lt;code&gt;.map()&lt;/code&gt; calls.&lt;/li&gt;
&lt;li&gt;Used unique keys (not index) to avoid re-rendering issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Takeaway&lt;/strong&gt;: Lists need extra care. Optimize them early.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6️⃣ Real Debug Example: The Mystery Re-Render
&lt;/h2&gt;

&lt;p&gt;The same seemingly innocent Dropdown component was triggering re-renders across the whole page. It was tied to a parent’s state via props, and every dropdown change re-rendered multiple unrelated charts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memoized the dropdown to isolate re-renders.&lt;/li&gt;
&lt;li&gt;Split state into smaller, targeted slices.&lt;/li&gt;
&lt;li&gt;Removed lifted state chain and used shared redux state.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Result&lt;/strong&gt;: Charts became responsive again, and interaction time dropped by ~200ms.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;React performance isn’t about overusing &lt;code&gt;useMemo&lt;/code&gt; or blindly adding caching. It’s about understanding how your app renders, keeping things simple, and avoiding unnecessary work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Start small. Measure. Fix what matters first.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Often, it’s basic architectural decisions—where state lives, how components are composed, how data flows—that have the biggest impact over time.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>performance</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I've learned things the hard way so you don't have to 👩🏻‍💻</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Mon, 10 Mar 2025 10:59:24 +0000</pubDate>
      <link>https://dev.to/_arpy/ive-learned-things-the-hard-way-so-you-dont-have-to-3ceg</link>
      <guid>https://dev.to/_arpy/ive-learned-things-the-hard-way-so-you-dont-have-to-3ceg</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/_arpy" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53792%2F75db98e0-7f50-4be7-b5d9-01f341eccbf0.png" alt="_arpy"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/_arpy/things-i-wish-i-knew-before-scaling-a-frontend-codebase-obp" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Things I Wish I Knew Before Scaling a Frontend Codebase 🚀&lt;/h2&gt;
      &lt;h3&gt;Arpy Vanyan ・ Mar 7&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#scaling&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>scaling</category>
      <category>react</category>
    </item>
    <item>
      <title>Things I Wish I Knew Before Scaling a Frontend Codebase 🚀</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Fri, 07 Mar 2025 13:54:59 +0000</pubDate>
      <link>https://dev.to/_arpy/things-i-wish-i-knew-before-scaling-a-frontend-codebase-obp</link>
      <guid>https://dev.to/_arpy/things-i-wish-i-knew-before-scaling-a-frontend-codebase-obp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Growing Pains of a Frontend Codebase
&lt;/h2&gt;

&lt;p&gt;Every frontend project starts small and simple—a few components, some state management, maybe a couple of API calls. Fast forward a year, and suddenly:&lt;/p&gt;

&lt;p&gt;❌ Code reviews take forever&lt;br&gt;
❌ Making a small UI change breaks unexpected parts of the app&lt;br&gt;
❌ Deployments become stressful, debugging is a nightmare&lt;br&gt;
❌ Onboarding new developers takes weeks&lt;/p&gt;

&lt;p&gt;I’ve been through multiple frontend projects that hit these exact roadblocks. Looking back, there are things I wish I had done earlier to avoid the mess.&lt;/p&gt;

&lt;p&gt;In this article, I’ll share 10 key lessons I’ve learned about scaling frontend codebases the hard way.&lt;/p&gt;




&lt;h2&gt;
  
  
  1️⃣ Keep the Codebase Modular From Day One
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; Everything was dumped into a single components/ folder with zero structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Organize by feature, not type (e.g., &lt;code&gt;features/dashboard/&lt;/code&gt; instead of &lt;code&gt;components/&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; A modular codebase scales better, and refactoring later is painful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Use feature-based architecture&lt;br&gt;
📌 Keep components small &amp;amp; reusable&lt;br&gt;
📌 Separate UI, state, and logic early&lt;/p&gt;




&lt;h2&gt;
  
  
  2️⃣ Choose the Right State Management Approach Early
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; We started with a custom state manager, which worked until it didn’t.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Use the simplest state management solution that fits your needs (Context API, Zustand, Redux, or React Query).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; Overcomplicated state management is a tech debt time bomb.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Keep local state inside components whenever possible&lt;br&gt;
📌 Use &lt;strong&gt;React Query&lt;/strong&gt; for server state instead of Redux&lt;br&gt;
📌 Avoid prop drilling hell with &lt;strong&gt;Context&lt;/strong&gt; or &lt;strong&gt;Zustand&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3️⃣ CI/CD &amp;amp; Automated Deployments Are Not an Afterthought
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; Manual deployments led to human errors and broken releases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Automate the entire process (testing, builds, deployments) using CI/CD tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; If you don’t automate early, you’ll regret it when your team grows.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Set up NX or Turborepo for efficient builds&lt;br&gt;
📌 Use feature flags to safely deploy unfinished features&lt;br&gt;
📌 Run automated tests before merging&lt;/p&gt;




&lt;h2&gt;
  
  
  4️⃣ Performance Optimization Is Important
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; We didn’t care about performance until users started complaining.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Optimize early by monitoring bundle sizes and network requests, note any unnecessary re-renders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; Performance bottlenecks are much harder to fix later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Use lazy loading &amp;amp; code splitting (React’s Suspense)&lt;br&gt;
📌 Optimize bundle size with tree shaking&lt;br&gt;
📌 Minimize re-renders with React.memo &amp;amp; useCallback&lt;/p&gt;




&lt;h2&gt;
  
  
  5️⃣ Proper Testing Saves You From Deployment Nightmares
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; We relied on manual testing instead of automating tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; A solid test strategy includes unit, integration, and E2E tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; The best time to start writing tests was yesterday.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Write unit tests for critical business logic&lt;br&gt;
📌 Use React Testing Library for component tests&lt;br&gt;
📌 Add Cypress or Playwright for E2E tests&lt;/p&gt;




&lt;h2&gt;
  
  
  6️⃣ Avoid Over-Engineering: Simple Is Better
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; We overcomplicated everything with abstractions and unnecessary layers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Build for today’s needs, but design with tomorrow in mind.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; Complexity grows fast; keep it as simple as possible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Don't abstract too early—wait until patterns emerge&lt;br&gt;
📌 Avoid unnecessary custom hooks if built-in hooks work fine&lt;br&gt;
📌 Keep dependencies minimal to reduce tech debt&lt;/p&gt;




&lt;h2&gt;
  
  
  7️⃣ Documentation Is a Lifesaver
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; The codebase relied on tribal knowledge, making onboarding painful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Keep lightweight, useful documentation (not just API specs).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; Well-documented projects are easier to scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Use Storybook for UI documentation&lt;br&gt;
📌 Maintain a simple README with architecture decisions&lt;br&gt;
📌 Write code comments where necessary (but don’t overdo it)&lt;/p&gt;




&lt;h2&gt;
  
  
  8️⃣ TypeScript Will Save You From a Lot of Debugging
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; Started with plain JS, then struggled with undefined errors everywhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Adopted TypeScript to reduce runtime errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; Types catch issues before they become bugs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Use TypeScript from day one&lt;br&gt;
📌 Type function props and API responses properly&lt;br&gt;
📌 Keep types clean (avoid any at all costs!)&lt;/p&gt;




&lt;h2&gt;
  
  
  9️⃣ API Communication Should Be Standardized
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The mistake:&lt;/strong&gt; Different parts of the app handled API requests inconsistently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The fix:&lt;/strong&gt; Created a unified API service with consistent response types and error handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Takeaway:&lt;/strong&gt; Standardized API calls reduce bugs &amp;amp; improve maintainability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Best Practice:&lt;/strong&gt;&lt;br&gt;
📌 Use &lt;strong&gt;React Query&lt;/strong&gt; or SWR for fetching&lt;br&gt;
📌 Centralize API logic in a single module&lt;br&gt;
📌 Use error boundaries to catch failures gracefully&lt;/p&gt;




&lt;h2&gt;
  
  
  🔟 Scaling a Frontend Isn’t Just About Code; It’s About Process
&lt;/h2&gt;

&lt;p&gt;At the end of the day, a scalable frontend isn’t just good architecture—it’s also about workflow, automation, and team collaboration.&lt;/p&gt;

&lt;p&gt;If I could go back in time, I’d tell myself:&lt;br&gt;
✅ Plan for modularization early&lt;br&gt;
✅ Keep things simple&lt;br&gt;
✅ Invest in automation, testing, and CI/CD before they become pain points&lt;/p&gt;

&lt;p&gt;💡 What’s your biggest lesson from scaling a frontend? Let’s discuss in the comments!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>scaling</category>
      <category>react</category>
    </item>
    <item>
      <title>From Spaghetti to Scalable: How I Modularized a Growing Frontend Codebase</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Mon, 24 Feb 2025 10:27:48 +0000</pubDate>
      <link>https://dev.to/_arpy/from-spaghetti-to-scalable-how-i-modularized-a-growing-frontend-codebase-33c6</link>
      <guid>https://dev.to/_arpy/from-spaghetti-to-scalable-how-i-modularized-a-growing-frontend-codebase-33c6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The "Oh No" Moment
&lt;/h2&gt;

&lt;p&gt;At some point in my career, I took over a &lt;strong&gt;large React app&lt;/strong&gt; that seemed fine at first — until it wasn't. 😅&lt;/p&gt;

&lt;p&gt;The project had evolved over time, but instead of growing gracefully, it became an unmanageable beast:&lt;/p&gt;

&lt;p&gt;❌ A custom state manager — hard to debug &amp;amp; scale.&lt;br&gt;
❌ Massive UI components — mixing business logic, API calls, and UI.&lt;br&gt;
❌ Multiple UI versions for different clients — but all versions lived in the same codebase.&lt;br&gt;
❌ Releases were painful — changing one part could break something completely unrelated.&lt;/p&gt;

&lt;p&gt;At some point, I realized: &lt;em&gt;This is unsustainable.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;This is the story of how I refactored that messy frontend into a modular, scalable, and maintainable system without breaking everything along the way.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Messy frontend code? Modularization is the key!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Break down your code into components, features, and domains.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep UI, logic, and data handling separate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NX monorepos solve interdependency issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start small, refactor in steps, and enforce structure with tools.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Phase 1: The Giant Monolithic App Era
&lt;/h2&gt;

&lt;p&gt;At the start, our React app was an all-in-one monolith:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Custom state management. We had built our own instead of using Redux or anything else (Context API was not that powerful yet).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;UI + logic bundled together. a single component could be over 500 lines long.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Multiple UI versions in one repo. Each client required a slightly different UI, but instead of separating them, all versions coexisted in the same codebase.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A single repo handled everything. State, API calls, business logic, and UI, making it hard to maintain and even harder to onboard new developers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNptkMFOwzAMhl_F8nl7gSIhlZYDh0qIwQ6kO5g2tJGSOEqcw7Tt3TFDAgnt5t_-bPn_TzjxbLHBJVNa4bW_GyNAawaO7J2sboIXS5NAm9IBttv7c8dRyMVyhgezExILA0VabLBRDtflf1hn3p6g45A4KlJuMr1pnxUi72_PH81QvbjkLXTe6RnY21wcx28cNxhsDuRm9QGnEWXVb0ZsYMQPKlpdFKEqvDvGCRvJ1W4wc11WbD7JF1U1zWqld6Q5hN9uovjO_Kft7ITz8JPYNbjLF2DXbWI" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2Fpako%3AeNptkMFOwzAMhl_F8nl7gSIhlZYDh0qIwQ6kO5g2tJGSOEqcw7Tt3TFDAgnt5t_-bPn_TzjxbLHBJVNa4bW_GyNAawaO7J2sboIXS5NAm9IBttv7c8dRyMVyhgezExILA0VabLBRDtflf1hn3p6g45A4KlJuMr1pnxUi72_PH81QvbjkLXTe6RnY21wcx28cNxhsDuRm9QGnEWXVb0ZsYMQPKlpdFKEqvDvGCRvJ1W4wc11WbD7JF1U1zWqld6Q5hN9uovjO_Kft7ITz8JPYNbjLF2DXbWI%3Ftype%3Dpng" alt="Monolith" width="800" height="179"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Biggest Pain Points:
&lt;/h3&gt;

&lt;p&gt;🚨 Scaling was impossible. As we added more clients, the complexity multiplied.&lt;br&gt;
🚨 Code duplication was everywhere. Reusing functionality meant lots of copy-pasting.&lt;br&gt;
🚨 UI modifications were a nightmare because each client had different design needs, we had tons of if statements handling different layouts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lesson Learned:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;A single repository containing everything isn't just inefficient — it's a ticking time bomb.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Phase 2: Splitting the Monolith — The First Step to Modularization
&lt;/h2&gt;

&lt;p&gt;Realizing the mess, I decided to refactor the app into separate repositories, each handling a specific concern.&lt;/p&gt;
&lt;h3&gt;
  
  
  The New Modular Structure:
&lt;/h3&gt;

&lt;p&gt;✅ A React component library 📦&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Contained state, API interactions, and core functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Single source of truth for all logic — no more duplication.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ A separate UI module 🎨&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A pure extension of Bootstrap CSS — no JavaScript, just styling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clients could now have different layouts without affecting the app logic.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ A React app for pages &amp;amp; UX 🏗️&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Handled routing, layouts, and page composition.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Different apps could now be built using the same API + component library.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNpVkU9rwzAMxb-K8Lk5JL1lMGgTBoUUyrLCmLODGrupIbGCIx9C6Xef0_TPejI_PT35WT6LmpQWqWgc9if4yt8qCzD4w8wZdT1ZbRkKc3DoxkkFWMeyZGQNW7TY6C40_N6URK52GyioMfW9tJQZOQ0f3tZsyGJreLxq2qrpeLlxv4EtKd_q2ZzFck3EAwcxOuCgFZQ8tsY2zwkv_k-NNcOq72d_HstdSDjcsuSJLHAkz4_CUoZe2H-_jlvHEEXvwX2FZIblBNl_5Q5JZcVCdNp1aFRYJpwrwaewl0qkUIkpdyUuoQU9UznaWqTsvF4IR745ifSI7RDI9yosNTcYntI9qj3aH6Ina2WY3Hb-tprs0TTi8gc2yJHS" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2Fpako%3AeNpVkU9rwzAMxb-K8Lk5JL1lMGgTBoUUyrLCmLODGrupIbGCIx9C6Xef0_TPejI_PT35WT6LmpQWqWgc9if4yt8qCzD4w8wZdT1ZbRkKc3DoxkkFWMeyZGQNW7TY6C40_N6URK52GyioMfW9tJQZOQ0f3tZsyGJreLxq2qrpeLlxv4EtKd_q2ZzFck3EAwcxOuCgFZQ8tsY2zwkv_k-NNcOq72d_HstdSDjcsuSJLHAkz4_CUoZe2H-_jlvHEEXvwX2FZIblBNl_5Q5JZcVCdNp1aFRYJpwrwaewl0qkUIkpdyUuoQU9UznaWqTsvF4IR745ifSI7RDI9yosNTcYntI9qj3aH6Ina2WY3Hb-tprs0TTi8gc2yJHS%3Ftype%3Dpng" alt="Modulized" width="800" height="213"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  What Changed?
&lt;/h3&gt;

&lt;p&gt;🚀 More flexibility — we could create apps with different layouts without duplicating code.&lt;br&gt;
🚀 Easier maintenance — frontend developers could work on UI without touching business logic.&lt;br&gt;
🚀 Cleaner separation of concerns — each module had a clear responsibility.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;The refactor was a game-changer. But it introduced a new challenge: managing interdependent packages.&lt;/em&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Phase 3: The NPM Link Hell &amp;amp; How NX Saved the Day
&lt;/h2&gt;

&lt;p&gt;After splitting the project into multiple repos, we ran into another problem:&lt;/p&gt;

&lt;p&gt;⚠️ &lt;em&gt;Local development became painful.&lt;/em&gt; We relied on npm linking to work across multiple co-dependent packages.&lt;br&gt;
⚠️ &lt;em&gt;Syncing changes was slow.&lt;/em&gt; Any update to one package had to be manually managed in others.&lt;br&gt;
⚠️ &lt;em&gt;Onboarding became complicated.&lt;/em&gt; New developers had to manually set up multiple repos just to get started.&lt;/p&gt;

&lt;p&gt;I realized that managing separate repos was becoming its own problem.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Solution: NX Monorepo
&lt;/h3&gt;

&lt;p&gt;To simplify development, we moved all modules into an NX workspace:&lt;/p&gt;

&lt;p&gt;✅ &lt;code&gt;Unified repository structure&lt;/code&gt; — All projects lived in one place.&lt;br&gt;
✅ &lt;code&gt;Built-in dependency graph&lt;/code&gt; — NX automatically understood how modules were connected.&lt;br&gt;
✅ &lt;code&gt;Faster builds&lt;/code&gt; — NX only rebuilt the parts of the code that changed.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;The migration strategy was key. To avoid disruption, we:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Created the app from scratch in the NX workspace.&lt;/li&gt;
&lt;li&gt;Copied the existing React component library without changing logic, just refactored class components into hooks.&lt;/li&gt;
&lt;li&gt;Introduced two additional modules to improve the architecture and add features.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://mermaid.live/edit#pako:eNp9Uk2LnEAQ_StFwzCXmYPmZiDgKIGFNQyZLCzRHGrsHm3QLumPBBnmv6fUrCs5LF76vVf16rXVd1GTVCIRjcWhhR_558oAuHBd8LdXKMiQVQNN_EbJmIT0_ATP-mrRjou829210T6B-963qlf7BPZXdGp_gErcOvpTt2h9JYArmKmD_a1mVAku047Pj-nb7RY_gDQqLx69ggINNmxp_K9Vi8s5ATW6_kcqIyvzX9SXJ07bD2S41731nqLyROSd55LjFFHCxY-dNs0HTl8V-sD3LkiGTq1eWVTm6NoroZVruCwuz5ZuulPv1KcyNdiNXtfugykFagPfFdYe0mF4a86j8sw_wK1ueVw-40jBbygeMAzw8rp13wxJIzgev3DeGcQLiCdwWpQ82oJZybZKFq-KOIhe2R615NcD90rMC6_EtEupbhg63vODqzB4uoymFom3QR2EpdC0Irlh5xiFQfJ2c418935lBzQ_id6xktqTLZanOr_Yx19vONZA" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmermaid.ink%2Fimg%2Fpako%3AeNp9Uk2LnEAQ_StFwzCXmYPmZiDgKIGFNQyZLCzRHGrsHm3QLumPBBnmv6fUrCs5LF76vVf16rXVd1GTVCIRjcWhhR_558oAuHBd8LdXKMiQVQNN_EbJmIT0_ATP-mrRjou829210T6B-963qlf7BPZXdGp_gErcOvpTt2h9JYArmKmD_a1mVAku047Pj-nb7RY_gDQqLx69ggINNmxp_K9Vi8s5ATW6_kcqIyvzX9SXJ07bD2S41731nqLyROSd55LjFFHCxY-dNs0HTl8V-sD3LkiGTq1eWVTm6NoroZVruCwuz5ZuulPv1KcyNdiNXtfugykFagPfFdYe0mF4a86j8sw_wK1ueVw-40jBbygeMAzw8rp13wxJIzgev3DeGcQLiCdwWpQ82oJZybZKFq-KOIhe2R615NcD90rMC6_EtEupbhg63vODqzB4uoymFom3QR2EpdC0Irlh5xiFQfJ2c418935lBzQ_id6xktqTLZanOr_Yx19vONZA%3Ftype%3Dpng" alt="NX Diagram" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  What Changed?
&lt;/h3&gt;

&lt;p&gt;🚀 Modular, scalable development — each team could now work on their own package without affecting others.&lt;br&gt;
🚀 Faster iteration — no more npm linking headaches!&lt;br&gt;
🚀 Better collaboration — dedicated teams worked on separate parts of the frontend.&lt;/p&gt;

&lt;p&gt;👉 &lt;em&gt;With NX, we finally had a system that was both modular and manageable.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Next Steps: Refining the NX Architecture&lt;/strong&gt; 🚀
&lt;/h3&gt;

&lt;p&gt;While migrating to an &lt;strong&gt;NX monorepo&lt;/strong&gt; significantly improved our workflow, there's still room for further modularization. The next phase will focus on &lt;em&gt;enhancing maintainability and scalability&lt;/em&gt; by:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Breaking Down Features into Micro Packages&lt;/strong&gt;&lt;br&gt;
Currently, our React component library contains both &lt;strong&gt;core functionality&lt;/strong&gt; and &lt;strong&gt;feature-specific logic&lt;/strong&gt;. To better align with &lt;strong&gt;NX's best practices&lt;/strong&gt;, we'll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Extract &lt;strong&gt;feature-specific modules&lt;/strong&gt; into &lt;strong&gt;standalone NX packages&lt;/strong&gt; (e.g., &lt;code&gt;@myorg/task-list&lt;/code&gt;, &lt;code&gt;@myorg/profile&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Ensure each feature package is &lt;strong&gt;independent and reusable&lt;/strong&gt; across multiple applications.&lt;/li&gt;
&lt;li&gt;  Reduce interdependencies between features to &lt;strong&gt;simplify development and deployment&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ &lt;strong&gt;Introducing Documentation with NX Storybook&lt;/strong&gt;&lt;br&gt;
To improve*developer experience and collaboration, we'll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Integrate &lt;strong&gt;NX Storybook&lt;/strong&gt; for our &lt;strong&gt;UI components&lt;/strong&gt; and &lt;strong&gt;feature modules&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Provide &lt;strong&gt;interactive documentation&lt;/strong&gt; where developers can preview and test components.&lt;/li&gt;
&lt;li&gt;  Standardize our &lt;strong&gt;design system and API contracts&lt;/strong&gt; to maintain consistency across projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these improvements, our &lt;strong&gt;NX workspace&lt;/strong&gt; will become even more &lt;em&gt;scalable, well-documented, and developer-friendly&lt;/em&gt; — allowing teams to work more efficiently with &lt;em&gt;clearly defined boundaries&lt;/em&gt; between features.&lt;/p&gt;


&lt;h2&gt;
  
  
  Final Takeaways: Lessons I Learned the Hard Way 😅
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;code&gt;Start modularizing early.&lt;/code&gt; Don't wait until the project is too big to handle.&lt;br&gt;
2️⃣ &lt;code&gt;Separate UI, logic, and state from the beginning.&lt;/code&gt; This saves countless hours of refactoring later.&lt;br&gt;
3️⃣ &lt;code&gt;Avoid unnecessary complexity.&lt;/code&gt; Modularization should make things easier, not harder.&lt;br&gt;
4️⃣ &lt;code&gt;Consider a monorepo for interdependent projects.&lt;/code&gt; NX solved many problems for us.&lt;br&gt;
5️⃣ &lt;code&gt;Migrating gracefully is key.&lt;/code&gt; Doing it step by step prevented downtime.&lt;/p&gt;


&lt;h2&gt;
  
  
  Conclusion: Keep It Simple, Keep It Scalable 🚀
&lt;/h2&gt;

&lt;p&gt;Modularization isn't about making things complex — it's about making them manageable.&lt;/p&gt;

&lt;p&gt;💡 If I were to start a frontend project today, I would:&lt;/p&gt;

&lt;p&gt;✅ Use a component-based architecture from day one.&lt;br&gt;
✅ Decouple UI from business logic immediately.&lt;br&gt;
✅ Consider a monorepo for interconnected projects.&lt;br&gt;
✅ Ensure teams have ownership over separate modules.&lt;/p&gt;

&lt;p&gt;🔹 Have you ever had to refactor a messy frontend codebase?&lt;br&gt;
🔹 What's your go-to strategy for keeping your projects modular?&lt;/p&gt;

&lt;p&gt;💬 Drop a comment — I'd love to hear your experiences!&lt;/p&gt;


&lt;h2&gt;
  
  
  📌 Want to Learn More?
&lt;/h2&gt;

&lt;p&gt;🔗 Here is more of my experience in scaling forntend apps:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/_arpy" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53792%2F75db98e0-7f50-4be7-b5d9-01f341eccbf0.png" alt="_arpy"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/_arpy/things-i-wish-i-knew-before-scaling-a-frontend-codebase-obp" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Things I Wish I Knew Before Scaling a Frontend Codebase 🚀&lt;/h2&gt;
      &lt;h3&gt;Arpy Vanyan ・ Mar 7&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#scaling&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;🔥 Like this post? Share it with your dev friends!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>nx</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Iterators in JavaScript Explained with Coffeeshops</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Tue, 18 Feb 2025 12:51:04 +0000</pubDate>
      <link>https://dev.to/_arpy/an-iterator-is-just-an-iterable-of-itself-javascript-explained-with-real-life-analogies-541</link>
      <guid>https://dev.to/_arpy/an-iterator-is-just-an-iterable-of-itself-javascript-explained-with-real-life-analogies-541</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;An Iterator is an Iterable of Itself&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Wait… What?!&lt;/strong&gt; 🤯
&lt;/h2&gt;

&lt;p&gt;Yeah, I know—it sounds like a &lt;strong&gt;weird riddle&lt;/strong&gt; from a programming wizard. But trust me, once you get it, &lt;strong&gt;you’ll never forget it&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript Iterators&lt;/strong&gt; are often misunderstood, but the truth is:&lt;br&gt;&lt;br&gt;
&lt;strong&gt;"An Iterator is just an Iterable of itself."&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;💡 Let’s &lt;strong&gt;break down this concept&lt;/strong&gt; with a &lt;strong&gt;fun analogy, some visual aids&lt;/strong&gt;, and &lt;strong&gt;real-life relatable examples&lt;/strong&gt;. If you’ve ever waited in line at a &lt;strong&gt;coffee shop&lt;/strong&gt;, you already know &lt;strong&gt;how iterators work&lt;/strong&gt;. ☕🔄  &lt;/p&gt;


&lt;h3&gt;
  
  
  🎯 &lt;strong&gt;TL;DR&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Iterables&lt;/strong&gt; have a &lt;strong&gt;&lt;code&gt;Symbol.iterator()&lt;/code&gt; method&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Iterators&lt;/strong&gt; have a &lt;strong&gt;&lt;code&gt;next()&lt;/code&gt; method&lt;/strong&gt; that returns &lt;code&gt;{ value, done }&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;strong&gt;an iterator returns itself&lt;/strong&gt; from &lt;strong&gt;&lt;code&gt;Symbol.iterator&lt;/code&gt;&lt;/strong&gt;, it becomes &lt;strong&gt;an iterable of itself&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Coffee queues&lt;/strong&gt; act like iterables. ☕&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  ☕ &lt;strong&gt;Imagine a Coffee Queue&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Picture this: you walk into your favorite &lt;strong&gt;coffee shop&lt;/strong&gt; and see a &lt;strong&gt;queue of people&lt;/strong&gt; waiting to order.  &lt;/p&gt;

&lt;p&gt;This &lt;strong&gt;queue of customers&lt;/strong&gt; is like a &lt;strong&gt;JavaScript iterable&lt;/strong&gt;—a &lt;strong&gt;collection&lt;/strong&gt; of people you can &lt;strong&gt;go through one by one&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;And guess what? &lt;strong&gt;The person serving the line&lt;/strong&gt; (the &lt;strong&gt;barista&lt;/strong&gt;) is like the &lt;strong&gt;iterator&lt;/strong&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;☕ &lt;strong&gt;The queue&lt;/strong&gt; = &lt;strong&gt;Iterable&lt;/strong&gt; (the collection)
&lt;/li&gt;
&lt;li&gt;👩‍🍳 &lt;strong&gt;The barista&lt;/strong&gt; = &lt;strong&gt;Iterator&lt;/strong&gt; (the one going through the collection)
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🧠 &lt;strong&gt;Here’s the key insight:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The barista (iterator) is also part of the queue (iterable).&lt;/strong&gt;  &lt;/p&gt;


&lt;h2&gt;
  
  
  🤯 &lt;strong&gt;Wait… How?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In JavaScript:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An &lt;strong&gt;iterator&lt;/strong&gt; &lt;strong&gt;is an object&lt;/strong&gt; that knows how to &lt;strong&gt;access items one-by-one&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;iterable&lt;/strong&gt; is an object that has a &lt;strong&gt;special method&lt;/strong&gt; (&lt;code&gt;Symbol.iterator&lt;/code&gt;) that returns an &lt;strong&gt;iterator&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;💡 The twist:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If an &lt;strong&gt;iterator returns itself when &lt;code&gt;Symbol.iterator&lt;/code&gt; is called&lt;/strong&gt;, it’s &lt;strong&gt;both&lt;/strong&gt; an &lt;strong&gt;iterator&lt;/strong&gt; &lt;strong&gt;and&lt;/strong&gt; an &lt;strong&gt;iterable&lt;/strong&gt;. 🤯  &lt;/p&gt;


&lt;h2&gt;
  
  
  🎯 &lt;strong&gt;Code Time! Let's See It in Action&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here's a simple &lt;strong&gt;custom iterator&lt;/strong&gt; in JavaScript that &lt;strong&gt;iterates over coffee orders&lt;/strong&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;const&lt;/span&gt; &lt;span class="nx"&gt;coffeeOrders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Latte&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Espresso&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cappuccino&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="c1"&gt;// Iterator next() method&lt;/span&gt;
  &lt;span class="nf"&gt;next&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&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;orders&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;index&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;done&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;done&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="c1"&gt;// Make the object an iterable of itself&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Iterating through coffee orders&lt;/span&gt;
&lt;span class="k"&gt;for &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;order&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;coffeeOrders&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`☕ Order: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🧠 &lt;strong&gt;What's Happening Here?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;next()&lt;/code&gt; Method:&lt;/strong&gt;
The &lt;strong&gt;barista (iterator)&lt;/strong&gt; goes through each &lt;strong&gt;coffee order&lt;/strong&gt; one by one.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;Symbol.iterator()&lt;/code&gt; Method:&lt;/strong&gt;
Returns &lt;strong&gt;&lt;code&gt;this&lt;/code&gt;&lt;/strong&gt;, meaning the &lt;strong&gt;iterator is also the iterable&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;📌 &lt;strong&gt;Output:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;☕ Order: Latte&lt;br&gt;
☕ Order: Espresso&lt;br&gt;
☕ Order: Cappuccino&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;See what we did there?&lt;/strong&gt;&lt;br&gt;
By returning &lt;strong&gt;&lt;code&gt;this&lt;/code&gt;&lt;/strong&gt; inside &lt;code&gt;Symbol.iterator()&lt;/code&gt;, we made the &lt;strong&gt;same object&lt;/strong&gt; act as &lt;strong&gt;both the iterator and the iterable&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  🖼️ &lt;strong&gt;Visualizing the Concept&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine this &lt;strong&gt;coffee queue&lt;/strong&gt; visually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+---------------------+
|  ☕ Latte            |
+---------------------+
|  ☕ Espresso         |
+---------------------+
|  ☕ Cappuccino       |
+---------------------+
|  👩‍🍳 Barista (Iterator)|
+---------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Barista (iterator) moves through each order.&lt;br&gt;
But... the Barista is also in the queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The barista is both:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Serving the orders&lt;/strong&gt; (iterator)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Part of the queue&lt;/strong&gt; (iterable)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧠 &lt;strong&gt;So... Why Does This Matter?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Understanding that &lt;strong&gt;"An Iterator Is an Iterable of Itself"&lt;/strong&gt; helps when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Creating custom iterators&lt;/strong&gt; like the &lt;code&gt;coffeeOrders&lt;/code&gt; example.&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Working with generator functions&lt;/strong&gt; (which &lt;strong&gt;return themselves&lt;/strong&gt; as iterators).&lt;/li&gt;
&lt;li&gt;  ✅ &lt;strong&gt;Debugging confusing iterator-related bugs&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🔍 &lt;strong&gt;Built-in Iterators That Follow This Rule&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;JavaScript &lt;strong&gt;already does this&lt;/strong&gt; with &lt;strong&gt;arrays, sets, maps&lt;/strong&gt;, and &lt;strong&gt;strings&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Check this out:&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;drinks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tea&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Coffee&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Juice&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// The array is both iterable and has an iterator&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;drinks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;drinks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]());&lt;/span&gt; &lt;span class="c1"&gt;// false (new iterator each time)&lt;/span&gt;

&lt;span class="c1"&gt;// But calling next() works just like with our custom iterator:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;drinkIterator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;drinks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&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;drinkIterator&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="c1"&gt;// { value: 'Tea', done: false }&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Arrays &lt;strong&gt;don't return themselves directly&lt;/strong&gt; but &lt;strong&gt;generate a new iterator&lt;/strong&gt;.&lt;br&gt;
But &lt;strong&gt;our &lt;code&gt;coffeeOrders&lt;/code&gt; object does&lt;/strong&gt;---making it both &lt;strong&gt;an iterator and an iterable of itself&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤓 &lt;strong&gt;The Takeaway (with Coffee!) ☕&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;"An Iterator is Just an Iterable of Itself"&lt;/strong&gt; means:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;An iterator&lt;/strong&gt; must implement a &lt;strong&gt;&lt;code&gt;next()&lt;/code&gt; method&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;strong&gt;&lt;code&gt;Symbol.iterator&lt;/code&gt; returns the same object&lt;/strong&gt;, it becomes &lt;strong&gt;an iterable as well&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  The &lt;strong&gt;same object&lt;/strong&gt; can &lt;strong&gt;both produce items&lt;/strong&gt; and &lt;strong&gt;represent the collection&lt;/strong&gt; being iterated over.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ☕ &lt;strong&gt;Final Thought: Coffee and JavaScript are Both Better When Shared!&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Next time you &lt;strong&gt;wait in a coffee queue&lt;/strong&gt;, remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;strong&gt;barista&lt;/strong&gt; isn't just &lt;strong&gt;serving customers&lt;/strong&gt;---they're also &lt;strong&gt;part of the system&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  Just like &lt;strong&gt;an iterator&lt;/strong&gt; that &lt;strong&gt;iterates over its own collection&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💬 &lt;strong&gt;Did this analogy help the concept click?&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Drop a comment below&lt;/strong&gt; and share &lt;strong&gt;your own JavaScript insights!&lt;/strong&gt; 🚀&lt;/p&gt;




&lt;p&gt;💡 &lt;strong&gt;Happy coding!&lt;/strong&gt; 🔄☕&lt;/p&gt;

</description>
      <category>javascrip</category>
      <category>programming</category>
      <category>coding</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Building a Scalable Delivery Pipeline for Small Teams 🚀</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Wed, 12 Feb 2025 13:13:11 +0000</pubDate>
      <link>https://dev.to/_arpy/building-a-scalable-delivery-pipeline-for-small-teams-g0c</link>
      <guid>https://dev.to/_arpy/building-a-scalable-delivery-pipeline-for-small-teams-g0c</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A well-structured &lt;strong&gt;delivery pipeline&lt;/strong&gt; ensures that software is shipped &lt;strong&gt;smoothly, reliably, and with confidence&lt;/strong&gt;. Whether you're working in a small team or a large enterprise, having a &lt;strong&gt;clear, repeatable&lt;/strong&gt; process is critical for delivering high-quality software.  &lt;/p&gt;

&lt;p&gt;This article breaks down a &lt;strong&gt;delivery pipeline setup&lt;/strong&gt; I implemented for a project, optimizing it for small teams. It includes &lt;strong&gt;staging best practices, automated deployments, package management, and a ticketing system that simplifies releases.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;If you're setting up a &lt;strong&gt;CI/CD workflow&lt;/strong&gt; or refining your software deployment process, this guide is for you! 🚀  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🎯 TL;DR&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;✔️ Always deploy to &lt;strong&gt;staging first&lt;/strong&gt; before production.&lt;br&gt;
✔️ Use &lt;strong&gt;nightly builds&lt;/strong&gt; to test new features early.&lt;br&gt;
✔️ Automate &lt;strong&gt;package publishing&lt;/strong&gt; and &lt;strong&gt;CI/CD deployments&lt;/strong&gt;.&lt;br&gt;
✔️ Keep &lt;strong&gt;staging clients on staging APIs&lt;/strong&gt; to prevent conflicts.&lt;br&gt;
✔️ Use &lt;strong&gt;Jira statuses&lt;/strong&gt; like &lt;strong&gt;"Ready for Deploy"&lt;/strong&gt; to improve workflow.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;1️⃣ The Importance of Staging&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Why Staging?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before any new feature or fix &lt;strong&gt;goes live&lt;/strong&gt;, it must be tested in an environment that closely mimics &lt;strong&gt;production&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;staging environment&lt;/strong&gt; serves as a &lt;strong&gt;sandbox for QAs and stakeholders&lt;/strong&gt; to validate changes &lt;strong&gt;before&lt;/strong&gt; they reach real users.  &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Golden Rule:&lt;/strong&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Never&lt;/strong&gt; ship any new code to production if it has not yet been tested and approved for deployment!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But how should the testers access the changes if they exist only on the developer’s local system?&lt;/p&gt;

&lt;p&gt;As the testers should act like end-users and not a part of the dev team, they should be able to access the final products in an environment that replicates the live version and includes all the latest changes that are ready to be tested. That is the staging environment.&lt;/p&gt;

&lt;p&gt;So, the dev team should always deploy the latest finished changes to the staging environment and ask the QA to test them. Normally, the deployment might include some issues and bugs (which doesn’t mean that the dev shouldn't test everything locally first), which the testers will notice and report.&lt;/p&gt;

&lt;p&gt;When the testers and the PO approve the current state of the staging environment, the team prepares for a release on production.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Deployment to Staging&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; push their latest changes to staging.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testers (QA)&lt;/strong&gt; validate everything &lt;strong&gt;as end-users would&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Product Owners (POs)&lt;/strong&gt; approve before release.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If it’s good, it goes live!&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

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


&lt;h2&gt;
  
  
  &lt;strong&gt;2️⃣ Think of Your Product Like a Pizza 🍕&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Your product is like a &lt;strong&gt;pizza&lt;/strong&gt;—it’s made up of different slices (components), and they all need to come together seamlessly when deployed. In most cases it is like a 3-slice pizza in fact:&lt;/p&gt;

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

&lt;p&gt;In this case, a deployment includes:&lt;br&gt;&lt;br&gt;
1️⃣ &lt;strong&gt;Packages&lt;/strong&gt; (code libraries and dependencies)&lt;br&gt;&lt;br&gt;
2️⃣ &lt;strong&gt;The Server&lt;/strong&gt; (backend APIs)&lt;br&gt;&lt;br&gt;
3️⃣ &lt;strong&gt;The Client&lt;/strong&gt; (front-end applications)  &lt;/p&gt;

&lt;p&gt;Each of these components &lt;strong&gt;must be properly staged, tested, and released&lt;/strong&gt; together for a smooth rollout.  &lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;3️⃣ Managing Packages Efficiently&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Most modern development relies on &lt;strong&gt;package management&lt;/strong&gt; to handle dependencies. Here’s how to keep it clean:  &lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Staging Packages with Nightly Builds 🌙&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When developing a new feature, testers should have access to &lt;strong&gt;pre-release versions&lt;/strong&gt;. A &lt;strong&gt;nightly build&lt;/strong&gt; ensures the latest changes are packaged daily.  &lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;How to publish a nightly build:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm publish &lt;span class="nt"&gt;--tag&lt;/span&gt; nightly
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Allows &lt;strong&gt;early testing&lt;/strong&gt; before an official release.&lt;/li&gt;
&lt;li&gt;  Ensures integration issues are caught early.&lt;/li&gt;
&lt;li&gt;  Automates packaging, reducing manual effort.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Production packages&lt;/strong&gt;, on the other hand, should be versioned properly using &lt;strong&gt;semantic versioning (semver)&lt;/strong&gt; for clarity.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4️⃣ Deployment Workflow: From Code to Production 🚀&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Remember to set the dependency packages in nightly builds to refer to their nightly versions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Server&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Runs in cloud or dedicated server, hosting the &lt;strong&gt;backend APIs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;New code&lt;/strong&gt; is deployed to &lt;strong&gt;staging first&lt;/strong&gt; before production.&lt;/li&gt;
&lt;li&gt;  The &lt;strong&gt;CI/CD pipeline&lt;/strong&gt; automates deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Client&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Any changes in the front-end must be deployed in sync with the backend.&lt;/li&gt;
&lt;li&gt;  If a client instance depends on a &lt;strong&gt;new API&lt;/strong&gt;, it must be tested &lt;strong&gt;in staging first&lt;/strong&gt; before being moved to production.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;5️⃣ Streamlining Task Management with Jira 📋&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As we want the testers to have something already deployed to Staging for them to start testing and avoid doing it locally, we need to have a new state on for the tickets called “Ready for deploy”.&lt;/p&gt;

&lt;p&gt;It would mean the following: &lt;em&gt;“The code was written and reviewed and is ready to be delivered to the testers”&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Old Ticket Flow:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To Do → In Progress → Code Review → Testing → Done&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;New &amp;amp; Improved Workflow:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;✅ To Do → In Progress → Code Review → &lt;strong&gt;Ready for Deploy&lt;/strong&gt; → Testing → Done&lt;/p&gt;

&lt;p&gt;After the sprint is finished and all the Done tasks are approved, the PO will identify the features that are ready to be delivered to the customers. For this kind of work, we will have separate deployment tasks that would skip the 3d and 4th steps during realization.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Why this change?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Before, &lt;strong&gt;testers had to wait&lt;/strong&gt; and guess when developers manually deployed the latest version to staging.&lt;/li&gt;
&lt;li&gt;  Now, with &lt;strong&gt;"Ready for Deploy"&lt;/strong&gt;, testers know &lt;strong&gt;when a feature is available in staging&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  This reduces &lt;strong&gt;bottlenecks&lt;/strong&gt; and improves &lt;strong&gt;release efficiency&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚀 &lt;strong&gt;Result:&lt;/strong&gt; Faster deployments, happier testers, and smoother releases!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;6️⃣ Final Steps to a Cleaner Pipeline&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To &lt;strong&gt;fully optimize&lt;/strong&gt; the delivery process, these improvements should be implemented:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;[Task Management]&lt;/strong&gt; Add a "Ready for Deploy" status in Jira.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[Automation]&lt;/strong&gt; Improve CI/CD scripts to auto-publish nightly builds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[Versioning]&lt;/strong&gt; Use &lt;strong&gt;semantic versioning&lt;/strong&gt; for clarity in releases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[CI/CD Improvements]&lt;/strong&gt; Automate deployment of &lt;strong&gt;server and client&lt;/strong&gt; to both staging and production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[Environment Fix]&lt;/strong&gt; Ensure all &lt;strong&gt;staging clients use staging APIs&lt;/strong&gt; only.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚀 &lt;em&gt;By implementing these best practices, small teams can maintain a highly efficient delivery pipeline without unnecessary delays or confusion.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion: Why This Works for Small Teams 🏆&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;structured&lt;/strong&gt; delivery pipeline isn't just for large teams---it's &lt;strong&gt;critical for small teams too!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By &lt;strong&gt;automating testing and deployments&lt;/strong&gt;, keeping environments &lt;strong&gt;clearly separated&lt;/strong&gt;, and &lt;strong&gt;simplifying task tracking&lt;/strong&gt;, you can:&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Ship faster&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Catch bugs earlier&lt;/strong&gt;&lt;br&gt;
✅ &lt;strong&gt;Reduce deployment stress&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're setting up a &lt;strong&gt;CI/CD process&lt;/strong&gt; for your team, &lt;strong&gt;start with these principles&lt;/strong&gt;---they will save you &lt;strong&gt;a ton of headaches&lt;/strong&gt; in the long run!&lt;/p&gt;

&lt;p&gt;💬 What challenges have you faced with setting up a delivery pipeline? Let's discuss in the comments! 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>softwaredevelopment</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The Prototype Chain Explained with a Library System 📚</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Sun, 09 Feb 2025 12:44:42 +0000</pubDate>
      <link>https://dev.to/_arpy/the-prototype-chain-explained-with-a-library-system-93g</link>
      <guid>https://dev.to/_arpy/the-prototype-chain-explained-with-a-library-system-93g</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Ever borrowed a book from a library? Good. You already understand JavaScript Prototypes.&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Imagine you walk into your &lt;strong&gt;neighborhood library&lt;/strong&gt; looking for a rare book on &lt;em&gt;"The Secrets of JavaScript Sorcery."&lt;/em&gt; You ask the librarian, but—oops!—your library doesn’t have it.  &lt;/p&gt;

&lt;p&gt;But don’t worry! Instead of sending you home empty-handed, the librarian &lt;strong&gt;calls up the central city library&lt;/strong&gt; to check if they have it. If they do, you get your book. If not, the search continues up the chain… maybe to the &lt;strong&gt;National Library Archive&lt;/strong&gt;. And if &lt;em&gt;even they&lt;/em&gt; don’t have it? Sorry, no book for you.  &lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;exactly&lt;/strong&gt; how JavaScript’s prototype chain works! 🚀  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📌 TL;DR&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  Objects in JavaScript can &lt;strong&gt;inherit properties&lt;/strong&gt; from other objects.&lt;/li&gt;
&lt;li&gt;  When a property isn't found in an object, JavaScript &lt;strong&gt;climbs up the prototype chain&lt;/strong&gt; to check its prototype.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;Object.create()&lt;/code&gt; is like opening a &lt;strong&gt;new library branch&lt;/strong&gt; connected to the central library.&lt;/li&gt;
&lt;li&gt;  If a property isn't found anywhere, JavaScript returns &lt;code&gt;undefined&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🏛 Libraries = JavaScript Objects&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In JavaScript, &lt;strong&gt;objects can borrow properties and methods&lt;/strong&gt; from other objects, just like a library can request books from a bigger library system. Let’s break it down:  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1️⃣ Local Library (Your Object)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your library has its own &lt;strong&gt;collection&lt;/strong&gt;—books it directly owns.&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;localLibrary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;specialCollection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ancient Maps&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rare Manuscripts&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;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;localLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;specialCollection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
&lt;span class="c1"&gt;// ["Ancient Maps", "Rare Manuscripts"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2️⃣ Central Library (Prototype)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;But what if your local library doesn't have a specific book? It asks the &lt;strong&gt;Central Library&lt;/strong&gt;, which has a much bigger collection.&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;centralLibrary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;lendBook&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Here's your book from the central archive!&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;h3&gt;
  
  
  &lt;strong&gt;3️⃣ Connecting Them (Prototype Chain)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Now, let's &lt;strong&gt;link&lt;/strong&gt; your local library to the central one using &lt;code&gt;Object.create()&lt;/code&gt;. This way, whenever your local library doesn't have something, it &lt;strong&gt;automatically&lt;/strong&gt; looks in the central library!&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;cityLibrary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;centralLibrary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;cityLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;specialCollection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ancient Maps&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Rare Manuscripts&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;cityLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;specialCollection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ["Ancient Maps", "Rare Manuscripts"]&lt;/span&gt;

&lt;span class="nx"&gt;cityLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lendBook&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// "Here's your book from the central archive!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though &lt;code&gt;lendBook&lt;/code&gt; &lt;strong&gt;wasn't defined&lt;/strong&gt; in &lt;code&gt;cityLibrary&lt;/code&gt;, it still worked! That's because JavaScript &lt;strong&gt;climbed up the prototype chain&lt;/strong&gt; and found it in the &lt;code&gt;centralLibrary&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🛤 The Search Path (Prototype Chain in Action)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's add another library: a &lt;strong&gt;small-town library&lt;/strong&gt; that borrows from the city library.&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;smallTownLibrary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cityLibrary&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;smallTownLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;specialCollection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ["Ancient Maps", "Rare Manuscripts"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom! Even though &lt;code&gt;smallTownLibrary&lt;/code&gt; doesn't have a &lt;code&gt;specialCollection&lt;/code&gt; &lt;strong&gt;directly&lt;/strong&gt;, it &lt;strong&gt;inherits it from cityLibrary&lt;/strong&gt;, which inherited it from itself.&lt;/p&gt;

&lt;p&gt;And it &lt;strong&gt;can still borrow books from the central library&lt;/strong&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;smallTownLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lendBook&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// "Here's your book from the central archive!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔗 &lt;strong&gt;JavaScript keeps searching up the chain until it finds what it needs---or gives up!&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;❌ What Happens If a Book Doesn't Exist?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say you ask for a &lt;strong&gt;mystery book that no one owns&lt;/strong&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;smallTownLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rareBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript checks:&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;code&gt;smallTownLibrary&lt;/code&gt; → ❌ (Doesn't have it)\&lt;br&gt;
2️⃣ &lt;code&gt;cityLibrary&lt;/code&gt; → ❌ (Doesn't have it either)\&lt;br&gt;
3️⃣ &lt;code&gt;centralLibrary&lt;/code&gt; → ❌ (Nope!)\&lt;br&gt;
4️⃣ &lt;strong&gt;&lt;code&gt;Object.prototype&lt;/code&gt;&lt;/strong&gt; → ❌ (Last stop---if it's not here, it doesn't exist)&lt;/p&gt;

&lt;p&gt;Since no one has it, you get &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;This is exactly how JavaScript searches for properties in objects.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;🖼 Visualizing the Prototype Chain&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;💡 &lt;strong&gt;Want an easier way to visualize the Prototype Chain?&lt;/strong&gt;\&lt;br&gt;
Here's what our example looks like behind the scenes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;smallTownLibrary  ---&amp;gt;  cityLibrary  ---&amp;gt;  centralLibrary  ---&amp;gt;  Object.prototype  ---&amp;gt;  null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every object in JavaScript follows this chain &lt;strong&gt;all the way up to &lt;code&gt;Object.prototype&lt;/code&gt;&lt;/strong&gt;, which is like the &lt;strong&gt;National Library Archive&lt;/strong&gt;---the place where common methods like &lt;code&gt;.toString()&lt;/code&gt; exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🎯 Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Next time you're borrowing a book from a library, think about JavaScript's prototype chain working in the same way. Your local branch (object) might not have a book (property), but it always knows where to look!&lt;/p&gt;

&lt;p&gt;This is what makes JavaScript so &lt;strong&gt;powerful and flexible&lt;/strong&gt;---objects can share behavior without copying everything manually.&lt;/p&gt;

&lt;p&gt;Now that you've cracked the mystery of &lt;strong&gt;Prototypes&lt;/strong&gt;, where should we go next? 🤔&lt;/p&gt;

&lt;p&gt;💡 Thinking about writing an article on &lt;strong&gt;how &lt;code&gt;new&lt;/code&gt; works in JavaScript&lt;/strong&gt;? Let me know!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;💬 What do you think?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Have you encountered prototype chains in your projects? Let me know your thoughts and experiences in the comments below! 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>prototype</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JavaScript Array.reduce() explained with LEGO bricks</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Thu, 20 Sep 2018 14:03:26 +0000</pubDate>
      <link>https://dev.to/_arpy/javascript-arrayreduce-explained-with-lego-bricks-4pca</link>
      <guid>https://dev.to/_arpy/javascript-arrayreduce-explained-with-lego-bricks-4pca</guid>
      <description>&lt;h4&gt;
  
  
  We all must agree that JavaScript is great! But you know what? LEGO is even greater! Why? Because you can explain and model so many ideas and behaviors and algorithms using this amazing toy 🚀.
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AHtqyqbVrAooagfsg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F0%2AHtqyqbVrAooagfsg" width="800" height="600"&gt;&lt;/a&gt;“assorted-color plastic toy lot” by &lt;a href="https://unsplash.com/@egnaro?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Rick Mason&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce" rel="noopener noreferrer"&gt;Mozilla Developers Network&lt;/a&gt; defines the reduce method in Array object prototype like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;reduce()&lt;/strong&gt; method executes a &lt;strong&gt;reducer&lt;/strong&gt; function (that you provide) on each member of the array resulting in a single output value.&lt;/p&gt;

&lt;p&gt;Your &lt;strong&gt;reducer&lt;/strong&gt; function’s returned value is assigned to the accumulator, whose value is remembered across each iteration throughout the array and ultimately becomes the final, single resulting value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All right, but when and how I can use this function? Is it only for summing all the numbers in an array? Is there a real-world example? And what do this Accumulator (acc), Current Value (cur), Current Index (idx) and Source Array (src) stand for?&lt;/p&gt;

&lt;p&gt;🧒🏻 Let’s dive into the kid’s room for a nice explanation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The colorful blocks
&lt;/h2&gt;

&lt;p&gt;Let’s be honest, I’m a totally incorrigible LEGO addict 🤪. Ah, those colors, shapes, and possibilities to build anything you can imagine out of them…&lt;/p&gt;

&lt;p&gt;Now, as I don’t have so much time to spend on them, I prefer to have all the sets built up and displayed on a shelf as they should look like according to the model. But, from time-to-time (especially when the kids get their hands over my precious collection) all of my sets get mixed up and thrown in a big container altogether. Oh, what a mess… And then comes the time for me to gather all my supplies, strength and motivation to bring them back onto their shelves.&lt;/p&gt;

&lt;p&gt;But wait, what about &lt;strong&gt;reducers&lt;/strong&gt;? Okay, so before I can restore my displayed collection, I need to build them, and to do that, I need to know which piece belongs to which set. Then I would be able to construct the sets with their instructions (as if I don’t know the instructions by heart 😁).&lt;/p&gt;

&lt;p&gt;And here comes the time for my brain to use a perfect &lt;strong&gt;array reducer&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s reduce the bricks
&lt;/h2&gt;

&lt;p&gt;Okay, so for the ease of the example, let’s assume that there are no shared blocks among the different sets. So I know, that if I see a black 2x2 block, I know that it belongs to my Star Wars &lt;strong&gt;B-Wing Fighter&lt;/strong&gt; and all my red windows belong to an old &lt;strong&gt;family house&lt;/strong&gt; set. Let’s assume I have only 3 LEGO sets: a B-Wing, a Harry Potter forbidden corridor room and a simple old house with white walls and red roof.&lt;/p&gt;

&lt;p&gt;So, here is my container of all the bricks messed up together.&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;bricks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;b-wing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2x2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;house&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;roof&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4x2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;hp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;spider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1x1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;b-wing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;panel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4x8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gray&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;b-wing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2x2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;black&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;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;house&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;brick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;6x1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I want to arrange them into boxes with LEGO sets like this:&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="nl"&gt;"b-wing"&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;"house"&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;"hp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[]}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📥📥📥 I haven't prepared the labeled boxes, so I will do it along the way, as soon as I stumble upon a piece that doesn’t have a box yet.&lt;/p&gt;

&lt;p&gt;So, what I am going to do, is to loop through all the bricks and put each of them into the corresponding box. Here are some statements from the process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Initially&lt;/em&gt;&lt;/strong&gt; , I have &lt;strong&gt;&lt;em&gt;no boxes&lt;/em&gt;&lt;/strong&gt; prepared for each set, but I know that I am going to put the boxes on &lt;strong&gt;&lt;em&gt;a special shelf&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;I take out a new brick from the &lt;strong&gt;&lt;em&gt;initial&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;container,&lt;/em&gt; process it in mind, decide where it belongs to, and put the &lt;strong&gt;&lt;em&gt;current&lt;/em&gt;&lt;/strong&gt; brick into its set box.&lt;/li&gt;
&lt;li&gt;If there is no box for the set of my &lt;strong&gt;&lt;em&gt;current piece,&lt;/em&gt;&lt;/strong&gt; I create and label a new box and put it on the  &lt;strong&gt;&lt;em&gt;shelf.&lt;/em&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Each time I take a brick from the &lt;strong&gt;&lt;em&gt;initial&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;container,&lt;/em&gt; I &lt;strong&gt;&lt;em&gt;reduce&lt;/em&gt;&lt;/strong&gt; the number of all bricks left to arrange.&lt;/li&gt;
&lt;li&gt;Finally, when there is no brick left in the &lt;strong&gt;&lt;em&gt;initial&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;container&lt;/em&gt; to process, I look at my shelf and see that my mixed pile of LEGO bricks got &lt;strong&gt;&lt;em&gt;transformed&lt;/em&gt;&lt;/strong&gt; into a structured arrangement of labeled boxes on my shelf.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, in other words (or in visual), I will transform the pile on the left into the organized structure on the right:&lt;/p&gt;

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

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

&lt;p&gt;👩🏻‍💻 If someone would have coded this whole process in JavaScript using the Array.reduce() method, it 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bricks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[....];&lt;/span&gt; &lt;span class="c1"&gt;//the pile of bricks defined above&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shelf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bricks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;shelfOfBoxes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;brick&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;brickNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pile&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="s2"&gt;`Checking the brick number &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;brickNumber&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;shelfOfBoxes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;brick&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="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;shelfOfBoxes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;brick&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;//add a new box if needed&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;shelfOfBoxes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;brick&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="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;brick&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//put the brick in its box&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="s2"&gt;`Bricks left: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;pile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;brickNumber&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//the empty shelf&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;shelf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And what do we have here?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Initially&lt;/strong&gt; I have a mixed pile of bricks stored in an array&lt;/li&gt;
&lt;li&gt;Initially my &lt;strong&gt;shelf&lt;/strong&gt; is empty. The second argument in the reduce function is the initial value of the shelf, which is an empty object: &lt;code&gt;{}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;I loop through the array with the &lt;strong&gt;reduce&lt;/strong&gt; method&lt;/li&gt;
&lt;li&gt;In each iteration of the loop I know the following: the current situation on the shelf (&lt;code&gt;shelfOfBoxes&lt;/code&gt;), the current brick I’m processing (&lt;code&gt;brick&lt;/code&gt;), which is the current index of the brick/how many I have already processed (&lt;code&gt;brickNumber&lt;/code&gt;) and the initial bunch of bricks (&lt;code&gt;pile&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;During each loop, I check if there is a box with the set name for my current brick on the shelf: &lt;code&gt;if(!shelfOfBoxes._hasOwnProperty_(brick.set))&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In case there is no box, I add a new &lt;strong&gt;empty&lt;/strong&gt; box with the label of current brick’s set to the shelf: &lt;code&gt;shelfOfBoxes[brick.set] = [];&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then I put the current brick into the box for its set: &lt;code&gt;shelfOfBoxes[brick.set]._push_(brick);&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;I note to myself how many bricks are left in the pile: console.log(&lt;code&gt;Bricks left: ${pile.length — (brickNumber + 1)}&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;In the end I have a &lt;strong&gt;shelf of boxes&lt;/strong&gt; filled with all the bricks that belong to each set box&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I used a &lt;strong&gt;&lt;em&gt;reducer&lt;/em&gt;&lt;/strong&gt; function to &lt;strong&gt;transform&lt;/strong&gt; an array of objects into something &lt;em&gt;completely different&lt;/em&gt;. That is the purpose of the &lt;code&gt;Array.reduce()&lt;/code&gt; method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Done
&lt;/h3&gt;

&lt;p&gt;Cool, now you should have a clue on what is the reduce method, what are its arguments, and what is a real world example when our brain works like a reducer 🧠.&lt;/p&gt;

&lt;p&gt;Of course there are other possibilities and use cases for the &lt;code&gt;Array.reduce()&lt;/code&gt; method. You should also know that the initial value of the transformation is optional. I already know another brick-related example for that case. Stay tuned for another article with the detailed explanation coming soon 📢.&lt;/p&gt;

&lt;p&gt;And, of course:&lt;/p&gt;

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




</description>
      <category>arrays</category>
      <category>javascript</category>
      <category>reducer</category>
      <category>node</category>
    </item>
    <item>
      <title>How to log out when using JWT</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Sun, 17 Jun 2018 10:46:42 +0000</pubDate>
      <link>https://dev.to/_arpy/how-to-log-out-when-using-jwt-4ajm</link>
      <guid>https://dev.to/_arpy/how-to-log-out-when-using-jwt-4ajm</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhop1kxi11ml5d1fhll3a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhop1kxi11ml5d1fhll3a.jpg" width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The wonder of JSON Web Tokens
&lt;/h3&gt;

&lt;p&gt;JSON Web Tokens (JWT) is a way of statelessly handling user authentication. What does it mean? Well, JWT helps to organize authentication without storing the authentication state in any storage be it a session or a database. Thus, when checking user’s authentication status you do not need to access the session or perform a database query. Instead, you generate a token based on the user payload of your choice and use it in requests from client side to identify the user on server. 🛂&lt;/p&gt;

&lt;p&gt;So, basically, whenever a token is created, it can be used forever, or until it is expired. JWT generator can get an option to invalidate the token after specified time.&lt;/p&gt;

&lt;p&gt;But what to do if you want to invalidate an existing token? What you actually need to do when the user opts to log out, or let’s say change password? 🤔&lt;/p&gt;

&lt;h3&gt;
  
  
  Let’s log out
&lt;/h3&gt;

&lt;p&gt;Okay, so usually, when using JWT authentication, the client side stores the token somewhere and attaches it to every request that needs authentication. So, the first thing to do when logging out, is just delete the token you stored on the client (e.i. browser local storage). In that case the client won’t have a token to put in the request, thus causing unauthorized response status. But is that enough? Well, that specific client (browser, app) won’t be authenticated any more, but the token still exists somewhere and it is still valid! If someone has copied the token from the request before, he/she would still be able to perform requests on behalf of the user! 👾 You can easily try this out on your own.&lt;/p&gt;

&lt;p&gt;“Okay, so let’s log out the user from the backend!” you would say. But hold down the horses. It’s not that simple with JWT. You cannot delete the session or cookie and get going.&lt;/p&gt;

&lt;p&gt;Actually, JWT serves a different purpose than a session and it is not possible to forcefully delete or invalidate an existing token.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expiring a token?
&lt;/h3&gt;

&lt;p&gt;Yes, the tokens can be expired. No, you cannot do it on demand.&lt;/p&gt;

&lt;p&gt;When signing a user payload for a JWT you are allowed to pass an expiration time to it. You can provide it as a field called &lt;strong&gt;exp&lt;/strong&gt; in the payload like this:&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;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&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;"John 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;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516234022&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1516239022&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;The expiration field takes number of milliseconds since the start of Unix epoch. As the iat field here stands for “issued at”, this token is set to expire 5 seconds after it was issued. ⏰&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note:&lt;/em&gt;&lt;/strong&gt; If you are using one of the JWT libraries listed &lt;a href="https://jwt.io/#libraries" rel="noopener noreferrer"&gt;here&lt;/a&gt;, most likely you can also pass an expiration time in the signing method options.&lt;/p&gt;

&lt;p&gt;If you don’t want to have forever valid tokens, you should always set a reasonable expiration time on you JWT. The amount of time really depends on your application. We’ll go with &lt;strong&gt;&lt;em&gt;one day&lt;/em&gt;&lt;/strong&gt; tokens here and generate them in our login action. For a NodeJS app the code should look something 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&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;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sub&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234567890&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;iat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1516234022&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1d&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;So, when the token expires, the validator will return an error and you backend will respond with an unauthorized response status as soon as it gets a request that needs authorization. Usually, you will unset the token from the client side and redirect the user to the login page. So, with this example, all users will be automatically logged out after 1 day of using your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  “Cool, but I still want to log out!” ➡️
&lt;/h3&gt;

&lt;p&gt;As already said, you cannot manually expire a token after it has been created. Thus, you cannot actually log out with JWT on the server side 🙀Or, unless, you can…&lt;/p&gt;

&lt;p&gt;It is said that using JWT should be stateless, meaning that you should store everything you need in the payload and skip performing a DB query on every request. But if you plan to have a strict log out functionality, that cannot wait for the token auto-expiration, even though you have cleaned the token from client side, then you might need to neglect the stateless logic and do some queries.&lt;/p&gt;

&lt;p&gt;An implementation would probably be, to store a so called “blacklist” of all the tokens that are valid no more and have not expired yet. You can use a DB that has TTL option on documents which would be set to the amount of time left until the token is expired. &lt;strong&gt;Redis&lt;/strong&gt; is a good option for this, that will allow fast in memory access to the list. Then, in a middleware of some kind that runs on every authorized request, you should check if provided token is in &lt;strong&gt;The Blacklist. 🕵️‍&lt;/strong&gt; If it is you should throw an unauthorized error. And if it is not, let it go and the JWT verification will handle it and identify if it is expired or still active.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5cbfru9n7uehowyu1el.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn5cbfru9n7uehowyu1el.jpeg" width="568" height="335"&gt;&lt;/a&gt;One does not simply log out with JWT…&lt;/p&gt;

&lt;p&gt;As it seems, creating a clean log out flow when using JSON Web Tokens is not so straightforward. You should either let a token be active until it is expired by itself, or opt to use a storage for logged out tokens if you want to restrict the usage of a token when a user logs out. To sum it all up, simply follow this 4 bullet points:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set a reasonable expiration time on tokens&lt;/li&gt;
&lt;li&gt;Delete the stored token from client side upon log out&lt;/li&gt;
&lt;li&gt;Have DB of no longer active tokens that still have some time to live&lt;/li&gt;
&lt;li&gt;Query provided token against &lt;strong&gt;The Blacklist&lt;/strong&gt; on every authorized request&lt;/li&gt;
&lt;/ol&gt;

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

</description>
      <category>jwt</category>
      <category>token</category>
      <category>authentication</category>
    </item>
    <item>
      <title>HTML5 form validation in React</title>
      <dc:creator>Arpy Vanyan</dc:creator>
      <pubDate>Sun, 18 Feb 2018 16:47:47 +0000</pubDate>
      <link>https://dev.to/_arpy/html5-form-validation-in-react-3308</link>
      <guid>https://dev.to/_arpy/html5-form-validation-in-react-3308</guid>
      <description>

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bcnek76T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2AHsjdj3i8TIc4_zrU." class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bcnek76T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/0%2AHsjdj3i8TIc4_zrU." alt=""&gt;&lt;/a&gt;“Colorful lines of code on a computer screen” by &lt;a href="https://unsplash.com/@_imkiran?utm_source=medium&amp;amp;utm_medium=referral"&gt;Sai Kiran Anagani&lt;/a&gt; on &lt;a href="https://unsplash.com?utm_source=medium&amp;amp;utm_medium=referral"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Best data is a validated data&lt;/h3&gt;

&lt;p&gt;Users… Data collection… Forms… I’m sure you know that user input is good when it is valid ✅. That is why websites must encourage the users to fill in the best fitting data whenever possible.&lt;/p&gt;

&lt;p&gt;There are various libraries like &lt;strong&gt;jQuery Validation&lt;/strong&gt; or &lt;strong&gt;Validate.js,&lt;/strong&gt; that help with form input validations. All of them implement the idea of performing predefined checks on each of the form fields before it is submitted. Then, they display error messages, if there are fields that do not qualify.&lt;/p&gt;

&lt;p&gt;But there is also the powerful HTML5 validation API. And it’s awesome. Modern browsers almost fully support the API. Of course, each of them implemented its own way of performing the validation and displaying error messages. And sometimes it looks really nasty 🙈&lt;/p&gt;

&lt;p&gt;So, why not implement our own layout for the validation errors? Sounds doable. We will use the following aspects from the HTML5 constraint validation API: the &lt;strong&gt;&lt;em&gt;checkValidity&lt;/em&gt;&lt;/strong&gt; method and the  &lt;strong&gt;&lt;em&gt;:valid/:invalid&lt;/em&gt;&lt;/strong&gt; states of a form, and the &lt;strong&gt;&lt;em&gt;validity&lt;/em&gt;&lt;/strong&gt; property of form elements. If curious, they are explained in detail in &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation"&gt;this superb MDN Web Docs (Mozilla Developer Network) page.&lt;/a&gt; What I am going to do is to implement custom validation messages using the API for a &lt;strong&gt;React&lt;/strong&gt; app. Let’s go! 🏁 🚗&lt;/p&gt;

&lt;h3&gt;The React Component&lt;/h3&gt;

&lt;p&gt;Well, React means Components! We surely need to create one for this task. And, surprisingly, it will be a custom stateful &lt;strong&gt;Form&lt;/strong&gt; component with its corresponding styles file.&lt;/p&gt;

&lt;p&gt;First of all, let's define how we want to display our validation errors. I prefer to have separate messages next to each form field. For our ease, we will assume, that every input field is assigned with  &lt;strong&gt;&lt;em&gt;.form-control&lt;/em&gt;&lt;/strong&gt; class, and each of them has a sibling &amp;lt;&lt;em&gt;span&amp;gt;&lt;/em&gt; with an  &lt;strong&gt;&lt;em&gt;.invalid-feedback&lt;/em&gt;&lt;/strong&gt; class. Each span will hold the error message of its relevant form element. In this implementation, each form element will have its own error message container next to it. Of course, you are free to define your own error containers and even have only one container for displaying all of the messages in one place.&lt;/p&gt;

&lt;p&gt;As you might already know, the validity of a form element is identified by a CSS pseudo class. If the element (&lt;em&gt;input, textarea, checkbox,…&lt;/em&gt;) passes the defined rules, it is assigned with  &lt;strong&gt;&lt;em&gt;:valid&lt;/em&gt;&lt;/strong&gt; pseudo class. Otherwise it gets  &lt;strong&gt;&lt;em&gt;:invalid&lt;/em&gt;&lt;/strong&gt; pseudo class. We will use this behavior do decide whether an error message should be displayed next to an element or not. We’ll define a style in our &lt;strong&gt;Form.css&lt;/strong&gt; that will hide the messages of valid elements.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.form-control&lt;/span&gt;&lt;span class="nd"&gt;:valid&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="nc"&gt;.invalid-feedback&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The idea of the component is the following. In React, typically, we don’t want to reload the page on form submission. Instead, we want to send the data with &lt;strong&gt;ajax&lt;/strong&gt; request. It doesn’t matter for our validation component how and what data is submitted. We just handle validation. That is why it will receive a property named &lt;strong&gt;submit&lt;/strong&gt;, which is a function, that should be called whenever the form is allowed to be submitted. The component will override the native form submit event in the following way. First, it will check the overall form validity with the &lt;strong&gt;&lt;em&gt;checkValidity&lt;/em&gt;&lt;/strong&gt; method. If no errors found, it will perform the submission by calling the &lt;em&gt;submit&lt;/em&gt; method from &lt;strong&gt;props.&lt;/strong&gt; If there was at least one invalid element, it will show the corresponding messages and cancel the form submission. And, of course, the component will render a regular &lt;em&gt;&amp;lt;form&amp;gt;&lt;/em&gt; tag, with all the child elements nested inside.&lt;/p&gt;

&lt;p&gt;Sounds pretty straightforward, right? Let’s see how it looks like as a code 😉&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&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="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react'&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;PropTypes&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'prop-types'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s1"&gt;'./Form.css'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="kd"&gt;extends&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;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;isValidated&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="nx"&gt;validate&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formLength&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;formEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&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;formEl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;checkValidity&lt;/span&gt;&lt;span class="p"&gt;()&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="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;formLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elem&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;formEl&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.invalid-feedback'&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;errorLabel&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nx"&gt;errorLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validationMessage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="nx"&gt;errorLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;return&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;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;formLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elem&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;formEl&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorLabel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parentNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.invalid-feedback'&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;errorLabel&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nodeName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;'button'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nx"&gt;errorLabel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="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;submitHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validate&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;submit&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;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="na"&gt;isValidated&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="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="nx"&gt;props&lt;/span&gt; &lt;span class="o"&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;classNames&lt;/span&gt; &lt;span class="o"&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;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;classNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
            &lt;span class="k"&gt;delete&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;className&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isValidated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;classNames&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="s1"&gt;'.was-validated'&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;form&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;formEl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="o"&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;submitHandler&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;classNames&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;noValidate&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;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;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/form&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Form&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 dig into it starting from the bottom ⬆️. So, we render a regular &lt;em&gt;&amp;lt;form&amp;gt;&lt;/em&gt; that includes all the children passed to our component. It also gets a  &lt;strong&gt;.was-validated&lt;/strong&gt; class in case we have no errors. We can use this class for styling for example. We also hold a reference to our form element in our component. Thus we would be able to work with it with JavaScript methods. Also, we assign a &lt;em&gt;submit handler&lt;/em&gt; function to the form with the &lt;strong&gt;&lt;em&gt;onSubmit&lt;/em&gt;&lt;/strong&gt; event.&lt;/p&gt;

&lt;p&gt;When the form is submitted (typically with a submit button), we call the component method called &lt;strong&gt;&lt;em&gt;validate().&lt;/em&gt;&lt;/strong&gt; It’s not hard to guess that this is the method where our component’s main functionality is hidden. So, if it returns &lt;strong&gt;&lt;em&gt;true&lt;/em&gt;&lt;/strong&gt;, the form is valid, and we are free to call the component’s &lt;strong&gt;&lt;em&gt;submit&lt;/em&gt;&lt;/strong&gt; method. Now, how does the validation work 🤔?&lt;/p&gt;

&lt;h4&gt;The Validate method&lt;/h4&gt;

&lt;p&gt;In HTML5, a form validity is checked with the &lt;strong&gt;&lt;em&gt;checkValidation()&lt;/em&gt;&lt;/strong&gt; method. It returns &lt;strong&gt;&lt;em&gt;true&lt;/em&gt;&lt;/strong&gt; if all the form elements qualify defined rules and &lt;strong&gt;&lt;em&gt;false&lt;/em&gt;&lt;/strong&gt;, if at least one validation rule fails. We’ll use this behavior in our component.&lt;/p&gt;

&lt;p&gt;In case the form is &lt;strong&gt;valid&lt;/strong&gt;, we will loop through its elements and remove the text of their corresponding error containers.&lt;/p&gt;

&lt;p&gt;If the form is invalid, we need to show messages for each of the erred elements. If a form element is invalid, its &lt;strong&gt;&lt;em&gt;validity.valid&lt;/em&gt;&lt;/strong&gt; property would be false. In such case, we will fill the  &lt;strong&gt;.invalid-feedback&lt;/strong&gt; &lt;em&gt;&amp;lt;span&amp;gt;&lt;/em&gt; with the corresponding error message. The error message provided by the API is accessible through the &lt;strong&gt;&lt;em&gt;validationMessage&lt;/em&gt;&lt;/strong&gt; property of an element. We will use that message as it is pretty much detailed and already localized with the browser locale. If you want to use your custom error messages, you should assign the &lt;em&gt;errorLabel.textContent&lt;/em&gt; with your value instead of &lt;em&gt;elem.validationMessage.&lt;/em&gt; As simple as that.&lt;/p&gt;

&lt;p&gt;Note, that we skip an element if it is a button. This is because a form refers to all of its elements that a user can interact with, including buttons.&lt;/p&gt;

&lt;p&gt;Now, all our invalid fields have error messages next to them and our form is not submitted until all errors are fixed 👍 The only thing left to do is styling! But I guess I’ll leave the funny part to you, as &lt;em&gt;“I want to believe”&lt;/em&gt; (👽) in your creativity 😜&lt;/p&gt;

&lt;p&gt;Thanks for reading this far, hope you had fun and learned something new here. &lt;/p&gt;

&lt;p&gt;Here is a full working &lt;a href="https://codepen.io/_arpy/pen/xYoyPW"&gt;CodePen&lt;/a&gt; that I created as a playground 🎮 Enjoy, coders!&lt;/p&gt;

&lt;p&gt;&lt;iframe height="500" src="https://codepen.io/_arpy/embed/xYoyPW/?height=505&amp;amp;theme-id=dark&amp;amp;default-tab=js,result&amp;amp;embed-version=2%20?height=500&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt; &lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;And one more thing…&lt;/p&gt;

&lt;h3&gt;Secure yourself from both sides&lt;/h3&gt;

&lt;p&gt;Remember, validating user input in client side is not enough. A smarty like you can always find a way to avoid the validation. That is why &lt;strong&gt;always&lt;/strong&gt; do checks also in your &lt;strong&gt;backend.&lt;/strong&gt; Believe me, you’ll thank yourself for that ☺️&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VlsT44Mm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media.giphy.com/media/u4KibgMsDLWM0/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VlsT44Mm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://media.giphy.com/media/u4KibgMsDLWM0/giphy.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;


</description>
      <category>react</category>
      <category>validation</category>
      <category>html5</category>
      <category>components</category>
    </item>
  </channel>
</rss>
