<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Amandeep Singh</title>
    <description>The latest articles on Forem by Amandeep Singh (@singhamandeep007).</description>
    <link>https://forem.com/singhamandeep007</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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg</url>
      <title>Forem: Amandeep Singh</title>
      <link>https://forem.com/singhamandeep007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/singhamandeep007"/>
    <language>en</language>
    <item>
      <title>Stop wasting hours on React setup. 🛑

I just launched Version 2 of my production-ready React-Vite-TS boilerplate. It’s now a single-command scaffold to get you from zero to production.</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Thu, 16 Apr 2026 05:41:01 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/stop-wasting-hours-on-react-setup-i-just-launched-version-2-of-my-production-ready-4kak</link>
      <guid>https://forem.com/singhamandeep007/stop-wasting-hours-on-react-setup-i-just-launched-version-2-of-my-production-ready-4kak</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l" class="crayons-story__hidden-navigation-link"&gt;Building a Production-Ready React + Vite + TypeScript Boilerplate: Architecture, Choices &amp;amp; DX Deep-Dive&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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" alt="singhamandeep007 profile" class="crayons-avatar__image" width="400" height="400"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/singhamandeep007" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Amandeep Singh
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Amandeep Singh
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" width="166" height="102"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-3445234" 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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" class="crayons-avatar__image" alt="" width="400" height="400"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Amandeep Singh&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 4&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l" id="article-link-3445234"&gt;
          Building a Production-Ready React + Vite + TypeScript Boilerplate: Architecture, Choices &amp;amp; DX Deep-Dive
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/vite"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;vite&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l" 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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;7&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l#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;
            12 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>
    </item>
    <item>
      <title>From college assignment to portfolio centerpiece. 📂</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Thu, 16 Apr 2026 05:28:54 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/from-college-assignment-to-portfolio-centerpiece-12ei</link>
      <guid>https://forem.com/singhamandeep007/from-college-assignment-to-portfolio-centerpiece-12ei</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd" class="crayons-story__hidden-navigation-link"&gt;Building an Interactive N-Queens Visualizer with React + TypeScript&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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" alt="singhamandeep007 profile" class="crayons-avatar__image" width="400" height="400"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/singhamandeep007" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Amandeep Singh
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Amandeep Singh
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" width="166" height="102"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-3455715" 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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" class="crayons-avatar__image" alt="" width="400" height="400"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Amandeep Singh&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/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 5&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/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd" id="article-link-3455715"&gt;
          Building an Interactive N-Queens Visualizer with React + TypeScript
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/algorithms"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;algorithms&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/visualization"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;visualization&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/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd" 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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&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/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd#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>algorithms</category>
      <category>react</category>
      <category>showdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How would you rate my portfolio out of 10 from a UX/UI and performance perspective? The good, the bad, and the ugly - tell me in the comments.</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Thu, 16 Apr 2026 05:26:05 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/how-would-you-rate-my-portfolio-out-of-10-from-a-uxui-and-performance-perspective-the-good-the-1gc8</link>
      <guid>https://forem.com/singhamandeep007/how-would-you-rate-my-portfolio-out-of-10-from-a-uxui-and-performance-perspective-the-good-the-1gc8</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba" class="crayons-story__hidden-navigation-link"&gt;How I Built My Portfolio Website with React + Vite: Themes, Particles, GitHub Visualizations, and a Dev.to-Powered Posts Page&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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" alt="singhamandeep007 profile" class="crayons-avatar__image" width="400" height="400"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/singhamandeep007" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Amandeep Singh
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Amandeep Singh
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png" width="166" height="102"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-3455657" 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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" class="crayons-avatar__image" alt="" width="400" height="400"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Amandeep Singh&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/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Apr 5&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/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba" id="article-link-3455657"&gt;
          How I Built My Portfolio Website with React + Vite: Themes, Particles, GitHub Visualizations, and a Dev.to-Powered Posts Page
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/portfolio"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;portfolio&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&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/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba" 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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&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/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba#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>performance</category>
      <category>showdev</category>
      <category>ui</category>
      <category>ux</category>
    </item>
    <item>
      <title>Building an Interactive N-Queens Visualizer with React + TypeScript</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:21:54 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd</link>
      <guid>https://forem.com/singhamandeep007/how-i-built-an-interactive-n-queens-visualizer-with-react-typescript-and-backtracking-4mpd</guid>
      <description>&lt;h1&gt;
  
  
  Building an Interactive N-Queens Visualizer with React + TypeScript
&lt;/h1&gt;

&lt;p&gt;I rebuilt this write-up after a full master-branch audit and focused it on what the code actually ships today: a single-page interactive algorithm visualizer with real-time constraint feedback, simulation playback, and responsive controls.&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%2Fgezjxkm4weru1yv51ign.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%2Fgezjxkm4weru1yv51ign.jpg" alt="AI-generated hero cover: algorithmic chess visualization" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live demo: &lt;a href="https://singhAmandeep007.github.io/eight-queens-problem-visualizer/" rel="noopener noreferrer"&gt;https://singhAmandeep007.github.io/eight-queens-problem-visualizer/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/singhAmandeep007/eight-queens-problem-visualizer" rel="noopener noreferrer"&gt;https://github.com/singhAmandeep007/eight-queens-problem-visualizer&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;What the App Does&lt;/li&gt;
&lt;li&gt;Architecture&lt;/li&gt;
&lt;li&gt;Design System&lt;/li&gt;
&lt;li&gt;Theming&lt;/li&gt;
&lt;li&gt;Motion and Animations&lt;/li&gt;
&lt;li&gt;Particles and Background Effects&lt;/li&gt;
&lt;li&gt;Special Interaction&lt;/li&gt;
&lt;li&gt;Projects Module&lt;/li&gt;
&lt;li&gt;Posts and Blog Module&lt;/li&gt;
&lt;li&gt;About and Profile Module&lt;/li&gt;
&lt;li&gt;Responsiveness&lt;/li&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;Key Implementation Details&lt;/li&gt;
&lt;li&gt;Lessons Learned and Next Steps&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the App Does
&lt;/h2&gt;

&lt;p&gt;The N-Queens puzzle asks us to place N pieces on an N x N board with zero conflicts.&lt;/p&gt;

&lt;p&gt;This project turns that into an interactive engineering playground:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Piece-rule switching: queen, bishop, rook, knight&lt;/li&gt;
&lt;li&gt;Manual mode for direct placement and conflict feedback&lt;/li&gt;
&lt;li&gt;Simulation mode for animated backtracking exploration&lt;/li&gt;
&lt;li&gt;Variable board size from 4x4 to 8x8&lt;/li&gt;
&lt;li&gt;Solution list replay to inspect discovered arrangements&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%2F080cu09zushgg4lfn3jq.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%2F080cu09zushgg4lfn3jq.png" alt="Home and board overview" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture
&lt;/h2&gt;

&lt;p&gt;The app is intentionally compact but still modular in behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App shell in App.tsx&lt;/li&gt;
&lt;li&gt;State domains in ControlContext and AlertContext&lt;/li&gt;
&lt;li&gt;Algorithm and rendering orchestration in Chessboard&lt;/li&gt;
&lt;li&gt;Rule engine utilities in constants&lt;/li&gt;
&lt;li&gt;Reusable control primitives in ControlSelect and common/button&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Flowchart image (static for Dev.to compatibility):&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%2Fxfqb6o0vy5yot9u1mj6a.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%2Fxfqb6o0vy5yot9u1mj6a.png" alt="Architecture flowchart" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Design System
&lt;/h2&gt;

&lt;p&gt;The design system is lightweight and practical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS variables define core color tokens&lt;/li&gt;
&lt;li&gt;Styled-components handle composable UI surfaces&lt;/li&gt;
&lt;li&gt;Reusable button primitive keeps action affordances consistent&lt;/li&gt;
&lt;li&gt;Board and controls share clear visual hierarchy and spacing&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%2Ffzclilgg2kwobzhbhi9c.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%2Ffzclilgg2kwobzhbhi9c.png" alt="Control configuration panel" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Theming
&lt;/h2&gt;

&lt;p&gt;Even without a dark/light toggle, the app is tokenized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primary and secondary hues drive control and action zones&lt;/li&gt;
&lt;li&gt;Surface and background tokens support layered feedback&lt;/li&gt;
&lt;li&gt;Piece and board contrast remains readable across interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because tokens are centralized, runtime theme switching can be introduced later with minimal component churn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motion and Animations
&lt;/h2&gt;

&lt;p&gt;Motion is used to explain logic rather than decorate UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simulation playback updates board state at user-selected speed&lt;/li&gt;
&lt;li&gt;Alerts animate in and out for lightweight status communication&lt;/li&gt;
&lt;li&gt;Solved-state celebration gives immediate completion feedback&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%2Fpkdt2jou988c5vzswmu1.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%2Fpkdt2jou988c5vzswmu1.png" alt="Simulation running state" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Particles and Background Effects
&lt;/h2&gt;

&lt;p&gt;This branch intentionally avoids heavy particle layers and uses informative effects instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Conflict squares use striped overlays&lt;/li&gt;
&lt;li&gt;Board container shadows emphasize focus&lt;/li&gt;
&lt;li&gt;Celebration overlay marks solved states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That keeps the experience fast while preserving strong visual state signaling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Special Interaction
&lt;/h2&gt;

&lt;p&gt;The standout interaction is simulation control + replayability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Play/Stop orchestrates async search&lt;/li&gt;
&lt;li&gt;Simulation auto-interrupt logic handles tab visibility changes&lt;/li&gt;
&lt;li&gt;Solved boards can be reset and replayed rapidly&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;GIF fallback:&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%2Fz34hntvwht8mpandpizk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz34hntvwht8mpandpizk.gif" alt="Simulation recording (GIF fallback)" width="960" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Projects Module
&lt;/h2&gt;

&lt;p&gt;In this single-page architecture, the solution explorer acts as the project/results module:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every valid solution is persisted&lt;/li&gt;
&lt;li&gt;Entries are clickable to preview placements instantly&lt;/li&gt;
&lt;li&gt;Duplicate solutions are deduplicated using serialized keys&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%2Fa63qvjpvc9uk7asvfosc.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%2Fa63qvjpvc9uk7asvfosc.png" alt="Solution explorer panel" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Posts and Blog Module
&lt;/h2&gt;

&lt;p&gt;The in-app information modal works as the educational content module:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Problem statement and interaction model are available inline&lt;/li&gt;
&lt;li&gt;Portal rendering avoids z-index and stacking issues&lt;/li&gt;
&lt;li&gt;Users can enter and exit context quickly without navigation&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%2F2ro22gzqa43hks1by7w5.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%2F2ro22gzqa43hks1by7w5.png" alt="In-app information modal" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About and Profile Module
&lt;/h2&gt;

&lt;p&gt;Profile attribution is implemented in the footer module:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Author identity is visible in the app shell&lt;/li&gt;
&lt;li&gt;External profile link supports discoverability and ownership&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%2Fso0fr5eofuhncazsm4jy.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%2Fso0fr5eofuhncazsm4jy.png" alt="Profile footer module" width="800" height="1111"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Responsiveness
&lt;/h2&gt;

&lt;p&gt;Responsive behavior is handled through global breakpoints and adaptive layouts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Root font scaling across screen-size bands&lt;/li&gt;
&lt;li&gt;Control bar wrapping under smaller widths&lt;/li&gt;
&lt;li&gt;Chessboard + side panel stack behavior for mobile ergonomics&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%2Fz8ldaxjcxovuwyazf1de.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%2Fz8ldaxjcxovuwyazf1de.png" alt="Mobile responsive layout" width="390" height="844"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance
&lt;/h2&gt;

&lt;p&gt;Performance decisions visible in the code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;useMemo for board-grid generation by board size&lt;/li&gt;
&lt;li&gt;Cached solved-state checks for repeated position sets&lt;/li&gt;
&lt;li&gt;Fast simulation mode for rapid enumeration&lt;/li&gt;
&lt;li&gt;Input controls disabled while simulation runs to reduce race conditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Known trade-off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Position encoding uses row*10+col, which is compact and efficient for current board ranges (4-8), but not ideal for larger generalized boards.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;Deployment pipeline is straightforward and production-safe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm run build creates dist output&lt;/li&gt;
&lt;li&gt;npm run deploy uses gh-pages&lt;/li&gt;
&lt;li&gt;Vite base path is derived from GITHUB_PAGES_REPO for GitHub Pages correctness&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Implementation Details
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Context-driven state architecture&lt;/li&gt;
&lt;li&gt;ControlContext owns mode, speed, piece type, board size, simulation state&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AlertContext centralizes user feedback and timeout cleanup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rule engine abstraction&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;checkConflictMethods encapsulates row/column, diagonal, and knight checks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;checkIsAttacking and checkIsSolved compose these rules for both manual and simulation paths&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Async simulation loop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recursive backtracking-style search enumerates candidate positions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Board state updates are interleaved with delays for visual progression&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stop conditions are managed with refs and side effects for safe interruption&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lessons Learned and Next Steps
&lt;/h2&gt;

&lt;p&gt;Lessons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explicit state boundaries make even single-page apps easier to reason about&lt;/li&gt;
&lt;li&gt;Algorithm visualizers benefit from controls that expose execution speed and mode&lt;/li&gt;
&lt;li&gt;Visual effects should carry semantic meaning, not just aesthetics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract solver logic to a dedicated module for stronger unit testing&lt;/li&gt;
&lt;li&gt;Add symmetry reduction for mathematically equivalent solutions&lt;/li&gt;
&lt;li&gt;Move from row*10+col encoding to coordinate tuples for long-term extensibility&lt;/li&gt;
&lt;li&gt;Add keyboard-first interaction flow for accessibility&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>algorithms</category>
      <category>visualization</category>
    </item>
    <item>
      <title>How I Built My Portfolio Website with React + Vite: Themes, Particles, GitHub Visualizations, and a Dev.to-Powered Posts Page</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:00:06 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba</link>
      <guid>https://forem.com/singhamandeep007/how-i-built-my-portfolio-website-with-react-vite-themes-particles-github-visualizations-and-a-37ba</guid>
      <description>&lt;h1&gt;
  
  
  How I Built My Portfolio Website with React + Vite: Themes, Particles, GitHub Visualizations, and a Dev.to-Powered Posts Page
&lt;/h1&gt;

&lt;p&gt;I recently rebuilt my personal portfolio to reflect how I like to build products: clear architecture, expressive UI, strong performance defaults, and data-backed sections that stay fresh.&lt;/p&gt;

&lt;p&gt;Live website: &lt;a href="https://singhamandeep007.github.io/" rel="noopener noreferrer"&gt;https://singhamandeep007.github.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repository: &lt;a href="https://github.com/singhAmandeep007/singhAmandeep007.github.io" rel="noopener noreferrer"&gt;https://github.com/singhAmandeep007/singhAmandeep007.github.io&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%2Fut6c0bsk8tk2ps9hg31z.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%2Fut6c0bsk8tk2ps9hg31z.png" alt="Portfolio Home" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Project Overview&lt;/li&gt;
&lt;li&gt;Design Direction&lt;/li&gt;
&lt;li&gt;Architecture At A Glance&lt;/li&gt;
&lt;li&gt;Theme Engine (Multi Theme)&lt;/li&gt;
&lt;li&gt;Particles Background With Floating Tech Logos&lt;/li&gt;
&lt;li&gt;Resume Open Animation&lt;/li&gt;
&lt;li&gt;Projects Page&lt;/li&gt;
&lt;li&gt;Posts Page (Powered By Dev.to API)&lt;/li&gt;
&lt;li&gt;About Page + GitHub Contributions + GitHub Showcase&lt;/li&gt;
&lt;li&gt;Responsive UX + Sidebar Navigation&lt;/li&gt;
&lt;li&gt;Performance + Developer Experience&lt;/li&gt;
&lt;li&gt;What I Would Improve Next&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;This portfolio is built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React 18 + TypeScript&lt;/li&gt;
&lt;li&gt;Vite 5&lt;/li&gt;
&lt;li&gt;styled-components&lt;/li&gt;
&lt;li&gt;React Router (lazy route loading)&lt;/li&gt;
&lt;li&gt;tsParticles for animated background motion&lt;/li&gt;
&lt;li&gt;Dev.to API integration for articles&lt;/li&gt;
&lt;li&gt;GitHub GraphQL API integration for contribution and profile showcase widgets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was simple:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep the UI visually alive without becoming noisy.&lt;/li&gt;
&lt;li&gt;Keep content dynamic where possible (GitHub + Dev.to).&lt;/li&gt;
&lt;li&gt;Keep the codebase modular and easy to personalize.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Design Direction
&lt;/h2&gt;

&lt;p&gt;I wanted the experience to feel like a blend of developer identity and product polish:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bright accent colors that can switch at runtime,&lt;/li&gt;
&lt;li&gt;subtle glassmorphism where it helps depth,&lt;/li&gt;
&lt;li&gt;playful details (handwave animation, envelope-style resume interaction),&lt;/li&gt;
&lt;li&gt;high-density information modules on About (contributions, profile metrics, repo cards).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The whole layout stays section-based, with each page having a clear visual job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Home: first impression + CTA&lt;/li&gt;
&lt;li&gt;Projects: proof of work&lt;/li&gt;
&lt;li&gt;Posts: writing and thought process&lt;/li&gt;
&lt;li&gt;About: profile depth + GitHub signal&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture At A Glance
&lt;/h2&gt;

&lt;p&gt;I use a shared layout route that always renders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sidebar menu,&lt;/li&gt;
&lt;li&gt;active route outlet,&lt;/li&gt;
&lt;li&gt;theme toggler,&lt;/li&gt;
&lt;li&gt;particle background.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
  A[ThemeProvider + GlobalStyle] --&amp;gt; B[Shared Layout]
  B --&amp;gt; C[SidebarMenu]
  B --&amp;gt; D[Route Outlet]
  B --&amp;gt; E[ToggleTheme]
  B --&amp;gt; F[ParticlesContainer]

  D --&amp;gt; H[Home]
  D --&amp;gt; I[Projects]
  D --&amp;gt; J[Posts]
  D --&amp;gt; K[About]

  K --&amp;gt; L[GitHub Contributions GraphQL]
  K --&amp;gt; M[GitHub Showcase GraphQL]
  J --&amp;gt; N[Dev.to Articles API]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This structure keeps global behavior centralized while pages remain focused.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theme Engine (Multi Theme)
&lt;/h2&gt;

&lt;p&gt;One of my favorite parts is the theme system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Themes are created through a small theme factory (&lt;code&gt;createTheme&lt;/code&gt;) using primary/background/font values.&lt;/li&gt;
&lt;li&gt;The app generates CSS variables for each theme class.&lt;/li&gt;
&lt;li&gt;Theme switching is class-based on &lt;code&gt;document.documentElement&lt;/code&gt; for instant variable swapping.&lt;/li&gt;
&lt;li&gt;A small transition class smooths the color shift.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also map theme colors into GitHub contribution chart palettes, so the data visuals feel native to whichever theme is active.&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%2Fippykg58vfzxcttw25op.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%2Fippykg58vfzxcttw25op.png" alt="Theme Toggle Open" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Particles Background With Floating Tech Logos
&lt;/h2&gt;

&lt;p&gt;The background uses tsParticles in two layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;baseline moving particles,&lt;/li&gt;
&lt;li&gt;floating image particles sourced from my tech logo list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A batched loader progressively injects logo particles so the effect ramps up instead of appearing all at once. It gives the page ambient motion while keeping content readable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resume Open Animation
&lt;/h2&gt;

&lt;p&gt;Instead of a normal download button, I built a small envelope interaction:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a cover flap rotates with &lt;code&gt;rotateX&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;the letter slides out,&lt;/li&gt;
&lt;li&gt;click opens/closes,&lt;/li&gt;
&lt;li&gt;click on letter triggers resume download.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is intentionally playful, but still functional and accessible.&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%2Fasd04hv2n1my1o5h8k79.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%2Fasd04hv2n1my1o5h8k79.png" alt="Resume Animation State" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Projects Page
&lt;/h2&gt;

&lt;p&gt;The Projects page is data-driven from a single projects data source:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;markdown-supported descriptions,&lt;/li&gt;
&lt;li&gt;per-project stack icons,&lt;/li&gt;
&lt;li&gt;image/video slide support,&lt;/li&gt;
&lt;li&gt;fullscreen preview support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I alternate layout direction between odd/even project items for visual rhythm on larger screens, then collapse to a single-column flow on mobile.&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%2Fres.cloudinary.com%2Fdryiuvv1l%2Fimage%2Fupload%2Fv1775368708%2Fportfolio-blog%2Fprojects.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%2Fres.cloudinary.com%2Fdryiuvv1l%2Fimage%2Fupload%2Fv1775368708%2Fportfolio-blog%2Fprojects.png" alt="Projects Page" width="800" height="3424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Posts Page (Powered By Dev.to API)
&lt;/h2&gt;

&lt;p&gt;The Posts page fetches articles directly from my Dev.to account and renders them as cards with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cover image,&lt;/li&gt;
&lt;li&gt;tags,&lt;/li&gt;
&lt;li&gt;publish date,&lt;/li&gt;
&lt;li&gt;comments count,&lt;/li&gt;
&lt;li&gt;reactions count.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I filter out repost-like items by checking reading time so the page emphasizes full technical pieces.&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%2Fnm1aoahciptq7q9plqzr.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%2Fnm1aoahciptq7q9plqzr.png" alt="Posts Page" width="800" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About Page + GitHub Contributions + GitHub Showcase
&lt;/h2&gt;

&lt;p&gt;This page combines static profile context with live GitHub data.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Contributions Calendar
&lt;/h3&gt;

&lt;p&gt;I fetch contribution years and calendars from GitHub GraphQL, then render a custom SVG chart.&lt;/p&gt;

&lt;p&gt;Features include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;virtualized week rendering for smoother scroll,&lt;/li&gt;
&lt;li&gt;multiple visual modes (Heatmap, Forest, Garden, Skyline),&lt;/li&gt;
&lt;li&gt;year jump controls,&lt;/li&gt;
&lt;li&gt;auto-scroll playback,&lt;/li&gt;
&lt;li&gt;palette adaptation by active theme.&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%2Fkete0v1lsojr216pijrs.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%2Fkete0v1lsojr216pijrs.png" alt="Contributions Forest Theme" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2) GitHub Showcase
&lt;/h3&gt;

&lt;p&gt;I also built a profile showcase module using GraphQL to display:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;follower and repo metrics,&lt;/li&gt;
&lt;li&gt;contribution metrics (commits/PRs),&lt;/li&gt;
&lt;li&gt;language distribution bar,&lt;/li&gt;
&lt;li&gt;pinned/top repositories with topic badges.&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%2Fpb9uxoa0osfrvljr5vqi.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%2Fpb9uxoa0osfrvljr5vqi.png" alt="GitHub Showcase Section" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Full About page context:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdryiuvv1l%2Fimage%2Fupload%2Fv1775368694%2Fportfolio-blog%2Fabout.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%2Fres.cloudinary.com%2Fdryiuvv1l%2Fimage%2Fupload%2Fv1775368694%2Fportfolio-blog%2Fabout.png" alt="About Page" width="800" height="1404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Responsive UX + Sidebar Navigation
&lt;/h2&gt;

&lt;p&gt;Responsiveness is handled through centralized breakpoints and component-level media rules.&lt;/p&gt;

&lt;p&gt;Key UX behaviors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;focus-trapped sidebar menu,&lt;/li&gt;
&lt;li&gt;click-outside to close overlays,&lt;/li&gt;
&lt;li&gt;blur treatment on background content when overlays are active,&lt;/li&gt;
&lt;li&gt;typography scaling by breakpoint,&lt;/li&gt;
&lt;li&gt;horizontal overflow handling for dense visual modules.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps keyboard and touch interactions practical across sizes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance + Developer Experience
&lt;/h2&gt;

&lt;p&gt;Some implementation decisions that helped:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;route-level lazy imports,&lt;/li&gt;
&lt;li&gt;manual chunk grouping for vendor and particle libraries,&lt;/li&gt;
&lt;li&gt;optional dev-time TypeScript/ESLint checking via environment toggles,&lt;/li&gt;
&lt;li&gt;build visualizer output for bundle inspection,&lt;/li&gt;
&lt;li&gt;strict TypeScript config and lint/format scripts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For deployment, GitHub Actions builds and ships to GitHub Pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Would Improve Next
&lt;/h2&gt;

&lt;p&gt;If I take this further, I would like to add:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;richer skeleton/loading states instead of blank transitions,&lt;/li&gt;
&lt;li&gt;offline support + cache strategy for API-backed sections,&lt;/li&gt;
&lt;li&gt;more accessibility audits (focus indicators, reduced-motion pathways),&lt;/li&gt;
&lt;li&gt;analytics on which projects/posts get most engagement.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;This portfolio became more than a profile page. It is now a living frontend playground where I can experiment with UI systems, data visualizations, and interaction patterns in production.&lt;/p&gt;

&lt;p&gt;If you want to explore or fork it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live: &lt;a href="https://singhamandeep007.github.io/" rel="noopener noreferrer"&gt;https://singhamandeep007.github.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/singhAmandeep007/singhAmandeep007.github.io" rel="noopener noreferrer"&gt;https://github.com/singhAmandeep007/singhAmandeep007.github.io&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would love feedback on the architecture and UX decisions.&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>portfolio</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building a Production-Ready React + Vite + TypeScript Boilerplate: Architecture, Choices &amp; DX Deep-Dive</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Sat, 04 Apr 2026 11:47:37 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l</link>
      <guid>https://forem.com/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-architecture-choices-dx-2i7l</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Table of Contents&lt;/li&gt;
&lt;li&gt;🎯 Why Another Boilerplate?&lt;/li&gt;
&lt;li&gt;🏗️ High-Level Architecture&lt;/li&gt;
&lt;li&gt;📁 Project Structure — Organized for Scale&lt;/li&gt;
&lt;li&gt;
⚡ The Foundation: Vite + React + TypeScript

&lt;ul&gt;
&lt;li&gt;Why Vite?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🧭 Routing: TanStack Router

&lt;ul&gt;
&lt;li&gt;Why TanStack Router over React Router?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🗄️ State Management: The Two-Store Strategy

&lt;ul&gt;
&lt;li&gt;TanStack Query — Server State&lt;/li&gt;
&lt;li&gt;Zustand — Client State&lt;/li&gt;
&lt;li&gt;Auto-Generated Selectors&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🌐 API Layer: ky + ApiService Pattern

&lt;ul&gt;
&lt;li&gt;Why ky over Axios or fetch?&lt;/li&gt;
&lt;li&gt;The ApiService abstraction&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;🎭 API Mocking: MSW&lt;/li&gt;

&lt;li&gt;🌍 Internationalization: i18next&lt;/li&gt;

&lt;li&gt;

🧪 Testing Strategy: The Full Pyramid

&lt;ul&gt;
&lt;li&gt;Unit Tests: Vitest + React Testing Library&lt;/li&gt;
&lt;li&gt;Component Tests: Storybook + Vitest Browser&lt;/li&gt;
&lt;li&gt;E2E Tests: Cypress&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🎨 UI Layer: Shadcn UI + Tailwind CSS

&lt;ul&gt;
&lt;li&gt;Why Shadcn UI?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

🔧 Developer Experience (DX) Toolchain

&lt;ul&gt;
&lt;li&gt;Code → Lint → Format → Commit&lt;/li&gt;
&lt;li&gt;ESLint: Context-Aware Rules&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;🛠️ DevTools: Development-Only by Design&lt;/li&gt;

&lt;li&gt;🔒 TypeScript: Beyond the Basics&lt;/li&gt;

&lt;li&gt;🚀 The Release Pipeline&lt;/li&gt;

&lt;li&gt;📊 Dependency Philosophy&lt;/li&gt;

&lt;li&gt;🏁 Getting Started in 30 Seconds&lt;/li&gt;

&lt;li&gt;🎬 Wrapping Up&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Why Another Boilerplate?
&lt;/h2&gt;

&lt;p&gt;Every new React project starts with the same ritual: configure the bundler, set up linting, add routing, figure out state management, wire up testing... and before you know it, you have spent two days on tooling instead of building features.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate" rel="noopener noreferrer"&gt;react-vite-boilerplate&lt;/a&gt;&lt;/strong&gt; to eliminate that friction. It is not a minimal starter — it is an &lt;strong&gt;opinionated, production-ready foundation&lt;/strong&gt; that codifies hard-won architectural decisions so you can ship from day one.&lt;/p&gt;

&lt;p&gt;In this post, I will walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The architecture&lt;/strong&gt; and how each layer connects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why&lt;/strong&gt; each dependency was chosen (and what alternatives were rejected)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The developer experience&lt;/strong&gt; toolchain that keeps the codebase healthy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The testing strategy&lt;/strong&gt; that spans unit, component, and E2E layers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The release pipeline&lt;/strong&gt; with automated versioning and npm publishing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏗️ High-Level Architecture
&lt;/h2&gt;

&lt;p&gt;The boilerplate follows a clear &lt;strong&gt;layered architecture&lt;/strong&gt; where each tier has a single, well-defined responsibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────┐
│              UI Layer                           │
│   React Components · Shadcn UI · Tailwind CSS   │
│   Storybook (component workshop)                │
├─────────────────────────────────────────────────┤
│              Routing Layer                      │
│   TanStack Router (file-based, fully typesafe)  │
├────────────────────┬────────────────────────────┤
│  Server State      │  Client State              │
│  TanStack Query    │  Zustand                   │
├────────────────────┴────────────────────────────┤
│              API Layer                          │
│   ky HTTP client · ApiService class             │
├─────────────────────────────────────────────────┤
│              Mock Layer                         │
│   MSW (Mock Service Worker)                     │
└─────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fw251zrtsopqvd5880wso.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%2Fw251zrtsopqvd5880wso.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why layers?&lt;/strong&gt; Each layer can be understood, tested, and replaced independently. Swap Zustand for Jotai? Only the client state layer changes. Switch from ky to axios? Only the API layer is affected.&lt;/p&gt;


&lt;h2&gt;
  
  
  📁 Project Structure — Organized for Scale
&lt;/h2&gt;

&lt;p&gt;The folder structure is intentionally &lt;strong&gt;feature-oriented&lt;/strong&gt; at the top level yet &lt;strong&gt;technically separated&lt;/strong&gt; within each feature:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── app/           # App shell: providers, router, auth context
├── api/           # Service classes + React Query hooks per domain
│   ├── apiService.ts   # Base HTTP client (ky wrapper)
│   ├── auth/           # Auth-specific API logic
│   ├── posts/          # Posts domain: service + hooks + types
│   └── user/           # User domain
├── components/    # Shared components
│   ├── ui/           # Shadcn UI primitives (Button, Toast, etc.)
│   ├── layout/       # Navbar, Footer, Sidebar
│   ├── forms/        # Form components with React Hook Form
│   └── hooks/        # Shared custom hooks
├── config/        # App configuration constants
├── mocker/        # MSW handlers and server setup
├── modules/       # Cross-cutting modules
│   └── i18n/         # Internationalization (i18next)
├── pages/         # Page-level components
│   ├── Home/
│   ├── Auth/
│   └── App/
├── routes/        # TanStack Router file-based route definitions
├── store/         # Zustand store with slices + middlewares
├── tests/         # Test utilities, setup, and wrappers
├── types/         # Global TypeScript type definitions
└── utils/         # Pure utility functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key insight&lt;/strong&gt;: The &lt;code&gt;api/&lt;/code&gt; directory co-locates &lt;strong&gt;service classes&lt;/strong&gt;, &lt;strong&gt;React Query hooks&lt;/strong&gt;, and &lt;strong&gt;TypeScript types&lt;/strong&gt; for each domain. This means everything related to "posts" lives in &lt;code&gt;api/posts/&lt;/code&gt; — making it trivial to find, modify, or delete an entire feature.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  ⚡ The Foundation: Vite + React + TypeScript
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why Vite?
&lt;/h3&gt;

&lt;p&gt;Vite is the &lt;strong&gt;fastest development server&lt;/strong&gt; in the React ecosystem. But we go further with a carefully tuned &lt;code&gt;vite.config.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;mode&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;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loadEnv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/env&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;isDevMode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;development&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;plugins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;svgr&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;                    &lt;span class="c1"&gt;// Import SVGs as React components&lt;/span&gt;
    &lt;span class="nc"&gt;TanStackRouterVite&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;      &lt;span class="c1"&gt;// Auto-generate route tree&lt;/span&gt;
    &lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;                   &lt;span class="c1"&gt;// React Fast Refresh&lt;/span&gt;
    &lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;                 &lt;span class="c1"&gt;// Vite plugin inspector (dev)&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="c1"&gt;// Conditional dev-time checks&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;isDevMode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;plugins&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="nf"&gt;checker&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;typescript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shouldCheckTypeScriptDev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;eslint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;shouldCheckESLintDev&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Bundle analysis on demand&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ANALYZE&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;true&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;plugins&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="nf"&gt;visualizer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;treemap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;What makes this special:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plugin&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vite-plugin-svgr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Import &lt;code&gt;.svg&lt;/code&gt; files as React components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;@tanstack/router-plugin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-generates the route tree from the file system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vite-plugin-checker&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;TypeScript + ESLint checks &lt;strong&gt;during dev&lt;/strong&gt; (configurable via env vars)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vite-plugin-inspect&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect Vite internals — useful for debugging transform pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rollup-plugin-visualizer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;On-demand bundle analysis with treemap, gzip, and brotli sizes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Pro tip&lt;/strong&gt;: The TypeScript and ESLint dev checks are &lt;strong&gt;toggleable via environment variables&lt;/strong&gt; (&lt;code&gt;VITE_TSC_DEV_CHECK&lt;/code&gt;, &lt;code&gt;VITE_ESLINT_DEV_CHECK&lt;/code&gt;). This lets you disable them when iterating quickly and re-enable for pre-commit validation.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  🧭 Routing: TanStack Router
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why TanStack Router over React Router?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Full type safety.&lt;/strong&gt; TanStack Router is the only React router that provides &lt;strong&gt;end-to-end TypeScript inference&lt;/strong&gt; — from route params, to search params, to loader data, to the &lt;code&gt;context&lt;/code&gt; object.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/app.tsx — Protected route with type-safe context&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createFileRoute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt;
  &lt;span class="na"&gt;beforeLoad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// context.auth is fully typed as TAuthStoreState | null&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;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/auth/login&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AppLayout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://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%2Fbfqjveqzymi1k2ea691g.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%2Fbfqjveqzymi1k2ea691g.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File-based routing&lt;/strong&gt; means the route hierarchy mirrors the file system:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;routes/
├── __root.tsx      → Root layout (devtools, document title)
├── index.tsx       → "/"  (landing page)
├── app.tsx         → "/app" (protected layout)
├── app/
│   └── ...         → "/app/*" child routes
├── auth.tsx        → "/auth" (guest-only layout)
└── auth/
    └── login.tsx   → "/auth/login"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The router is configured to work seamlessly with &lt;strong&gt;React Query&lt;/strong&gt; by sharing the &lt;code&gt;queryClient&lt;/code&gt; via context:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;routeTree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queryClient&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;defaultPreload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;intent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;defaultPreloadStaleTime&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;// Always re-fetch on preload&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;defaultPreloadStaleTime: 0&lt;/code&gt;?&lt;/strong&gt; Since React Query manages caching, we want the router to always invoke the loader so React Query can decide whether to serve from cache or refetch. This gives us a &lt;strong&gt;single source of truth&lt;/strong&gt; for cache policy.&lt;/p&gt;


&lt;h2&gt;
  
  
  🗄️ State Management: The Two-Store Strategy
&lt;/h2&gt;

&lt;p&gt;State management is where most boilerplates get it wrong by choosing a single solution for everything. This boilerplate makes a deliberate split:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────┐
│           State Management Strategy          │
├──────────────────────┬───────────────────────┤
│   Server State       │   Client State        │
│   TanStack Query     │   Zustand             │
│                      │                       │
│   • API responses    │   • Auth state        │
│   • Caching          │   • UI preferences    │
│   • Refetching       │   • Session data      │
│   • Pagination       │   • Form state        │
│   • Optimistic       │   • Theme             │
│     updates          │                       │
└──────────────────────┴───────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fp02l35dizll0np18apye.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%2Fp02l35dizll0np18apye.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  TanStack Query — Server State
&lt;/h3&gt;

&lt;p&gt;Server state is data that lives on the server and is &lt;strong&gt;temporarily borrowed&lt;/strong&gt; by the client. React Query handles caching, background refetching, stale-while-revalidate, pagination, and more.&lt;/p&gt;

&lt;p&gt;Here is how we structure API queries:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// api/posts/posts.hooks.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useGetPostsQuery&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UseQueryOptions&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TGetPostsResponsePayload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TApiServiceError&lt;/span&gt;&lt;span class="o"&gt;&amp;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;queryKey&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;queryFn&lt;/span&gt;&lt;span class="dl"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;useQuery&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;queryKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;GET_POSTS_QUERY_KEY&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;queryFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;postsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPosts&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why wrap &lt;code&gt;useQuery&lt;/code&gt; in custom hooks?&lt;/strong&gt; Encapsulation. The consuming component does not need to know the query key, the service method, or how to handle errors — it just calls &lt;code&gt;useGetPostsQuery()&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Zustand — Client State
&lt;/h3&gt;

&lt;p&gt;For client-only state (auth, theme, UI preferences), Zustand provides a lightweight, boilerplate-free solution:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// store/store.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useStoreBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TStore&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;()(&lt;/span&gt;
  &lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                      &lt;span class="c1"&gt;// Custom logging middleware&lt;/span&gt;
    &lt;span class="nf"&gt;devtools&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;                  &lt;span class="c1"&gt;// Redux DevTools integration&lt;/span&gt;
      &lt;span class="nf"&gt;subscribeWithSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="c1"&gt;// Fine-grained subscriptions&lt;/span&gt;
        &lt;span class="nf"&gt;persist&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;       &lt;span class="c1"&gt;// Session storage persistence&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;STORE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;createJSONStorage&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;STORE_VERSION&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;migrate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;persistedState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prevVersion&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Handle breaking changes gracefully&lt;/span&gt;
          &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isDebugMode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;STORE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;isDebugMode&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The middleware stack tells a story:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;persist&lt;/code&gt;&lt;/strong&gt; — Survives page refreshes via &lt;code&gt;sessionStorage&lt;/code&gt; with versioned migrations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;subscribeWithSelector&lt;/code&gt;&lt;/strong&gt; — Components re-render only when &lt;em&gt;their specific slice&lt;/em&gt; changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;devtools&lt;/code&gt;&lt;/strong&gt; — Time-travel debugging in Redux DevTools (only in dev)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;logger&lt;/code&gt;&lt;/strong&gt; — Custom middleware that logs state transitions with styled console output&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;
  
  
  Auto-Generated Selectors
&lt;/h4&gt;

&lt;p&gt;Instead of writing selectors by hand, the &lt;code&gt;createSelectors&lt;/code&gt; utility generates them automatically:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Instead of:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useStore&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// You write:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This is powered by a small but elegant utility:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createSelectors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;S&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;UseBoundStore&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StoreApi&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;S&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;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;_store&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;TWithSelectors&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="o"&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;const&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="k"&gt;of&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;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getState&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;use&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="nx"&gt;k&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌐 API Layer: ky + ApiService Pattern
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why ky over Axios or fetch?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;axios&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;ky&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bundle size&lt;/td&gt;
&lt;td&gt;0 KB&lt;/td&gt;
&lt;td&gt;~13 KB&lt;/td&gt;
&lt;td&gt;~3 KB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry logic&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hook system&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Interceptors&lt;/td&gt;
&lt;td&gt;Hooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON parsing&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;ky&lt;/strong&gt; gives us the best of both worlds: a tiny bundle with powerful features like hooks, timeout, and retry — without the overhead of axios.&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%2Fe0cntsy0vzby4n4p869k.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%2Fe0cntsy0vzby4n4p869k.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The ApiService abstraction
&lt;/h3&gt;

&lt;p&gt;Rather than coupling &lt;code&gt;ky&lt;/code&gt; throughout the app, we wrap it in a class that implements a generic &lt;code&gt;THttpService&lt;/code&gt; interface:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;THttpService&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&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;post&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&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;put&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;B&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApiService&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;THttpService&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Options&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Options&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;kyInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ky&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="na"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;beforeRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Accept-Language&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentLanguage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}],&lt;/span&gt;
        &lt;span class="na"&gt;beforeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// Translate HTTP error codes to i18n messages&lt;/span&gt;
          &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;t&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;errors:http.status&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;errors:http.unknown&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;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;});&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}],&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;prefixUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;apiURL&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="na"&gt;retry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why this pattern?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Swap-ability&lt;/strong&gt;: Replacing &lt;code&gt;ky&lt;/code&gt; with &lt;code&gt;axios&lt;/code&gt; or &lt;code&gt;fetch&lt;/code&gt; requires changing only &lt;code&gt;ApiService&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-cutting concerns&lt;/strong&gt;: Language headers, error translations, and auth tokens are configured once&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testability&lt;/strong&gt;: Mock the &lt;code&gt;ApiService&lt;/code&gt; in tests without mocking HTTP internals&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🎭 API Mocking: MSW
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mock Service Worker&lt;/strong&gt; is the unsung hero of this boilerplate. It intercepts HTTP requests at the &lt;strong&gt;network level&lt;/strong&gt;, meaning your application code does not know (or care) whether it is talking to a real API or a mock.&lt;/p&gt;


  



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// mocker/server.ts&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setupWorker&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;runServer&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;onUnhandledRequest&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bypass&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;serviceWorkerUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;appBasePath&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why MSW over JSON server or local Express?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works in the &lt;strong&gt;browser&lt;/strong&gt; (dev) and in &lt;strong&gt;Node&lt;/strong&gt; (unit tests) with the same handlers&lt;/li&gt;
&lt;li&gt;No separate process to start — it runs alongside your app&lt;/li&gt;
&lt;li&gt;Handlers are strongly typed and co-located with API code&lt;/li&gt;
&lt;li&gt;E2E tests can override individual handlers for edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In &lt;code&gt;main.tsx&lt;/code&gt;, the MSW server starts &lt;strong&gt;before React renders&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setupApp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&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;mocker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./mocker/index.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mocker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;runServer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;setupApp&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StrictMode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StrictMode&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌍 Internationalization: i18next
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;I18n&lt;/code&gt; class wraps &lt;code&gt;i18next&lt;/code&gt; with a clean, testable API:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;I18n&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;initOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="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;i18nInstance&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;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initReactI18next&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;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withLanguageDetector&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;i18nInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;LanguageDetector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Dynamic imports for locale files via Vite glob&lt;/span&gt;
    &lt;span class="nx"&gt;i18nInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&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="s2"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;language&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&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;modules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./locales/*/*.json&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`./locales/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;language&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;namespace&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.json`&lt;/span&gt;&lt;span class="p"&gt;]();&lt;/span&gt;
        &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Key design decisions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vite &lt;code&gt;import.meta.glob&lt;/code&gt;&lt;/strong&gt; for lazy-loading locale files — only the active language is loaded&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom formatters&lt;/strong&gt; (&lt;code&gt;uppercase&lt;/code&gt;, &lt;code&gt;lowercase&lt;/code&gt;) registered at init time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser language detection&lt;/strong&gt; with localStorage caching and graceful fallback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Namespace-based organization&lt;/strong&gt; — separate &lt;code&gt;common.json&lt;/code&gt;, &lt;code&gt;errors.json&lt;/code&gt;, &lt;code&gt;auth.json&lt;/code&gt; per language&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type-safe translations&lt;/strong&gt; via &lt;code&gt;i18next.d.ts&lt;/code&gt; declarations&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🧪 Testing Strategy: The Full Pyramid
&lt;/h2&gt;

&lt;p&gt;The boilerplate implements a &lt;strong&gt;complete testing pyramid&lt;/strong&gt; with MSW as the mocking backbone across all layers:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          ╱╲
         ╱  ╲
        ╱ E2E╲         Cypress
       ╱──────╲
      ╱Component╲      Storybook + Vitest Browser Mode
     ╱────────────╲
    ╱  Unit Tests   ╲   Vitest + React Testing Library
   ╱──────────────────╲
  ╱   MSW (all layers)  ╲
 └───────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fy5uhsf58m4uht1r4e6tu.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%2Fy5uhsf58m4uht1r4e6tu.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Unit Tests: Vitest + React Testing Library
&lt;/h3&gt;

&lt;p&gt;Vitest shares Vite's config and transformation pipeline, which means &lt;strong&gt;zero config drift&lt;/strong&gt; between dev and test environments:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vitest.config.ts (simplified)&lt;/span&gt;
&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;jsdom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;setupFiles&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;./tests/setup.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;typecheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;enabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;  &lt;span class="c1"&gt;// Test your types too!&lt;/span&gt;
  &lt;span class="nx"&gt;mockReset&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="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;v8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;reporter&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;html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The test wrapper&lt;/strong&gt; is designed for maximum realism:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Wrapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PropsWithChildren&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TWrapperProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;withToaster&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;withRouter&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="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="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TProvider&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="nx"&gt;providers&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="na"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ThemeProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;withRouter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Sets up a real TanStack Router instance for each test&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRootRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Outlet&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;indexRoute&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRoute&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="cm"&gt;/* ... */&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;providers&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="na"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;RouterProvider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;router&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="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;addProviders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providers&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;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Component Tests: Storybook + Vitest Browser
&lt;/h3&gt;

&lt;p&gt;Storybook is not just for documentation — it is a &lt;strong&gt;testing runtime&lt;/strong&gt;. The boilerplate uses &lt;code&gt;@storybook/addon-vitest&lt;/code&gt; to run story-based tests in a real browser via Playwright:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// vitest.config.ts — storybook project&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;storybookTest&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;configDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.storybook&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;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;storybook&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;enabled&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="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;playwright&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nx"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chromium&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Accessibility is enforced&lt;/strong&gt;: The &lt;code&gt;@storybook/addon-a11y&lt;/code&gt; plugin runs &lt;strong&gt;axe-core checks&lt;/strong&gt; on every story, configured to &lt;strong&gt;fail on violations&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  E2E Tests: Cypress
&lt;/h3&gt;

&lt;p&gt;For full user-journey validation:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test&lt;/span&gt;:e2e          &lt;span class="c"&gt;# Interactive mode&lt;/span&gt;
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:e2e:headless &lt;span class="c"&gt;# CI mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Cypress tests live in &lt;code&gt;cypress/specs/&lt;/code&gt; and use custom ESLint rules to enforce best practices like &lt;code&gt;data-*&lt;/code&gt; selectors and assertion-before-screenshot.&lt;/p&gt;


  



&lt;h2&gt;
  
  
  🎨 UI Layer: Shadcn UI + Tailwind CSS
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why Shadcn UI?
&lt;/h3&gt;

&lt;p&gt;Shadcn is &lt;strong&gt;not a component library&lt;/strong&gt; — it is a collection of &lt;strong&gt;copy-paste components&lt;/strong&gt; built on Radix UI primitives. You own the code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;components/ui/
├── Button/          # Button with variants via CVA
├── Toast/           # Toast notifications (Radix)
├── DropdownMenu/    # Dropdown with keyboard nav
├── Tooltip/         # Accessible tooltips
├── ThemeToggler/    # Dark/light mode switch
├── LangToggler/     # Language switcher
├── Typography/      # Consistent text styles
├── Brand/           # Logo and branding
└── RouteLink/       # Type-safe navigation link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Why this over Material UI or Ant Design?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero runtime overhead&lt;/strong&gt; — it is just your code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full customization&lt;/strong&gt; — no fighting framework CSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Radix primitives&lt;/strong&gt; — best-in-class accessibility (WAI-ARIA)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CVA (Class Variance Authority)&lt;/strong&gt; — Type-safe component variants&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🔧 Developer Experience (DX) Toolchain
&lt;/h2&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%2Ff3ed84bsy2nis4pwal75.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%2Ff3ed84bsy2nis4pwal75.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DX pipeline ensures quality at every stage:&lt;/p&gt;
&lt;h3&gt;
  
  
  Code → Lint → Format → Commit
&lt;/h3&gt;


  



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; Developer writes code
         │
    ┌────▼────┐
    │  ESLint │  Static analysis with 8 plugins
    └────┬────┘   (react, hooks, refresh, cypress,
         │        storybook, testing-library, typescript)
    ┌────▼──────┐
    │  Prettier │  Opinionated formatting with
    └────┬──────┘   import sorting + Tailwind ordering
         │
    ┌────▼──────────┐
    │  lint-staged  │  Only processes staged files
    └────┬──────────┘
         │
    ┌────▼──────────┐
    │  Commitizen   │  Conventional commit messages
    └────┬──────────┘
         │
    ┌────▼──────┐
    │  Devmoji  │  Automatic emoji decoration ✨
    └────┬──────┘
         │
    ┌────▼──────┐
    │   Husky   │  Git hooks orchestration
    └───────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  ESLint: Context-Aware Rules
&lt;/h3&gt;

&lt;p&gt;The ESLint config uses &lt;strong&gt;flat config&lt;/strong&gt; with context-aware rule sets:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;tseslint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// Base: TypeScript recommended + stylistic&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;tseslint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recommendedTypeChecked&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="c1"&gt;// Stories: Storybook-specific rules&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;files&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;**/*.stories.{ts,tsx}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;storybook&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flat/recommended&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="c1"&gt;// Tests: Testing Library rules&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;files&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;**/*.{spec,test}.{ts,tsx}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;testingLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flat/react&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="c1"&gt;// E2E: Cypress rules&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;files&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;cypress/**/*&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cypress&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recommended&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Naming conventions are enforced at the type level:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// All type aliases must start with "T"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@typescript-eslint/naming-convention&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&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;selector&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;typeAlias&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;format&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;PascalCase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;custom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;^T[A-Z]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛠️ DevTools: Development-Only by Design
&lt;/h2&gt;


  


&lt;p&gt;The boilerplate ships with three sets of devtools that are &lt;strong&gt;automatically tree-shaken in production&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// components/developmentTools.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TanStackRouterDevelopmentTools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isDevelopment&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;  &lt;span class="c1"&gt;// No-op in production&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tanstack/router-devtools&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TanStackRouterDevtools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}))&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check &lt;code&gt;isDevelopment&lt;/code&gt; at module scope&lt;/li&gt;
&lt;li&gt;In production: export a component that returns &lt;code&gt;null&lt;/code&gt; (zero bundle cost)&lt;/li&gt;
&lt;li&gt;In development: &lt;code&gt;React.lazy()&lt;/code&gt; for code-split loading&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means &lt;strong&gt;devtools are never included in your production bundle&lt;/strong&gt; — not even as dead code.&lt;/p&gt;


&lt;h2&gt;
  
  
  🔒 TypeScript: Beyond the Basics
&lt;/h2&gt;

&lt;p&gt;The boilerplate includes a set of &lt;strong&gt;global utility types&lt;/strong&gt; that solve real problems:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Deeply partial types (useful for Zustand store updates)&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;RecursivePartial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]?:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nf"&gt;extends &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;U&lt;/span&gt;&lt;span class="p"&gt;)[]&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;RecursivePartial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;U&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;RecursivePartial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&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;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Type-safe value extraction from const objects&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ValueOf&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="c1"&gt;// const THEME = { LIGHT: "light", DARK: "dark" } as const;&lt;/span&gt;
&lt;span class="c1"&gt;// type TTheme = ValueOf&amp;lt;typeof THEME&amp;gt;; // "light" | "dark"&lt;/span&gt;

&lt;span class="c1"&gt;// String manipulation at the type level&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ReplaceFirst&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;TString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TToReplace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TReplacement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="nx"&gt;TString&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;TToReplace&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt; &lt;span class="nx"&gt;S&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;TReplacement&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;S&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="nx"&gt;TString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Type testing&lt;/strong&gt; is first-class — all &lt;code&gt;*.test-d.ts&lt;/code&gt; files are automatically discovered and validated by Vitest.&lt;/p&gt;


&lt;h2&gt;
  
  
  🚀 The Release Pipeline
&lt;/h2&gt;

&lt;p&gt;The boilerplate includes a &lt;strong&gt;complete automated release system&lt;/strong&gt; powered by Changesets + GitHub Actions:&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%2F1jdbwoq43eeo16nwm8ei.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%2F1jdbwoq43eeo16nwm8ei.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature Branch ──► PR to main ──► Merge
                                    │
                         ┌──────────▼──────────┐
                         │   release.yml runs  │
                         │   lint → typecheck  │
                         │   → test → publish  |
                         └──────────┬──────────┘
                                    │
                   ┌────────────────▼────────────────┐
                   │     Release PR created          │
                   │  version bump + changelog       │
                   └────────────────┬────────────────┘
                                    │
                             Merge Release PR
                                    │
                         ┌──────────▼──────────┐
                         │  npm publish        │
                         │  + GitHub Release   │
                         └─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The published CLI package &lt;code&gt;@singhamandeep/crvb&lt;/code&gt; lets anyone scaffold a new project:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @singhamandeep/crvb@latest my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📊 Dependency Philosophy
&lt;/h2&gt;

&lt;p&gt;Every dependency was chosen based on three criteria:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Necessity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Does this solve a real problem that would require significant custom code?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Quality&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is this actively maintained, well-tested, and has a healthy community?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Is this the smallest possible solution that meets our needs?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Why This Over Alternatives&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bundler&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10-100x faster than Webpack; native ESM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Router&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TanStack Router&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Only fully type-safe React router&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server State&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TanStack Query&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Best caching + devtools; de facto standard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Client State&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Zustand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~1KB; no boilerplate; middleware-composable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Client&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ky&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~3KB fetch wrapper with hooks and retry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forms&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;React Hook Form + Zod&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Uncontrolled perf; schema-first validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shadcn + Radix&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You own the code; best a11y primitives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Tailwind CSS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Utility-first; no CSS-in-JS runtime cost&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;i18n&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;i18next&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Most mature; plugin ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Utilities&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Radash&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modern lodash; tree-shakeable; zero deps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Date&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;date-fns&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Modular; tree-shakeable; immutable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API Mocking&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MSW&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Network-level; browser + Node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unit Test&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Vitest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vite-native; Jest-compatible API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;E2E Test&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Cypress&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Best DX for E2E; time-travel debugging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Components&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Storybook&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Industry standard; visual testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  🏁 Getting Started in 30 Seconds
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Option 1: Scaffold via CLI&lt;/span&gt;
npx @singhamandeep/crvb@latest my-app
&lt;span class="nb"&gt;cd &lt;/span&gt;my-app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev

&lt;span class="c"&gt;# Option 2: Clone directly&lt;/span&gt;
git clone https://github.com/singhAmandeep007/react-vite-boilerplate.git
&lt;span class="nb"&gt;cd &lt;/span&gt;react-vite-boilerplate
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run prepare &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



  



&lt;h2&gt;
  
  
  🎬 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;This boilerplate is the result of years of iterating on production React applications. Every choice — from the middleware stack in Zustand to the ESLint naming conventions — was battle-tested in real projects before making it into the template.&lt;/p&gt;

&lt;p&gt;The goal is not to provide &lt;em&gt;every&lt;/em&gt; feature, but to provide the &lt;strong&gt;right foundation&lt;/strong&gt; that scales from a side project to a production application without requiring an architectural rewrite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Star the repo&lt;/strong&gt; if you found this useful: &lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate" rel="noopener noreferrer"&gt;⭐ react-vite-boilerplate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scaffold your next project:&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;npx @singhamandeep/crvb@latest my-next-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Have questions or suggestions? Open an issue or drop a comment below — I would love to hear how you are using it! 🚀&lt;/p&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/singhAmandeep007" rel="noopener noreferrer"&gt;
        singhAmandeep007
      &lt;/a&gt; / &lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate" rel="noopener noreferrer"&gt;
        react-vite-boilerplate
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Delightful boilerplate for starting your awesome react + vite application.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;React Vite Boilerplate&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/public/react-vite-boilerplate.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fpublic%2Freact-vite-boilerplate.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything you need to start with your next Vite + React web app! Delighful developer experience with batteries included.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Demo&lt;/h2&gt;
&lt;/div&gt;


  
    

    &lt;span class="m-1"&gt;react-vite-boilerplate.webm&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;a href="https://dev.to/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh" rel="nofollow"&gt;Technical Blog&lt;/a&gt;&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#overview" rel="noopener noreferrer"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#requirements" rel="noopener noreferrer"&gt;Requirements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#getting-started" rel="noopener noreferrer"&gt;Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#scaffold-via-npx" rel="noopener noreferrer"&gt;Scaffold via npx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#scripts" rel="noopener noreferrer"&gt;Scripts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#open-source-setup" rel="noopener noreferrer"&gt;Open Source Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#publishing-and-releases" rel="noopener noreferrer"&gt;Publishing and Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#release-system-diagram" rel="noopener noreferrer"&gt;Release System Diagram&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#versioning-guide" rel="noopener noreferrer"&gt;Versioning Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#owner-release-checklist" rel="noopener noreferrer"&gt;Owner Release Checklist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#complete-owner-example" rel="noopener noreferrer"&gt;Complete Owner Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#important-note" rel="noopener noreferrer"&gt;Important Note&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#testing" rel="noopener noreferrer"&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#deployment" rel="noopener noreferrer"&gt;Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#devtools" rel="noopener noreferrer"&gt;DevTools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#installed-packages" rel="noopener noreferrer"&gt;Installed Packages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Overview&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Built with type safety, scalability, and developer experience in mind. A batteries included Vite + React template.&lt;/p&gt;

&lt;p&gt;A more detailed list of the included packages can be found in the &lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate#installed-packages" rel="noopener noreferrer"&gt;Installed Packages&lt;/a&gt; section.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nodejs.org/en" rel="nofollow noopener noreferrer"&gt;NodeJS 24.x&lt;/a&gt; (see &lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate/.nvmrc" rel="noopener noreferrer"&gt;.nvmrc&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com" rel="nofollow noopener noreferrer"&gt;npm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Getting Started&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Getting started is a simple as cloning the repository&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;git clone https://github.com/singhAmandeep007/react-vite-boilerplate.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Changing into the new directory&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;cd react-vite-boilerplate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Removing the .git folder (and any additional files, folders or dependencies you may not need)&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;rm -rf .git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Installing dependencies&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And running the setup script…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/singhAmandeep007/react-vite-boilerplate" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Happy coding!&lt;/em&gt; ✨&lt;/p&gt;

</description>
      <category>react</category>
      <category>typescript</category>
      <category>vite</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hey devs, checkout my article on building a production ready react + vite application using an awesome boilerplate. 🚀</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Thu, 11 Sep 2025 14:51:52 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/hey-devs-checkout-my-article-on-building-a-production-ready-react-vite-application-using-an-2n6k</link>
      <guid>https://forem.com/singhamandeep007/hey-devs-checkout-my-article-on-building-a-production-ready-react-vite-application-using-an-2n6k</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh" class="crayons-story__hidden-navigation-link"&gt;Building a Production Ready React Vite TypeScript Boilerplate&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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" alt="singhamandeep007 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/singhamandeep007" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Amandeep Singh
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Amandeep Singh
                
              
              &lt;div id="story-author-preview-content-2120210" 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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Amandeep Singh&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Nov 25 '24&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh" id="article-link-2120210"&gt;
          Building a Production Ready React Vite TypeScript Boilerplate
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/vite"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;vite&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh" 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/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&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;27&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/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh#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>react</category>
      <category>vite</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Hey devs, checkout my new article on hosting your own n8n server for free, this can save you a lot of $$$. Try it out. 🙂</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Thu, 11 Sep 2025 14:44:49 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/hey-devs-checkout-my-new-article-on-hosting-your-own-n8n-server-for-free-this-can-save-you-a-lot-38d1</link>
      <guid>https://forem.com/singhamandeep007/hey-devs-checkout-my-new-article-on-hosting-your-own-n8n-server-for-free-this-can-save-you-a-lot-38d1</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69" class="crayons-story__hidden-navigation-link"&gt;The Ultimate Guide to Self-Hosting n8n for Free using Render and Nhost&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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" alt="singhamandeep007 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/singhamandeep007" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Amandeep Singh
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Amandeep Singh
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-2837422" 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="/singhamandeep007" 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%2F392464%2F38017c9b-89f2-42ab-b7d3-41a25728aead.jpeg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Amandeep Singh&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/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Sep 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/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69" id="article-link-2837422"&gt;
          The Ultimate Guide to Self-Hosting n8n for Free using Render and Nhost
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/automation"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;automation&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/tutorial"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;tutorial&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/hosting"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;hosting&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/n8n"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;n8n&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/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69" 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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&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;9&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/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; 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;
            7 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>automation</category>
      <category>tutorial</category>
      <category>hosting</category>
      <category>n8n</category>
    </item>
    <item>
      <title>The Ultimate Guide to Self-Hosting n8n for Free using Render and Nhost</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Wed, 10 Sep 2025 18:03:38 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69</link>
      <guid>https://forem.com/singhamandeep007/the-ultimate-guide-to-self-hosting-n8n-for-free-using-render-and-nhost-2d69</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%2Fa7hmuaticavvkexhl0z5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7hmuaticavvkexhl0z5.gif" alt=" " width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Are you tired of manual, repetitive tasks? Do you wish you had a powerful, open-source automation tool that you could truly own and control?&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%2Flg3t02oc8ykzssj67rmx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg3t02oc8ykzssj67rmx.gif" alt=" " width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then welcome to the world of &lt;strong&gt;n8n&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9bzf8e0zl36x7f403gk.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%2Fk9bzf8e0zl36x7f403gk.png" alt="n8n workflow" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;N8n is a powerful, open-source, and feature-rich workflow automation tool. With its intuitive visual editor and a wide array of over 400 integrations, it's a stellar alternative to SaaS giants like Zapier and Make. But where should you run it? That's the first question on every developer's mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hosting Dilemma
&lt;/h2&gt;

&lt;p&gt;Every journey with n8n begins with a choice: do you opt for the convenience of a managed cloud service or do you take the road of self-hosting? This is the central hosting dilemma.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;n8n Cloud:&lt;/strong&gt; This is the easiest, most hassle-free option for those who want to get started quickly and don't want to worry about server maintenance. Updates, security patches, backups, and scaling are all handled for you. However, n8n's cloud plan can start around $24/month for a limited number of executions, with costs quickly climbing for higher usage, which can be a significant barrier for students and hobbyists.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self-Hosting:&lt;/strong&gt; Self-hosting means you install and run n8n on your own infrastructure, giving you complete control over your data, a key advantage for organizations with strict data privacy requirements. You can easily accomplish this with Docker, which offers portability, reproducibility, and simplified updates. However, this comes with the responsibility of managing the server, including security, backups, and updates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Best of Both Worlds: The Solution:&lt;/strong&gt; This article proposes a middle ground that combines the flexibility and cost-effectiveness of self-hosting with the simplified management of a cloud platform. By using a managed service like Render for application hosting and Nhost for a free PostgreSQL database, you can bypass many of the complexities of traditional self-hosting.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Cloud Hosting Providers Comparison
&lt;/h2&gt;

&lt;p&gt;For those who choose the self-hosting path, selecting the right cloud provider is a critical decision. While a traditional VPS (Virtual Private Server) from a company like DigitalOcean offers a high degree of control, platforms like Render and Railway have emerged as strong contenders with their simplified, managed services.&lt;/p&gt;

&lt;p&gt;Here’s a comparison of these providers to help you decide.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Starting Price&lt;/th&gt;
&lt;th&gt;Specs Included&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Render&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$0/month&lt;/strong&gt; + DB&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.5 vCPU, 512 MB RAM (Web)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Free web service, but &lt;strong&gt;spins down after 15 mins of inactivity&lt;/strong&gt;. The database is a separate, paid service starting at $7/month.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Railway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;$5/month&lt;/strong&gt; (Hobby plan)&lt;/td&gt;
&lt;td&gt;~$5 in usage credit; pay for usage&lt;/td&gt;
&lt;td&gt;Usage-based pricing can be hard to predict but avoids over-provisioning.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DigitalOcean&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;~$6/month&lt;/strong&gt; (Droplet)&lt;/td&gt;
&lt;td&gt;1 vCPU, 2 GB RAM, 25–50 GB SSD&lt;/td&gt;
&lt;td&gt;Polished UI, but requires manual setup and management.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Sliplane&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;€9/month&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2 GB RAM, 2 vCPU, 40 GB SSD&lt;/td&gt;
&lt;td&gt;Offers one-click n8n deployment with backups and HTTPS.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hetzner&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~€3.79/month&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2 vCPU, 4 GB RAM, 40 GB SSD (CX22)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Requires a lot of technical know-how&lt;/strong&gt;. You are responsible for all management, including SSL and backups.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For this tutorial, we will focus on &lt;a href="https://render.com/" rel="noopener noreferrer"&gt;Render&lt;/a&gt; and &lt;a href="https://nhost.io/" rel="noopener noreferrer"&gt;Nhost&lt;/a&gt; because they offer a powerful, zero-cost entry point for a fully functional, self-hosted n8n instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Backend: Why a PostgreSQL Database is a Must
&lt;/h2&gt;

&lt;p&gt;While n8n can function with a default SQLite database, a production-level, self-hosted deployment requires a more robust solution. This is where PostgreSQL comes in as the recommended choice for your backend database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQLite:&lt;/strong&gt; By default, n8n uses SQLite, which is a file-based database. It's excellent for local development and single-user scenarios because of its simplicity. However, it is not designed for concurrent write operations, which makes it unsuitable for a cloud environment where multiple processes might access it at the same time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PostgreSQL:&lt;/strong&gt; Switching to a client-server database like PostgreSQL unlocks a new level of performance, reliability, and scalability.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency and Reliability:&lt;/strong&gt; PostgreSQL is a highly reliable and fault-tolerant database that uses Multi-Version Concurrency Control (MVCC) to handle multiple users accessing data simultaneously without conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; PostgreSQL can handle a significant quantity of data and a large number of concurrent users, making it ideal for growing applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Integrity and Security:&lt;/strong&gt; PostgreSQL is ACID-compliant (Atomicity, Consistency, Isolation, and Durability), which ensures that database transactions are processed reliably and data integrity is maintained.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Managed Services:&lt;/strong&gt; By using a managed PostgreSQL service like Nhost, you are freed from the burden of database administration, including tasks like optimization and backup management.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Deployment Guide
&lt;/h2&gt;

&lt;p&gt;This tutorial will walk you through the step-by-step process of deploying your own self-hosted n8n instance on Render, using a managed PostgreSQL database from Nhost.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Set Up Your Nhost Database
&lt;/h3&gt;

&lt;p&gt;First, you need to set up your database on &lt;a href="https://nhost.io/" rel="noopener noreferrer"&gt;Nhost&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Sign up and Create a Project:&lt;/strong&gt; Sign up for &lt;a href="https://app.nhost.io/signup" rel="noopener noreferrer"&gt;Nhost&lt;/a&gt; using your GitHub account or email. Once in the dashboard, click "Create Project" and give it a name.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Configure Database and Get Credentials:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to your project's settings, then go to the "Database" section.&lt;/li&gt;
&lt;li&gt;Here you need to enable Public access to Connect directly to the Postgres database.&lt;/li&gt;
&lt;li&gt;Here, you will find the connection information for your PostgreSQL database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crucial Step:&lt;/strong&gt; Note down all the individual components from the connection string: the host, port, user, password, and database name. You will need to parse the single &lt;code&gt;DATABASE_URL&lt;/code&gt; into these separate environment variables for Render.&lt;/li&gt;
&lt;li&gt;Change the password for your database and save it securely.&lt;/li&gt;
&lt;/ul&gt;
&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%2Fdr6af664ms49w2izporb.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%2Fdr6af664ms49w2izporb.png" alt="Nhost database credentials screen" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy n8n on &lt;a href="https://render.com/" rel="noopener noreferrer"&gt;Render&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Next, you will deploy the n8n application to Render, connecting it to your Nhost database.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sign Up for &lt;a href="https://dashboard.render.com/register" rel="noopener noreferrer"&gt;Render&lt;/a&gt;:&lt;/strong&gt; If you don't have an account, sign up for Render.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a New Web Service:&lt;/strong&gt; From the Render dashboard, click "+ New" and select "Web Service".&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%2F71gmetbk1woz6cowpnir.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%2F71gmetbk1woz6cowpnir.png" alt="Render dashboard with 'New Web Service' selected" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose the Docker Image:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Under "Source," select "Existing Image".&lt;/li&gt;
&lt;li&gt;In the "Image URL" field, enter &lt;code&gt;n8nio/n8n:latest&lt;/code&gt; and click "Connect". This will use the official &lt;a href="https://hub.docker.com/r/n8nio/n8n" rel="noopener noreferrer"&gt;n8n Docker image&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Give your service a name, choose a region closest to you, and select the "Free" instance type.&lt;/li&gt;
&lt;/ul&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%2Functrnz82og0jbk6zuyd.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%2Functrnz82og0jbk6zuyd.png" alt="Image n8n docker" width="800" height="268"&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%2Fcqqwh77541xh9z2d6feu.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%2Fcqqwh77541xh9z2d6feu.png" alt="Render configuration screen for a new web service" width="800" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add Environment Variables:&lt;/strong&gt; This is the most important step for connecting your n8n app to the Nhost database and configuring it properly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expand the "Advanced" section and add the following environment variables.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DB_TYPE&lt;/code&gt;: &lt;code&gt;postgresdb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DB_POSTGRESDB_DATABASE&lt;/code&gt;: &lt;code&gt;&amp;lt;nhost database name&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DB_POSTGRESDB_HOST&lt;/code&gt;: &lt;code&gt;&amp;lt;nhost postgres host&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DB_POSTGRESDB_PASSWORD&lt;/code&gt;: &lt;code&gt;&amp;lt;nhost postgres password&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DB_POSTGRESDB_PORT&lt;/code&gt;: &lt;code&gt;5432&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DB_POSTGRESDB_USER&lt;/code&gt;: &lt;code&gt;postgres&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DATABASE_URL&lt;/code&gt;: &lt;code&gt;&amp;lt;nhost connection string&amp;gt;&lt;/code&gt; + &lt;code&gt;?sslmode=require&lt;/code&gt;. E.g. &lt;code&gt;postgres://postgres:&amp;lt;password&amp;gt;@&amp;lt;host&amp;gt;:&amp;lt;port&amp;gt;/&amp;lt;name&amp;gt;?sslmode=require&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GENERIC_TIMEZONE&lt;/code&gt;: &lt;code&gt;America/New_York&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_ENCRYPTION_KEY&lt;/code&gt;: &lt;code&gt;LTZl8zNn721OB3x73nGS1QNKu9mXoqblHw0LFr9ifq4=&lt;/code&gt; (This is a unique key for encrypting credentials in your database. &lt;strong&gt;For security, you must generate your own!&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_HOST&lt;/code&gt;: This will be the URL that Render assigns to your service. You will add this after the first deployment. E.g. &lt;code&gt;self-hosted-n8n.onrender.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_PORT&lt;/code&gt;: &lt;code&gt;5678&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_PROTOCOL&lt;/code&gt;: &lt;code&gt;https&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WEBHOOK_URL&lt;/code&gt;: &lt;code&gt;&amp;lt;render web service URL&amp;gt;&lt;/code&gt; This will also be the Render URL, added after the first deployment. E.g. &lt;code&gt;https://self-hosted-n8n.onrender.com/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TZ&lt;/code&gt;: &lt;code&gt;America/New_York&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NODE_ENV&lt;/code&gt;: &lt;code&gt;production&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_RUNNERS_ENABLED&lt;/code&gt;: &lt;code&gt;true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_PAYLOAD_SIZE_MAX&lt;/code&gt;: &lt;code&gt;16&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_LOG_LEVEL&lt;/code&gt;: &lt;code&gt;info&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS&lt;/code&gt;: &lt;code&gt;false&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Frtwcs6hdl50e31x2sxgd.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%2Frtwcs6hdl50e31x2sxgd.png" alt=" " width="800" height="823"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial Deployment:&lt;/strong&gt; Click "Create Web Service" to start the deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Final Configuration and Verification
&lt;/h3&gt;

&lt;p&gt;After the initial deployment, you need to update the two environment variables and verify everything is working.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Update URLs:&lt;/strong&gt; Once your service is live, Render will provide a public URL (e.g., &lt;code&gt;self-hosted-n8n.onrender.com&lt;/code&gt;). Go to your service's settings, then "Environment," and click "Edit". Replace the placeholder values for &lt;code&gt;N8N_HOST&lt;/code&gt; with your new Render URL and &lt;code&gt;WEBHOOK_URL&lt;/code&gt; with your Render URL including &lt;code&gt;https://&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Check Logs:&lt;/strong&gt; After the redeployment, check the logs on the Render dashboard. A successful deployment will show lines like "Starting migration," "Finished migration," and "n8n ready on ::, port 5678".&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Verify Functionality:&lt;/strong&gt; Visit the Render URL to access your n8n instance and create your first user account. Your cloud-hosted n8n is now ready to use, and all your workflows and data will be persisted in your Nhost PostgreSQL database.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  First Workflow &amp;amp; Verification
&lt;/h3&gt;

&lt;p&gt;At first, it may take a few minutes for the container to download the n8n image and spin up the service, especially for the first-time deployment. Also, note that Render's free web services will "sleep" after 15 minutes of inactivity and will take some time to wake up when accessed again. This is normal for the free tier and a small price to pay for a free, managed service.&lt;/p&gt;

&lt;p&gt;After signing up wiht email and password start creating your own workflows and credentials, which are now safely stored and secured in the cloud and remotely accessible. You have unlocked all the features available by hosting it on the cloud, such as making your workflows public.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts &amp;amp; Next Steps
&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%2Fu7o0j0cuwlk4nh7qpk93.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7o0j0cuwlk4nh7qpk93.gif" alt="well done" width="480" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully deployed your own n8n instance with a robust PostgreSQL backend for little to no cost. This powerful setup gives you the freedom and control of self-hosting, combined with the convenience of a managed cloud environment. Now, go build something amazing!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bonus
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Zie619/n8n-workflows/tree/main/workflows" rel="noopener noreferrer"&gt;List of some awesome n8n workflows&lt;/a&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>tutorial</category>
      <category>hosting</category>
      <category>n8n</category>
    </item>
    <item>
      <title>Building a Production Ready React Vite TypeScript Boilerplate</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Mon, 25 Nov 2024 12:19:49 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh</link>
      <guid>https://forem.com/singhamandeep007/building-a-production-ready-react-vite-typescript-boilerplate-4ifh</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;As developers, we often find ourselves setting up the same tools and configurations when starting new projects. To address this challenge, I've created a fully type-safe React + Vite boilerplate/starter that serves as a solid foundation for production-ready web applications which scales well.&lt;/p&gt;

&lt;p&gt;This template emerged from a need to standardize new projects at work, focusing on developer experience, code quality, and scalability. Let me walk you through what makes this boilerplate special and how you can use it for your next project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;p&gt;🚀 Lightning-fast development with Vite&lt;br&gt;
💪 Full TypeScript support&lt;br&gt;
🗂️ Well organized project structure&lt;br&gt;
🔒 Includes JWT authentication implementation&lt;br&gt;
📡 Modern data fetching with Tanstack React Query&lt;br&gt;
🗃️ State management using Zustand&lt;br&gt;
🛣️ Type-safe and File based routing with Tanstack Router&lt;br&gt;
🌐 Internationalization support (i18n)&lt;br&gt;
📝 Form handling with React Hook Form + Zod&lt;br&gt;
🎨 UI components with Tailwind CSS + shadcn/ui&lt;br&gt;
📚 Component documentation using Storybook&lt;br&gt;
✅ Comprehensive testing setup with Vitest + Cypress + MSW&lt;/p&gt;
&lt;h2&gt;
  
  
  Requirement
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 20+&lt;/li&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone https://github.com/singhAmandeep007/react-vite-boilerplate.git

&lt;span class="c"&gt;# cd into folder&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;react-vite-boilerplate

&lt;span class="c"&gt;# Removing the .git folder (and any additional files, folders or dependencies you may not need)&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; .git

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Run the setup script (initializes git repository and husky)&lt;/span&gt;
npm run prepare

&lt;span class="c"&gt;# Start development server, yeah that's all&lt;/span&gt;
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
├── .storybook
├── cypress
│   ├── downloads
│   ├── fixtures
│   ├── specs
│   ├── support
|   └── tsconfig.json
├── env
├── public
├── src
│   ├── __mocks__
│   ├── app
│   │   ├── auth.ts
│   │   ├── App.ts
│   │   └── router.ts
│   ├── assets
│   ├── api
│   │   ├── auth
│   │   ├── posts
│   │   ├── user
│   │   └── apiService.ts
│   ├── components
│   │   ├── forms
│   │   ├── hooks
│   │   ├── layout
│   │   ├── ui
│   │   └── developmentTools.tsx
│   ├── config
│   ├── mocker
│   ├── modules
│   │   └── i18n
│   ├── pages
│   │   ├── app
│   │   ├── home
│   │   └── auth
│   ├── routes
│   ├── store
│   │   └── auth
│   ├── tests
│   ├── types
│   ├── utils
│   └── index.css
│   └── main.tsx
├── index.html
├── .editorconfig
├── eslint.config.js
├── prettier.config.js
├── cypress.config.js
├── tailwind.config.js
├── .gitignore
├── tsconfig.json
├── vite.config.ts
└── package.json

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

&lt;/div&gt;

&lt;h3&gt;
  
  
  Key folders and files with purpose
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Root&lt;/strong&gt; Directory&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.storybook/&lt;/code&gt;: Contains configuration files for Storybook, a popular tool for building UI components and testing them in isolation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cypress/&lt;/code&gt;: Holds end-to-end testing configurations and files.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;downloads/&lt;/code&gt;: For storing temporary downloads during tests.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fixtures/&lt;/code&gt;: Mock data for testing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specs/&lt;/code&gt;: Test cases for Cypress.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;support/&lt;/code&gt;: Custom commands and reusable configurations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tsconfig.json&lt;/code&gt;: TypeScript configuration specific to Cypress.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;env/&lt;/code&gt;: Environment-specific files (e.g., .env.development, .env.production).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;public/&lt;/code&gt;: Publicly accessible assets, such as images or static files.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;index.html&lt;/code&gt;: Entry point for the application.&lt;/li&gt;
&lt;li&gt;Configuration files for linting, formatting, and build tools:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.editorconfig&lt;/code&gt;, &lt;code&gt;eslint.config.js&lt;/code&gt;, &lt;code&gt;prettier.config.js&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tailwind.config.js&lt;/code&gt;: Tailwind CSS configuration.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vite.config.ts&lt;/code&gt;: Vite configuration.&lt;/li&gt;
&lt;li&gt;tsconfig.json: TypeScript compiler configuration.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;src&lt;/strong&gt; Directory&lt;br&gt;
The src folder contains the core of the application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;__mocks__/&lt;/code&gt;: Mock files for testing purposes.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;app/&lt;/code&gt;: Application-level configurations, such as providers (e.g., for React Query, Router, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;api/&lt;/code&gt;: Directory is organized into folders of related API endpoints. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;assets/&lt;/code&gt;: Stores static resources that are part of application.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;components/&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;forms/&lt;/code&gt;: Reusable form components like input fields or buttons.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hooks/&lt;/code&gt;: Custom React hooks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;layout/&lt;/code&gt;: Components related to the app's layout (headers, footers).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ui/&lt;/code&gt;: Reusable UI components (buttons, cards).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;developmentTools.tsx&lt;/code&gt;: Tools or utilities for local development, such as react query devtools.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;config/&lt;/code&gt;: Configuration files, such as API base URLs or environment settings.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mocker/&lt;/code&gt;: For mocking API responses or other utilities during development.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;modules/&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;i18n/&lt;/code&gt;: Internationalization configurations and translation files.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pages/&lt;/code&gt;: Top-level pages, often aligned with routes.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;App/&lt;/code&gt;: Pages related to the main application (dasboard, settings).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Home/&lt;/code&gt;: Homepage or landing page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Auth/&lt;/code&gt;: Authentication-related pages (login, signup).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;routes/&lt;/code&gt;: File based Route configuration for the app, using Tanstack router.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;store/&lt;/code&gt;: Global state management, organized by domain.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;auth/&lt;/code&gt;: State management logic for authentication.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tests/&lt;/code&gt;: Utility functions and wrappers for unit testing.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;types/&lt;/code&gt;: Shared TypeScript types and interfaces.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;utils/&lt;/code&gt;: Reusable utility functions and helpers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;index.css&lt;/code&gt;: Global CSS or Tailwind imports.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main.tsx&lt;/code&gt;: Application entry point, initializing React and rendering the app.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Authentication Implementation
&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%2F7zfzsfez243pj4bk6q5k.webp" 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%2F7zfzsfez243pj4bk6q5k.webp" alt="auth" width="520" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The boilerplate includes a complete JWT authentication setup demonstrating best practices:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Flow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API requests using ky for modern HTTP client capabilities. Ky allows modification the request lifecycle using hooks.&lt;/li&gt;
&lt;li&gt;Request/response handling with React Query for caching and synchronization&lt;/li&gt;
&lt;li&gt;State management through Zustand for auth status and user data&lt;/li&gt;
&lt;li&gt;Protected routes implementation with Tanstack Router&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Testing
&lt;/h2&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%2Fqrj1t6jpskl9xjdizog4.webp" 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%2Fqrj1t6jpskl9xjdizog4.webp" alt="testing" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The boilerplate comes with a comprehensive testing setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Tests: Vitest + React Testing Library&lt;/li&gt;
&lt;li&gt;E2E Tests: Cypress&lt;/li&gt;
&lt;li&gt;API Mocking: MSW (Mock Service Worker)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Unit Testing&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 run &lt;span class="nb"&gt;test&lt;/span&gt;:unit

&lt;span class="c"&gt;# or with coverage&lt;/span&gt;
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:unit:coverage

&lt;span class="c"&gt;# or in watch mode&lt;/span&gt;
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:unit:watch

&lt;span class="c"&gt;# or in ui mode&lt;/span&gt;
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:unit:ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Testing &lt;strong&gt;types&lt;/strong&gt; is also supported with vitest and this application is set up to run tests for types using it. By default all tests inside &lt;code&gt;*.test-d.ts&lt;/code&gt; files are considered type tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;End-to-End (E2E) Testing&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 run &lt;span class="nb"&gt;test&lt;/span&gt;:e2e

&lt;span class="c"&gt;# or in headless mode&lt;/span&gt;
npm run &lt;span class="nb"&gt;test&lt;/span&gt;:e2e:headless
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Development Tools
&lt;/h2&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%2Fcrs9u4umjhosn76osuqk.webp" 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%2Fcrs9u4umjhosn76osuqk.webp" alt="devtools" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dev tools

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://tanstack.com/query/v4/docs/react/devtools" rel="noopener noreferrer"&gt;@tanstack/react-query-devtools&lt;/a&gt; - Dedicated dev tools to help visualize the inner workings of React Query&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tanstack.com/router/v1/docs/devtools" rel="noopener noreferrer"&gt;@tanstack/router-devtools&lt;/a&gt; - Dedicated dev tools to help visualize the inner workings of TanStack Router&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://react-hook-form.com/dev-tools" rel="noopener noreferrer"&gt;@hookform/DevTools&lt;/a&gt; - React Hook Form Devtools to help debug forms with validation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Code Quality&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ESLint for code linting&lt;/li&gt;
&lt;li&gt;Prettier for code formatting&lt;/li&gt;
&lt;li&gt;husky for git hooks&lt;/li&gt;
&lt;li&gt;commitizen + devmoji for standardized commit messages&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Pre-commit Checks&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The boilerplate automatically runs the following checks before each commit:&lt;/li&gt;
&lt;li&gt;Linting&lt;/li&gt;
&lt;li&gt;Type checking&lt;/li&gt;
&lt;li&gt;Format checking&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;p&gt;The project includes GitHub Actions workflows for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Continuous Integration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running e2e tests&lt;/li&gt;
&lt;li&gt;Code quality checks&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Continuous Deployment&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic deployment to production environments&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;This boilerplate aims to provide a solid foundation for your React projects while maintaining flexibility. It incorporates modern tools and best practices without being overly opinionated, allowing you to adapt it to your specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Clone the repository&lt;/li&gt;
&lt;li&gt;Check out the demo implementation&lt;/li&gt;
&lt;li&gt;Customize it for your project&lt;/li&gt;
&lt;li&gt;Provide feedback or contribute&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember one design doesn't fit all, so feel free to customize it according to your needs.&lt;/p&gt;

&lt;p&gt;Your feedback and contributions are always welcome! Feel free to open issues or submit pull requests on GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://singhamandeep.me/react-vite-boilerplate/" rel="noopener noreferrer"&gt;Live Demo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/singhAmandeep007/react-vite-boilerplate/blob/main/README.md" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback and questions are always welcome and I appreciate anyone willing to checkout this project.&lt;/p&gt;

&lt;p&gt;Goodluck shipping you next project. &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%2F5m7i8zekvtrxwndtnrje.webp" 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%2F5m7i8zekvtrxwndtnrje.webp" alt="rocket" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Unit testing</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Wed, 06 Nov 2024 15:37:20 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/unit-testing-4nen</link>
      <guid>https://forem.com/singhamandeep007/unit-testing-4nen</guid>
      <description>&lt;p&gt;Testing at the unit level reduces the risk of unexpected behaviors, giving developers confidence that their code performs reliably. In this series, we’ll cover unit testing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript/Typescript (React) for Web UI Components&lt;/li&gt;
&lt;li&gt;Python for API Endpoints&lt;/li&gt;
&lt;li&gt;Go for Backend Logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll dive into strategies, role in SDLC, specific examples and best practices, covering essential tools and techniques that will help you test more effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit testing strategies
&lt;/h2&gt;

&lt;p&gt;To create unit tests, you can follow some basic techniques to ensure coverage of all test cases.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Logic checks - Does the system perform the right calculations and follow the right path through the code given a correct, expected input? Are all paths through the code covered by the given inputs?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boundary checks - For the given inputs, how does the system respond? How does it respond to typical inputs, edge cases, or invalid inputs?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Error handling - When there are errors in inputs, how does the system respond? Is the user prompted for another input? Does the software crash?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Object-oriented checks - If the state of any persistent objects is changed by running the code, is the object updated correctly?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Unit Testing and SDLC
&lt;/h2&gt;

&lt;p&gt;Unit testing plays a critical role throughout the Software Development Lifecycle (SDLC), helping developers detect and fix issues early on, reducing costly fixes later in the process. Unit testing can be integrated into SDLC in a few main approaches:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Test-Driven Development (TDD): In TDD, tests are written before the actual code. Developers begin by writing a failing unit test for a small piece of functionality, then implement the code to pass the test, and finally refactor the code if needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Testing After Completing a Code Block: Often, developers write tests after completing a block of code, verifying its behavior against expected outcomes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automated Testing in CI/CD Pipelines: Once tests are written, integrating them into CI/CD pipelines ensures that they run automatically whenever new code is added catching potential issues before they make it to production.&lt;/p&gt;&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%2Fxa1u4dotiu2lj9ghzajp.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%2Fxa1u4dotiu2lj9ghzajp.jpeg" alt="Best practices" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Best practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Mock Dependencies&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolate the functionality under test by mocking external dependencies. This allows you to test components independently and assume that external modules or APIs will behave as expected.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Naming&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The name of unit test should describe the intent of the test to us clearly. We should be able to infer method behavior from the name of the method without looking at the code itself.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Organize your tests into three clear steps, following the AAA (Arrange, Act, Assert) pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Arrange (Setup) - Prepare the necessary environment, mock data, and dependencies required for the test.&lt;/li&gt;
&lt;li&gt;Act (Stimulus) - Execute the function or method that you want to test.&lt;/li&gt;
&lt;li&gt;Assert (Expectation) - Verify the result by asserting that the outcome matches the expected behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid Snapshot Testing for Units&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snapshot testing can obscure specific failures. Instead, write tests with explicit assertions that clearly outline expected behaviors.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use Visual Testing for Complex UI Components&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For testing visual elements like charts, maps, and graphs, consider visual testing. Capture and compare screenshots to detect unintended changes over time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use Simple, Readable Data Sets for Assertions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose datasets that are straightforward and easy to understand, minimizing cognitive load for anyone reviewing the tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Minimize Flakiness&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Design tests to be consistent and reliable by avoiding dependencies on fluctuating states or unpredictable data.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use Accessibility Attributes as Selectors&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When possible, use accessibility attributes to select elements for testing. This can improve both test accuracy and app accessibility.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid Global State&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep tests independent by avoiding global state that can cause unexpected interactions between tests. Each test should be isolated in its execution.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use Dependency Injection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use dependency injection to pass external dependencies into your unit, allowing for better control and flexibility during testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aim for High Code Coverage&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strive for at least 85% line coverage to ensure a thorough evaluation of your code and increase confidence in its reliability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>unittest</category>
      <category>testing</category>
      <category>programming</category>
    </item>
    <item>
      <title>Basics of Testing</title>
      <dc:creator>Amandeep Singh</dc:creator>
      <pubDate>Wed, 06 Nov 2024 15:36:09 +0000</pubDate>
      <link>https://forem.com/singhamandeep007/basics-of-testing-3g6h</link>
      <guid>https://forem.com/singhamandeep007/basics-of-testing-3g6h</guid>
      <description>&lt;h2&gt;
  
  
  Why test?
&lt;/h2&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%2Fmz4d3axyza37wwt83f21.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmz4d3axyza37wwt83f21.gif" alt="why test" width="290" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Improved Code Quality&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Early Bug Detection: Catching bugs during development saves time and prevents costly fixes later in production.&lt;/li&gt;
&lt;li&gt;Confident Refactoring: With a solid test suite, developers can refactor code freely, knowing they’ll be alerted to any unintended side effects.&lt;/li&gt;
&lt;li&gt;Clear Code Documentation: Tests provide a living document of how the code is intended to work, helping new team members understand the functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Increased Productivity&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster Debugging: Automated tests quickly point to the source of issues, allowing developers to focus on fixing rather than finding bugs.&lt;/li&gt;
&lt;li&gt;Easier Code Maintenance: Tests help identify when changes introduce new issues, making it easier to maintain code and add new features without disrupting existing functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Stronger Team Collaboration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shared Understanding of Features: Writing and reviewing tests together promotes a shared vision of how the application should behave, ensuring consistency.&lt;/li&gt;
&lt;li&gt;Self-Documenting Codebase: Well-written tests serve as additional documentation, clarifying expected behavior and saving time on onboarding.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Increased Confidence in Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Peace of Mind: Comprehensive testing reduces anxiety about deploying changes, as developers know the code has been thoroughly vetted.&lt;/li&gt;
&lt;li&gt;Enhanced User Experience (UX): Tests ensure that critical user journeys work as expected, resulting in a smoother, more reliable experience for users.&lt;/li&gt;
&lt;li&gt;Reduced Risk in Production: Testing minimizes the likelihood of serious issues reaching the production environment, protecting both the brand and user trust.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to setup testing environment?
&lt;/h2&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%2F6rk8p5tgbp8tdc74w1qy.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%2F6rk8p5tgbp8tdc74w1qy.jpeg" alt="setting up" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A robust testing environment is key to maintaining high-quality frontend and web applications. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start by configuring your setup to be intuitive and well-documented, so developers can easily write and run tests with minimal setup time.&lt;/li&gt;
&lt;li&gt;For frontend testing ensure that your environment supports UI testing tools and accessibility checks to verify that your app is usable for all users. Structure your UI components to follow testing best practices, making them easier to test in realistic use cases.&lt;/li&gt;
&lt;li&gt;A well-designed environment should minimize flakiness in tests, reducing the chance of inconsistent results and making it easier to identify real issues.&lt;/li&gt;
&lt;li&gt;Performance testing is also essential to confirm that your app meets speed and responsiveness standards.&lt;/li&gt;
&lt;li&gt;Set up your environment to support writing tests that simulate real-world scenarios.&lt;/li&gt;
&lt;li&gt;Ensure that developers can quickly write and execute tests, with easy access to stack traces for efficient debugging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Types of Tests
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Testing level&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Unit tests

&lt;ul&gt;
&lt;li&gt;Testing individual components or functions in isolation to verify they work as expected.&lt;/li&gt;
&lt;li&gt;e.g., Testing a single function to ensure it returns the correct result for given inputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Integration tests

&lt;ul&gt;
&lt;li&gt;Broader scope than unit tests, verifies that different modules or components interact correctly when combined.&lt;/li&gt;
&lt;li&gt;e.g., Testing an API endpoint to check if it correctly integrates with the database and other services.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;End to End tests

&lt;ul&gt;
&lt;li&gt;Test the entire application flow, aiming to mimic real user behavior and interactions with the complete system.&lt;/li&gt;
&lt;li&gt;e.g., Testing a user’s journey from login to checkout in an e-commerce app.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Acceptance Tests

&lt;ul&gt;
&lt;li&gt;Ensure the application meets business requirements and functions as expected from a user’s perspective, usually part of agile methodology.&lt;/li&gt;
&lt;li&gt;e.g., Testing whether the app fulfills specific user stories or requirements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Automation&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Automated tests

&lt;ul&gt;
&lt;li&gt;Run tests automatically to save time and reduce human error, usually as part of CI/CD.&lt;/li&gt;
&lt;li&gt;e.g., Running a suite of unit and integration tests on every pull request.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Manual tests

&lt;ul&gt;
&lt;li&gt;Conduct tests manually to explore features and validate scenarios that might be difficult to automate.&lt;/li&gt;
&lt;li&gt;e.g., Manually checking complex user flows or new features for usability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Functionality&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Functional tests

&lt;ul&gt;
&lt;li&gt;Verify that specific features work according to the functional requirements.&lt;/li&gt;
&lt;li&gt;e.g., Testing that a search feature returns the correct results based on input.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Performance tests

&lt;ul&gt;
&lt;li&gt;Measure how the application performs under various conditions, focusing on speed, stability, and responsiveness.&lt;/li&gt;
&lt;li&gt;e.g., Testing app load times and response times under heavy traffic. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Security tests

&lt;ul&gt;
&lt;li&gt;Identify vulnerabilities and ensure the application is secure against threats.&lt;/li&gt;
&lt;li&gt;e.g., Testing for common vulnerabilities like SQL injection or cross-site scripting (XSS).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Usability tests

&lt;ul&gt;
&lt;li&gt;Evaluate how easy and intuitive the application is to use for real users.&lt;/li&gt;
&lt;li&gt;e.g., Observing users to see if they can navigate the app without difficulty.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Accessibility tests

&lt;ul&gt;
&lt;li&gt;Ensure the application is accessible to users with disabilities.&lt;/li&gt;
&lt;li&gt;e.g., Testing keyboard navigation, screen reader compatibility, and color contrast.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Scalability tests

&lt;ul&gt;
&lt;li&gt;Assess the application’s ability to handle increased load or traffic without performance degradation.&lt;/li&gt;
&lt;li&gt;e.g., Testing how the app performs when scaled to handle thousands of users.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Other&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Regression

&lt;ul&gt;
&lt;li&gt;Confirm that new code changes haven’t negatively impacted existing functionality.&lt;/li&gt;
&lt;li&gt;Running tests after updates to ensure core features still work as expected.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Smoke tests

&lt;ul&gt;
&lt;li&gt;Perform a quick, high-level check to see if critical functions of the application work after a deployment.&lt;/li&gt;
&lt;li&gt;Testing basic features like login and navigation immediately after a new build.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;h2&gt;
  
  
  What are the tradeoffs with tests level?
&lt;/h2&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%2F82rms2028zc34iljjhg7.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%2F82rms2028zc34iljjhg7.jpeg" alt="testing pyramid" width="736" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Integration&lt;/th&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;E2E&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Scope&lt;/td&gt;
&lt;td&gt;Lowest scope, focusing on individual units like functions or classes.&lt;/td&gt;
&lt;td&gt;Broader scope than unit tests, focusing on how units interact within a module or subsystem.&lt;/td&gt;
&lt;td&gt;Even broader scope, covering the entire system as a whole, integrating all components and functionalities.&lt;/td&gt;
&lt;td&gt;Highest scope, aiming to mimic real user behavior and interactions with the complete.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Fastest to write and execute due to their limited scope and isolation.&lt;/td&gt;
&lt;td&gt;Generally faster than system and E2E tests, but slower than unit tests due to increased complexity.&lt;/td&gt;
&lt;td&gt;Can be slower than integration tests due to the larger scope and potential dependencies on external systems.&lt;/td&gt;
&lt;td&gt;Often the slowest due to their comprehensive nature and potential reliance on real user environments.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Isolation&lt;/td&gt;
&lt;td&gt;Highest isolation, focusing on individual units without external dependencies.&lt;/td&gt;
&lt;td&gt;Moderate isolation, testing interactions within a module but potentially having dependencies on external modules or mock objects.&lt;/td&gt;
&lt;td&gt;Lower isolation, often involving real or simulated external systems and dependencies.&lt;/td&gt;
&lt;td&gt;Lowest isolation, typically running in the actual user environment with real dependencies.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How to Create a Testing Strategy?
&lt;/h2&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%2Frug5fs0dgg3gemdc3uq8.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%2Frug5fs0dgg3gemdc3uq8.jpeg" alt="strategy" width="736" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A well-defined testing strategy is essential for ensuring that your application is reliable, maintainable, and resilient.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Start with defining Goals&lt;/strong&gt; and Objectives which align with business objectives and project requirements&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify Key Goals: Define what you want to achieve with your testing, such as reducing bug frequency, improving user experience, or achieving faster release cycles.&lt;/li&gt;
&lt;li&gt;Set Quality Standards: Determine acceptable levels of reliability, performance, and security.&lt;/li&gt;
&lt;li&gt;Specify Success Metrics: Decide how you’ll measure the success of your testing, such as test coverage percentage.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Identify Scope and Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Application Components: Identify which parts of the application need testing (frontend, backend, database, APIs).&lt;/li&gt;
&lt;li&gt;Supported Environments: List the devices, operating systems, and browsers that need coverage.&lt;/li&gt;
&lt;li&gt;Functional vs. Non-functional Requirements: Differentiate between functional requirements (features and functionality) and non-functional requirements (performance, usability, security).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Choose Types of Tests&lt;/strong&gt; - Choose the appropriate types of tests for your application to ensure thorough coverage at every level.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Tests&lt;/li&gt;
&lt;li&gt;End-to-End (E2E) Tests&lt;/li&gt;
&lt;li&gt;Performance Tests.&lt;/li&gt;
&lt;li&gt;Security Tests&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Select Testing Tools and Frameworks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit Testing Tools: Examples include Jest + React Testing Library (JavaScript), unittest (Python), pytest (Python), or Go testing framework.&lt;/li&gt;
&lt;li&gt;Integration and E2E Testing Tools: Consider Cypress, Playwright, or Selenium.&lt;/li&gt;
&lt;li&gt;Performance Testing Tools: Tools like JMeter, Gatling, or k6 can help you simulate load and assess performance.&lt;/li&gt;
&lt;li&gt;Security Testing Tools: Use tools like OWASP ZAP or Burp Suite to scan for vulnerabilities.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Define Test Data and Environment Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing Environments: Decide if you need separate environments for development, testing, and production. Create isolated environments that mirror production as closely as possible.&lt;/li&gt;
&lt;li&gt;Test Data Management: Use representative data for testing while protecting sensitive information. Implement strategies to refresh or reset data between test runs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Plan for Test Automation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify Candidates for Automation: Determine which tests are suitable for automation, typically repetitive and high-priority tests.&lt;/li&gt;
&lt;li&gt;Select Automation Frameworks: Choose frameworks that align with your project’s tech stack and testing goals.&lt;/li&gt;
&lt;li&gt;Set Automation Goals: Decide what percentage of tests to automate and prioritize high-impact areas like unit tests and E2E tests.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Establish a CI/CD Testing Pipeline&lt;/strong&gt; ensuring that code changes are continuously validated before deployment.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure Automated Test Runs: Set up automated tests to run on each pull request, commit, or at scheduled intervals.&lt;/li&gt;
&lt;li&gt;Set Up Build and Deployment Triggers: Use CI/CD tools like GitHub Actions, Jenkins, or CircleCI to trigger tests and manage the deployment workflow.&lt;/li&gt;
&lt;li&gt;Define Test Gates: Establish criteria that code must pass (such as a minimum test coverage) before it can be merged or deployed.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Monitor&lt;/strong&gt;, &lt;strong&gt;Report&lt;/strong&gt;, and &lt;strong&gt;Improve&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set Up Monitoring Tools: Use monitoring tools to keep an eye on application performance, error rates, and uptime in production.&lt;/li&gt;
&lt;li&gt;Notify stakeholders with Test Reports. Set up periodic updates or email notifications to stakeholders, summarizing testing outcomes and key insights.&lt;/li&gt;
&lt;li&gt;Analyze Test Reports: Review test reports and metrics regularly to identify patterns, such as areas prone to bugs or performance issues.&lt;/li&gt;
&lt;li&gt;Iterate and Improve: Use insights from monitoring and reports to continuously refine your testing strategy, improve test coverage, and resolve bottlenecks. Check for flakiness.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>testing</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
