<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chintan Soni</title>
    <description>The latest articles on DEV Community by Chintan Soni (@ichintansoni).</description>
    <link>https://dev.to/ichintansoni</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%2F77400%2Fc004d047-fe39-4206-8882-f37eae4a45fb.jpeg</url>
      <title>DEV Community: Chintan Soni</title>
      <link>https://dev.to/ichintansoni</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ichintansoni"/>
    <language>en</language>
    <item>
      <title>What Is a Vector Database? A Practical Deep Dive with Milvus</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Fri, 09 Jan 2026 08:27:17 +0000</pubDate>
      <link>https://dev.to/ichintansoni/what-is-a-vector-database-a-practical-deep-dive-with-milvus-1m9g</link>
      <guid>https://dev.to/ichintansoni/what-is-a-vector-database-a-practical-deep-dive-with-milvus-1m9g</guid>
      <description>&lt;p&gt;Vector databases have become a foundational component of modern AI systems — yet many developers struggle to understand why they exist and how they actually work.&lt;/p&gt;

&lt;p&gt;In this video, I explain vector databases from first principles using real-world examples, focusing on clarity over buzzwords.&lt;/p&gt;

&lt;p&gt;🔍 What You’ll Learn&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why traditional databases fail at semantic search&lt;/li&gt;
&lt;li&gt;What embeddings are and why they are high-dimensional&lt;/li&gt;
&lt;li&gt;How vector databases enable similarity search using ANN&lt;/li&gt;
&lt;li&gt;How Milvus is architected for scale&lt;/li&gt;
&lt;li&gt;Where vector databases fit in RAG and AI agent systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🎥 Watch the video here:&lt;br&gt;
👉 &lt;a href="https://youtu.be/7hSDxxby66M" rel="noopener noreferrer"&gt;https://youtu.be/7hSDxxby66M&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This video is part of my AI Foundations for Developers series — aimed at helping software engineers build solid mental models before jumping into frameworks.&lt;/p&gt;

&lt;p&gt;📌 Coming next:&lt;br&gt;
LangChain + Milvus, real documents, embeddings, hybrid search, and the foundation for AI agents.&lt;/p&gt;

&lt;p&gt;If you’re building or planning to build AI-powered systems, this should help clear a lot of confusion.&lt;/p&gt;

</description>
      <category>vectordatabase</category>
      <category>milvus</category>
      <category>aiengineering</category>
      <category>langchain</category>
    </item>
    <item>
      <title>Dense vs Sparse Vectors in AI — Explained for Developers</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Tue, 06 Jan 2026 10:27:45 +0000</pubDate>
      <link>https://dev.to/ichintansoni/dense-vs-sparse-vectors-in-ai-explained-for-developers-ea0</link>
      <guid>https://dev.to/ichintansoni/dense-vs-sparse-vectors-in-ai-explained-for-developers-ea0</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Dense vs Sparse Vectors in AI — Explained for Developers&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When people talk about AI, embeddings, or semantic search, one concept quietly sits underneath almost everything:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vectors.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And more specifically — &lt;strong&gt;dense vectors and sparse vectors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I recently published &lt;strong&gt;Video #2&lt;/strong&gt; in my &lt;em&gt;AI Foundations for Developers&lt;/em&gt; series, where I break this down with &lt;strong&gt;simple mental models and real-world examples&lt;/strong&gt;, without diving into heavy math or ML theory.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤔 Why this topic matters
&lt;/h2&gt;

&lt;p&gt;If you’ve worked with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search engines&lt;/li&gt;
&lt;li&gt;Embeddings&lt;/li&gt;
&lt;li&gt;RAG systems&lt;/li&gt;
&lt;li&gt;Vector databases&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…you’re already using dense or sparse vectors — even if you’ve never stopped to think about them.&lt;/p&gt;

&lt;p&gt;Understanding the difference helps you answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why keyword search behaves differently from semantic search&lt;/li&gt;
&lt;li&gt;Why embeddings are needed at all&lt;/li&gt;
&lt;li&gt;Why modern AI systems often combine multiple approaches&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📌 What this video covers
&lt;/h2&gt;

&lt;p&gt;In this video, I explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;What &lt;strong&gt;sparse vectors&lt;/strong&gt; are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How keyword-based search works&lt;/li&gt;
&lt;li&gt;Why systems like BM25 still matter&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;What &lt;strong&gt;dense vectors (embeddings)&lt;/strong&gt; are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How AI captures semantic meaning&lt;/li&gt;
&lt;li&gt;Why similar sentences cluster together&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Real-world examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Find documents containing ERROR”&lt;/li&gt;
&lt;li&gt;vs&lt;/li&gt;
&lt;li&gt;“Find documents related to scaling cloud apps”&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Why modern AI systems use &lt;strong&gt;both&lt;/strong&gt; (hybrid search)&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is all explained from a &lt;strong&gt;developer’s perspective&lt;/strong&gt;, focusing on intuition before tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  ▶️ Watch the video
&lt;/h2&gt;

&lt;p&gt;🎥 &lt;strong&gt;Dense vs Sparse Vectors in AI | AI Foundations for Developers #2&lt;/strong&gt;&lt;br&gt;
👉 &lt;a href="https://www.youtube.com/watch?v=F84s1pxwWGo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=F84s1pxwWGo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re new to the series, I strongly recommend starting here:&lt;/p&gt;

&lt;p&gt;🎥 &lt;strong&gt;What Are Vectors in AI? | AI Foundations for Developers #1&lt;/strong&gt;&lt;br&gt;
👉 &lt;a href="https://www.youtube.com/watch?v=nZRiStzyRdo" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=nZRiStzyRdo&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧱 About the series
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI Foundations for Developers&lt;/strong&gt; is a video series where I focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building strong conceptual foundations&lt;/li&gt;
&lt;li&gt;Avoiding hype and buzzwords&lt;/li&gt;
&lt;li&gt;Explaining &lt;em&gt;why&lt;/em&gt; things exist before showing &lt;em&gt;how&lt;/em&gt; to code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Upcoming videos will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vector Databases (Milvus)&lt;/li&gt;
&lt;li&gt;Hybrid Search&lt;/li&gt;
&lt;li&gt;LangChain integrations&lt;/li&gt;
&lt;li&gt;Hands-on demos&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💬 Feedback welcome
&lt;/h2&gt;

&lt;p&gt;I’m building this series in public, and feedback from fellow developers is extremely valuable.&lt;/p&gt;

&lt;p&gt;If you watched the video:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What clicked immediately?&lt;/li&gt;
&lt;li&gt;What felt confusing?&lt;/li&gt;
&lt;li&gt;What should I cover next?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading 🙏&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>search</category>
      <category>embeddings</category>
    </item>
    <item>
      <title>AI Foundations for Developers #1: What Are Vectors?</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Sat, 03 Jan 2026 18:28:04 +0000</pubDate>
      <link>https://dev.to/ichintansoni/ai-foundations-for-developers-1-what-are-vectors-14c4</link>
      <guid>https://dev.to/ichintansoni/ai-foundations-for-developers-1-what-are-vectors-14c4</guid>
      <description>&lt;p&gt;I’ve started a new video series called &lt;strong&gt;AI Foundations for Developers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This series is aimed at software engineers who want to understand&lt;br&gt;
how modern AI systems work from first principles — not just by&lt;br&gt;
using frameworks or copying code.&lt;/p&gt;

&lt;p&gt;Most AI content today jumps straight into tools like LangChain,&lt;br&gt;
RAG pipelines, or AI agents. But without understanding the basics,&lt;br&gt;
it’s hard to reason about design choices or debug issues in production.&lt;/p&gt;

&lt;p&gt;In the first video of the series, I focus on a very fundamental question:&lt;/p&gt;

&lt;p&gt;👉 What exactly is a vector, and why does AI represent information as vectors?&lt;/p&gt;

&lt;p&gt;Here’s the video:&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/nZRiStzyRdo"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;p&gt;Over the next videos, I’ll be covering topics like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dense vs sparse vectors&lt;/li&gt;
&lt;li&gt;Vector databases&lt;/li&gt;
&lt;li&gt;Hybrid search&lt;/li&gt;
&lt;li&gt;RAG systems&lt;/li&gt;
&lt;li&gt;AI agents, memory, and protocols&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re a developer planning to build AI-powered features,&lt;br&gt;
this series is meant to give you clarity and strong foundations.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>softwareengineering</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Node.js Just Got Cooler: Imports and Package JSON Are Here to Save Your Day</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Sun, 31 Aug 2025 11:20:18 +0000</pubDate>
      <link>https://dev.to/ichintansoni/nodejs-just-got-cooler-imports-and-package-json-are-here-to-save-your-day-3ggo</link>
      <guid>https://dev.to/ichintansoni/nodejs-just-got-cooler-imports-and-package-json-are-here-to-save-your-day-3ggo</guid>
      <description>&lt;p&gt;If you’ve ever worked on a Node.js project, you’ve probably had this experience:&lt;/p&gt;

&lt;p&gt;You’re writing an import, your brain says &lt;em&gt;“easy-peasy”&lt;/em&gt;, but your editor whispers:&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;import&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./../../../path/to/some/service.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suddenly, you’re not coding anymore. You’re Indiana Jones, lost in a temple of &lt;code&gt;../&lt;/code&gt; and praying you don’t accidentally end up in the wrong directory.&lt;/p&gt;

&lt;p&gt;Well, guess what? Node.js just threw us a lifeline. It’s called &lt;strong&gt;Imports via &lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt;, and it’s here to kick those &lt;code&gt;../../../&lt;/code&gt; nightmares out of your life.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Before: The Jungle of Relative Paths&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Back in the day, importing a file felt like playing &lt;em&gt;“how many dots can you fit in a path?”&lt;/em&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;import&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./../../../path/to/some/service.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is fine when your project is three files and a dream. But once it grows, you’re basically navigating with Google Maps set to “maze mode.”&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;After: The Alias Glow-Up&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s where the magic happens. Open up your &lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt;, sprinkle in a little configuration, and suddenly your imports are as smooth as butter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"imports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"#src/*"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./src/*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it. Seriously. Just one tiny block and your codebase is already breathing easier.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Usage: Imports, But Make Them Sexy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now instead of typing a path that looks like a family tree gone wrong, you just do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#src/path/to/some/app.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean. Simple. Understandable.&lt;br&gt;
And if someone asks, “where’s that service coming from?” you don’t have to pull out a whiteboard and draw arrows through directories.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why This Rocks&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No More Dot Gymnastics&lt;/strong&gt; – Your pinky finger finally gets a break from all those &lt;code&gt;../&lt;/code&gt; key presses.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Readable Code&lt;/strong&gt; – Your imports now &lt;em&gt;explain themselves&lt;/em&gt;, instead of looking like cryptic treasure maps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Future-Proof&lt;/strong&gt; – This is modern Node.js flexing its muscles. You’re not just writing code, you’re writing &lt;strong&gt;fancy code&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Bonus: Pair It with Watch Mode&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Check out my other piece: &lt;a href="https://dev.to/ichintansoni/nodejs-just-got-cooler-native-typescript-and-watch-mode-are-here-to-party-a5a"&gt;Node.js Just Got Cooler: Native TypeScript and Watch Mode Are Here to Party&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Node.js Just Got Cooler: Native TypeScript and Watch Mode Are Here to Party</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Thu, 24 Apr 2025 18:12:15 +0000</pubDate>
      <link>https://dev.to/ichintansoni/nodejs-just-got-cooler-native-typescript-and-watch-mode-are-here-to-party-a5a</link>
      <guid>https://dev.to/ichintansoni/nodejs-just-got-cooler-native-typescript-and-watch-mode-are-here-to-party-a5a</guid>
      <description>&lt;p&gt;Node.js just rolled up in sunglasses, holding a smoothie, and said, &lt;em&gt;“Guess who supports TypeScript natively now?”&lt;/em&gt; That’s right—it’s leveling up in a big way. With &lt;strong&gt;built-in TypeScript support&lt;/strong&gt; and a brand new &lt;strong&gt;watch mode&lt;/strong&gt;, you can finally spend less time wrangling build tools and more time pretending to debug while secretly scrolling memes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Native TypeScript Support: No Compiler? No Problem.&lt;/strong&gt;&lt;br&gt;
Remember the old days when you had to run tsc just to breathe near a TypeScript file? That’s history. Now, Node.js can run &lt;code&gt;.ts&lt;/code&gt; files directly using the &lt;code&gt;--experimental-transform&lt;/code&gt; flag. It’s like Node looked at your workflow and said, &lt;em&gt;“You deserve better.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Here’s the magic spell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--experimental-transform-types&lt;/span&gt; ./src/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No compiling. No bundling. No stress. Just type, run, repeat. Sure, it’s still marked as experimental, but so were electric cars—and look at them now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Watch Mode: Because Manually Restarting is So 2022&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’ve ever fixed a bug and then sighed dramatically while restarting your app… good news: &lt;strong&gt;Node.js watch mode&lt;/strong&gt; has entered the chat. It watches your files and restarts the app automatically when something changes—like an attentive sidekick who actually pulls their weight.&lt;/p&gt;

&lt;p&gt;Use it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--watch&lt;/span&gt; ./src/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or specify what to watch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--watch-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./src ./src/index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bonus Tip: Let package.json Do the Heavy Lifting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add a script to your package.json like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node --experimental-transform-types --watch-path=./src src/index.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can just run:&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 dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more typing out long commands like you’re programming in the Stone Age.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wrapping Up: Node.js Just Became Your Cool Dev Friend&lt;/strong&gt;&lt;br&gt;
These new features aren’t just convenient—they’re a vibe. Native TypeScript support means fewer tools to manage. Watch mode means faster feedback loops. And your brain? It means less cluttered by &lt;em&gt;“Did I forget to restart the server?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So give it a whirl. Build something. Break something. Fix it. Repeat. Just remember to hydrate—and maybe check a meme or two along the way.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Understanding JavaScript's Event Loop: A Simple Cookie-Making Analogy 🍪</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Fri, 11 Oct 2024 02:28:33 +0000</pubDate>
      <link>https://dev.to/ichintansoni/understanding-javascripts-event-loop-a-simple-cookie-making-analogy-3485</link>
      <guid>https://dev.to/ichintansoni/understanding-javascripts-event-loop-a-simple-cookie-making-analogy-3485</guid>
      <description>&lt;p&gt;When learning JavaScript, the &lt;strong&gt;event loop&lt;/strong&gt; is one of those tricky topics that can leave you scratching your head. But don’t worry! We’re going to explain it in a fun and simple way using a real-world example that even a 5-year-old would understand: making cookies! 🎉&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%2Fgj4kz0e72xyzhhhwiub0.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%2Fgj4kz0e72xyzhhhwiub0.jpg" alt="A playful illustration of a child baking cookies" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s imagine you’re in the kitchen and want to bake a batch of cookies. But here’s the catch—you can only do &lt;strong&gt;one thing at a time&lt;/strong&gt;. This is just like JavaScript: it’s &lt;strong&gt;single-threaded&lt;/strong&gt;, meaning it can only do one task at a time. Now, let’s see how the cookie-making process can help us understand how the &lt;strong&gt;event loop&lt;/strong&gt; works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Call Stack = Your To-Do List
&lt;/h2&gt;

&lt;p&gt;In the kitchen, you have a &lt;strong&gt;to-do list&lt;/strong&gt; that tells you exactly what to do next. You follow it step-by-step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mix the dough.
&lt;/li&gt;
&lt;li&gt;Put the cookies in the oven.
&lt;/li&gt;
&lt;li&gt;Pour some milk.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can only check off one task at a time. In JavaScript, this list is called the &lt;strong&gt;call stack&lt;/strong&gt;. JavaScript runs code one step at a time, just like how you follow your cookie recipe.&lt;/p&gt;

&lt;h2&gt;
  
  
  Synchronous Tasks = Simple, Quick Tasks
&lt;/h2&gt;

&lt;p&gt;Some tasks are super simple and take just a moment, like &lt;strong&gt;mixing dough&lt;/strong&gt; or &lt;strong&gt;pouring milk&lt;/strong&gt;. You don’t need to wait for anything, and you can do them immediately. This is like &lt;strong&gt;synchronous code&lt;/strong&gt; in JavaScript—it runs from top to bottom, one step after another, without waiting.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mix dough&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pour milk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code runs just like mixing dough and pouring milk—you do one, then the next, and move on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Asynchronous Tasks = Waiting Tasks
&lt;/h2&gt;

&lt;p&gt;But what happens when you put the cookies in the oven? You can't just stand there doing nothing while they bake, right? That would be a waste of time! Instead, you set a &lt;strong&gt;timer&lt;/strong&gt; for 10 minutes and move on to something else, like cleaning up or setting the table. &lt;/p&gt;

&lt;p&gt;In JavaScript, this is like using something called &lt;code&gt;setTimeout&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Put cookies in oven&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Take cookies out of oven&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="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here’s what happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, you put the cookies in the oven.&lt;/li&gt;
&lt;li&gt;Then, you set a timer (10,000 milliseconds = 10 minutes), but you &lt;strong&gt;don’t wait around&lt;/strong&gt;! Instead, you move on to pouring milk.&lt;/li&gt;
&lt;li&gt;When the timer goes off, you come back to take the cookies out of the oven.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what we call an &lt;strong&gt;asynchronous task&lt;/strong&gt; in JavaScript—it doesn’t block other things from happening while it waits.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Event Loop = Your Kitchen Helper
&lt;/h2&gt;

&lt;p&gt;Now, while you’re busy pouring milk or setting the table, you have a &lt;strong&gt;kitchen helper&lt;/strong&gt; (think of the &lt;strong&gt;event loop&lt;/strong&gt;) who checks if your cookies are done. When the timer goes off, your helper reminds you: "Hey! The cookies are ready, time to take them out!"&lt;/p&gt;

&lt;p&gt;In JavaScript, the &lt;strong&gt;event loop&lt;/strong&gt; constantly checks if the &lt;strong&gt;call stack&lt;/strong&gt; is clear. If it’s empty and there’s a waiting task (like the cookies being done), it moves that task to the front of the list so it can be completed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microtasks = Extra Important Jobs
&lt;/h2&gt;

&lt;p&gt;Sometimes, you have something super important to do, like setting the table. Even if the cookies are almost done, you make sure to set the table first before taking the cookies out. &lt;/p&gt;

&lt;p&gt;In JavaScript, these extra important tasks are called &lt;strong&gt;microtasks&lt;/strong&gt; (usually created by things like promises). The event loop makes sure &lt;strong&gt;microtasks&lt;/strong&gt; are done &lt;strong&gt;before&lt;/strong&gt; the regular tasks (like taking the cookies out of the oven).&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Mix dough&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Take cookies out of oven&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Set table&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mix dough
Pour milk
Set table
Take cookies out of oven
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that "Set table" happens &lt;strong&gt;before&lt;/strong&gt; the cookies come out, even though the &lt;code&gt;setTimeout&lt;/code&gt; had a shorter delay! That’s because &lt;strong&gt;microtasks&lt;/strong&gt; (like promises) are more urgent than regular tasks.&lt;/p&gt;

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

&lt;p&gt;So, let’s bring it all together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Call Stack&lt;/strong&gt;: Your to-do list in the kitchen—one task at a time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synchronous Tasks&lt;/strong&gt;: Quick tasks like mixing dough or pouring milk, done immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous Tasks&lt;/strong&gt;: Tasks that take time, like baking cookies, but you don’t wait—you set a timer and come back later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Event Loop&lt;/strong&gt;: Your kitchen helper, making sure everything happens at the right time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microtasks&lt;/strong&gt;: Super important tasks, like setting the table, that get done before the regular tasks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding the &lt;strong&gt;event loop&lt;/strong&gt; using a cookie-making analogy, you can now see how JavaScript can do many things without ever getting stuck waiting!&lt;/p&gt;




&lt;p&gt;Feel free to share this with anyone just starting out with JavaScript or anyone who loves cookies! 🍪&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>GitLab CI/CD Pipelines: Best Practices for Monorepos</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Mon, 01 Jul 2024 02:42:52 +0000</pubDate>
      <link>https://dev.to/ichintansoni/gitlab-cicd-pipelines-best-practices-for-monorepos-cba</link>
      <guid>https://dev.to/ichintansoni/gitlab-cicd-pipelines-best-practices-for-monorepos-cba</guid>
      <description>&lt;p&gt;Hello everyone! This article is for those who want to optimize their CI/CD pipelines using best practices in a monorepo setup.&lt;/p&gt;

&lt;p&gt;To provide a clear walkthrough, let’s consider the following example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project structure:&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%2F9sd3js5y3d96qrweu20o.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%2F9sd3js5y3d96qrweu20o.png" alt="Image description" width="592" height="280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial .gitlab-ci.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;

&lt;span class="na"&gt;build-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;test-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;deploy-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;build-b&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;test-b&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;deploy-b&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;build-c&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;test-c&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;deploy-c&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above configuration can quickly become unmanageable as the number of projects in the monorepo increases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this a problem?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unnecessary Job Triggers:&lt;/strong&gt; A single commit will trigger all jobs, regardless of the scope of the change. For instance, a commit made for changes in project-a will also trigger jobs for project-b and project-c, which is inefficient..&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%2Fpehiota46yud0483i6c1.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%2Fpehiota46yud0483i6c1.png" alt="Screenshot of original pipeline" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reduced Readability:&lt;/strong&gt; The CI/CD configuration becomes less readable and harder to maintain, especially with environment-specific jobs for dev, QA, UAT, and prod.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Complexity:&lt;/strong&gt; The setup becomes fragile, making it easy for anyone to inadvertently disrupt the pipeline. It requires more expertise to understand the scope, impact of changes, and dependencies of jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to solve this?
&lt;/h2&gt;

&lt;p&gt;We will perform a series of steps to optimize the above pipeline. Let’s start.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parent-Child Pipelines Architecture
&lt;/h3&gt;

&lt;p&gt;With this approach, you will create a child pipeline, meaning a separate CI/CD file, only for that particular project. Move the relevant code into that project’s &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;. Below is the example for &lt;code&gt;project-a&lt;/code&gt;, and similarly, it can be replicated for &lt;code&gt;project-b&lt;/code&gt; and &lt;code&gt;project-c&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;project-a/.gitlab-ci.yml&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;

&lt;span class="na"&gt;build-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;test-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;deploy-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, link the child pipeline to the parent as below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root .gitlab-ci.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;

&lt;span class="na"&gt;trigger-project-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-a/.gitlab-ci.yml&lt;/span&gt;

&lt;span class="na"&gt;trigger-project-b&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-b/.gitlab-ci.yml&lt;/span&gt;

&lt;span class="na"&gt;trigger-project-c&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-c/.gitlab-ci.yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this simple refactor, the pipeline structure becomes more manageable:&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%2Fq40xaqqhzsqfp66amd4k.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%2Fq40xaqqhzsqfp66amd4k.png" alt="Screenshot after implementing Parent-child architecture" width="800" height="318"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use rules: changes
&lt;/h3&gt;

&lt;p&gt;To scope job execution to project-level changes, we can modify the pipeline to trigger jobs only when changes are made to specific projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root .gitlab-ci.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;

&lt;span class="na"&gt;trigger-project-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-a/.gitlab-ci.yml&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;changes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;project-a/**/*&lt;/span&gt;

&lt;span class="na"&gt;trigger-project-b&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-b/.gitlab-ci.yml&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;changes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;project-b/**/*&lt;/span&gt;

&lt;span class="na"&gt;trigger-project-c&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;triggers&lt;/span&gt;
  &lt;span class="na"&gt;trigger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;project-c/.gitlab-ci.yml&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;changes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;project-c/**/*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see duplicate pipelines running (a commit to a branch triggering the pipeline twice), you can add the following rule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;trigger-project-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;if '$CI_PIPELINE_SOURCE == "merge_request_event"'&lt;/span&gt;
      &lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;never&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&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%2Fkus2neb9zm7sbni5bkpr.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%2Fkus2neb9zm7sbni5bkpr.png" alt="Screenshot after implementing rules:changes" width="800" height="123"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use YAML Anchors:
&lt;/h3&gt;

&lt;p&gt;YAML anchors allow for the reuse of common configuration blocks, increasing reusability and reducing redundancy, especially when targeting multiple environments like dev, QA, staging, and prod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;project-a/.gitlab-ci.yml:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;.base-build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;node:22-alpine&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cd project-a&lt;/span&gt;

&lt;span class="na"&gt;build-a-dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.base-build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ENV = "dev"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;// build steps for dev&lt;/span&gt;

&lt;span class="na"&gt;build-a-qa&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.base-build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ENV = "qa"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;// build steps for qa&lt;/span&gt;

&lt;span class="na"&gt;build-a-staging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.base-build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ENV = "staging"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;// build steps for staging&lt;/span&gt;

&lt;span class="na"&gt;build-a-prod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.base-build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ENV = "prod"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;// build steps for prod&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to reuse only specific blocks of an anchor, you can use &lt;code&gt;!reference&lt;/code&gt; as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;build-a-dev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!reference&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;.base-build&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;before_script&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;export ENV = "dev"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;// build steps for dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using needs for Proper Job Chaining
&lt;/h3&gt;

&lt;p&gt;We can create dependencies between jobs using &lt;code&gt;needs&lt;/code&gt;, ensuring proper execution order.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;build-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;test-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;build-a&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;deploy-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&lt;/span&gt;
  &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test-a&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48acv0ufm86g4bcdgrf8.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%2F48acv0ufm86g4bcdgrf8.png" alt="Screenshot after implementing needs" width="800" height="291"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Parallel Job Execution
&lt;/h3&gt;

&lt;p&gt;To execute multiple jobs in parallel, for example, if there’s a check stage before the build stage, with a check-a job performing static code analysis, lint checks, etc., you can configure it as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;check&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;check-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check&lt;/span&gt;
  &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;build-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;test-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;build-a&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;

&lt;span class="na"&gt;deploy-a&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="na"&gt;needs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;test-a&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&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%2Fsrk1n5zxcv37k16qvwac.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%2Fsrk1n5zxcv37k16qvwac.png" alt="Screenshot for parallel execution" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;You can find the source code here: &lt;a href="https://gitlab.com/iChintanSoni/learning-ci-cd/" rel="noopener noreferrer"&gt;https://gitlab.com/iChintanSoni/learning-ci-cd/&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Optimizing CI/CD pipelines in a monorepo setup can significantly enhance the efficiency, readability, and maintainability of your projects. By adopting best practices such as using parent-child pipeline architecture, applying rules: changes, leveraging YAML anchors, and strategically utilizing needs for job chaining, you can create a more robust and scalable pipeline.&lt;/p&gt;

&lt;p&gt;These techniques not only help in minimizing unnecessary job executions but also streamline the overall development workflow, making it easier to manage complex projects. By implementing these best practices, you ensure that your CI/CD processes are both efficient and adaptable to the evolving needs of your monorepo.&lt;/p&gt;

&lt;p&gt;I hope this guide helps you in refining your GitLab CI/CD pipelines. If you have any questions or additional tips, feel free to share them in the comments below. Happy coding!&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>cicd</category>
      <category>pipeline</category>
    </item>
    <item>
      <title>Streamlining Database Migrations: From Basic to Ultra Pro Max Approach</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Fri, 22 Dec 2023 07:11:31 +0000</pubDate>
      <link>https://dev.to/ichintansoni/streamlining-database-migrations-from-basic-to-ultra-pro-max-approach-34e</link>
      <guid>https://dev.to/ichintansoni/streamlining-database-migrations-from-basic-to-ultra-pro-max-approach-34e</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the ever-evolving landscape of database management, effective migration strategies can significantly impact project timelines and productivity. Having encountered the need for migrating a substantial amount of data from Dynamo DB to RDS PgSQL DB through the AppSync framework, I embarked on a journey to optimize the process. Through trial and error, I discovered methods that not only saved time but also enhanced data integrity.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Tasked with migrating 4.8L records from Dynamo DB to RDS PgSQL DB using AppSync, the initial approach involved fetching records recursively in batches of 1000 and then iterating over the array to insert them into PgSQL one by one. However, this proved to be time-consuming, taking approximately 1.5 hours for 15K records, means around 48 hours in total. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolution
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Batched Insert Operation&lt;/strong&gt;&lt;br&gt;
To improve efficiency, I introduced batching with a size of 1000 records. By collecting promises of insert operations into an array and executing them simultaneously using &lt;code&gt;await Promise.all()&lt;/code&gt;, the time required was reduced to 36 hours. Though an improvement, the risk of data loss remained low, contingent on any constraint violations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Bulk Insert Statement&lt;/strong&gt;&lt;br&gt;
The next level involved rewriting the insert statement to support bulk insert. This approach utilized only one database connection to insert all 1000 records at once, cutting the time down to 18 hours. However, the drawback was that if a single record failed insertion, the entire batch was skipped, posing a higher risk of data loss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Ultra Pro Max Approach&lt;/strong&gt;&lt;br&gt;
Seeking the optimal solution, I implemented a unique strategy. By making calls to AppSync with pagination of 1000, I set up a local PgSQL database environment and synchronized all 4.8L records in just 1.5 hours. Subsequently, I exported the records into a CSV file using PGAdmin (warning: massive file size!) and imported it into the remote PgSQL instance. Surprisingly, the entire process, including data insertion, took less than 2 hours, showcasing the power of import/export features.&lt;/p&gt;

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

&lt;p&gt;The moral of this migration tale is clear: leveraging the import/export features of databases can drastically reduce migration times and mitigate the risk of data loss. The journey from a basic iterative approach to an Ultra Pro Max strategy highlights the importance of exploring various techniques to find the most efficient solution for your specific migration needs.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>database</category>
      <category>dynamodb</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Arrow Functions vs. Regular Functions in JavaScript: A Comprehensive Guide</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Wed, 22 Nov 2023 13:43:01 +0000</pubDate>
      <link>https://dev.to/ichintansoni/arrow-functions-vs-regular-functions-in-javascript-a-comprehensive-guide-4dpi</link>
      <guid>https://dev.to/ichintansoni/arrow-functions-vs-regular-functions-in-javascript-a-comprehensive-guide-4dpi</guid>
      <description>&lt;p&gt;In the realm of JavaScript, two primary types of functions reign supreme: arrow functions and regular functions. While both serve the purpose of encapsulating reusable code blocks, they exhibit distinct characteristics that influence their usage and impact on the overall programming flow. Understanding these differences is crucial for JavaScript developers to make informed decisions and craft efficient, maintainable code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arrow Function Syntax: A Concise Approach
&lt;/h2&gt;

&lt;p&gt;Arrow functions, also known as lambda expressions, are a concise and expressive way to define functions in JavaScript. Introduced in ES6 (ECMAScript 2015), they offer a shorter and more elegant syntax compared to regular functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Regular function&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Arrow function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;square&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Regular Function Syntax: The Traditional Way
&lt;/h2&gt;

&lt;p&gt;Regular functions, the classic approach to defining functions in JavaScript, have been around since the language's inception. They employ a more explicit syntax, encompassing the function keyword, parameters, and a block of code enclosed in curly braces.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&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;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&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;
  
  
  Key Differences: Unveiling the Distinctions
&lt;/h2&gt;

&lt;p&gt;Beyond their syntactical differences, arrow functions and regular functions diverge in several aspects, each with its own implications for code structure and behavior.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;this&lt;/code&gt; &lt;strong&gt;Binding:&lt;/strong&gt; Regular functions have their own &lt;code&gt;this&lt;/code&gt; binding, which refers to the execution context of the function. This value can change depending on how the function is invoked. Arrow functions, on the other hand, inherit their &lt;code&gt;this&lt;/code&gt; binding from the surrounding scope, ensuring consistent behaviour regardless of invocation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Arguments Object:&lt;/strong&gt; Regular functions have access to an &lt;code&gt;arguments&lt;/code&gt; object, an array-like collection of the function's arguments. Arrow functions do not have this object directly available, but they can still access arguments using the rest parameter syntax (e.g., &lt;code&gt;(...args) =&amp;gt; {...}&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Constructor Usage:&lt;/strong&gt; Regular functions can be used as constructors to create new objects. Arrow functions, however, are not constructors and cannot be invoked with the &lt;code&gt;new&lt;/code&gt; keyword. This distinction stems from their different &lt;code&gt;this&lt;/code&gt; binding behavior.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conciseness and Readability:&lt;/strong&gt; Arrow functions often lead to more concise and readable code, especially for simple functions. Their shorter syntax reduces boilerplate and improves code readability. However, for more complex functions with multiple statements, regular functions may provide better clarity.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Choosing the Right Tool for the Job
&lt;/h2&gt;

&lt;p&gt;The decision between using an arrow function or a regular function depends on the specific context and requirements of the code. Arrow functions are well-suited for short, concise functions, especially within callbacks or nested functions. Regular functions, with their explicit syntax and constructor capabilities, remain valuable for more complex scenarios.&lt;/p&gt;

&lt;p&gt;In summary, understanding the differences between arrow functions and regular functions empowers JavaScript developers to make informed choices, enhancing the maintainability and efficiency of their code. By carefully considering the syntax, &lt;code&gt;this&lt;/code&gt; binding, arguments access, constructor usage, and conciseness trade-offs, developers can select the most appropriate function type for each task, ensuring clear, well-structured code that aligns with the specific needs of the project.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Creating Custom Hooks in React: Enhancing Component Reusability with Audio Playback</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Wed, 15 Nov 2023 10:27:01 +0000</pubDate>
      <link>https://dev.to/ichintansoni/creating-custom-hooks-in-react-enhancing-component-reusability-with-audio-playback-39mh</link>
      <guid>https://dev.to/ichintansoni/creating-custom-hooks-in-react-enhancing-component-reusability-with-audio-playback-39mh</guid>
      <description>&lt;p&gt;React's custom hooks are a powerful tool for encapsulating reusable logic and state management within functional components. They allow developers to extract common patterns into reusable functions, promoting code modularity and enhancing component maintainability. In this article, we'll explore the concept of custom hooks and delve into the creation of an audio hook for playing sounds in React applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demystifying Custom Hooks
&lt;/h2&gt;

&lt;p&gt;Custom hooks are essentially functions that start with the prefix "use" and encapsulate reusable logic for React components. They provide a structured approach to sharing common functionalities across components, enhancing code organization and maintainability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an Audio Hook for Sound Playback
&lt;/h2&gt;

&lt;p&gt;To illustrate the power of custom hooks, let's create an audio hook for playing sounds in React applications. This hook will handle creating audio elements, managing playback behavior, and providing methods for playing, pausing, and resuming sounds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;useAudio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;audio&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Audio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;loop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &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;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;play&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;play&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;pause&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&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;isPlaying&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;audio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paused&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;isPlaying&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;pause&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;useAudio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This custom hook takes an audio source URL as a parameter and returns an object containing three methods: play, pause, and resume. These methods can be used to control the playback of the sound.&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizing the Audio Hook in Components
&lt;/h2&gt;

&lt;p&gt;To use the audio hook in a component, simply import it and call it with the desired audio source URL. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;useAudio&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./useAudio&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;MyComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;play&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isPlaying&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useAudio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;Is&lt;/span&gt; &lt;span class="na"&gt;Playing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isPlaying&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;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;play&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;Play&lt;/span&gt; &lt;span class="nx"&gt;Sound&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;pause&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;Pause&lt;/span&gt; &lt;span class="nx"&gt;Sound&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This component utilizes the useAudio hook to create an audio element for the specified sound source. It then provides buttons to control the playback using the play, pause, and resume methods provided by the hook.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of Custom Hooks
&lt;/h2&gt;

&lt;p&gt;Custom hooks offer several advantages for building React applications:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Reusability:&lt;/strong&gt; Custom hooks encapsulate reusable logic, allowing developers to share common functionalities across components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability:&lt;/strong&gt; By extracting logic into hooks, code becomes more organized and easier to maintain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulation:&lt;/strong&gt; Hooks promote encapsulation, keeping component logic separate and reducing code complexity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Management:&lt;/strong&gt; Custom hooks can manage state efficiently, simplifying stateful logic within functional components.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Custom hooks are a valuable addition to React's arsenal, enabling developers to create reusable and maintainable components. By encapsulating logic into hooks, developers can enhance code organization, improve maintainability, and promote a more structured approach to building React applications.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>audio</category>
    </item>
    <item>
      <title>Using React.memo to optimize your React applications</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Fri, 10 Nov 2023 10:25:17 +0000</pubDate>
      <link>https://dev.to/ichintansoni/using-reactmemo-to-optimize-your-react-applications-577a</link>
      <guid>https://dev.to/ichintansoni/using-reactmemo-to-optimize-your-react-applications-577a</guid>
      <description>&lt;p&gt;React.memo is a higher-order component (HOC) that can be used to wrap a component and memoize its rendered output. This means that React will only re-render the component if its props change. This can be useful for preventing unnecessary re-renders and improving the performance of your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use React.memo
&lt;/h2&gt;

&lt;p&gt;React.memo should be used for components that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are pure components, meaning that they always return the same output for the same props and state.&lt;/li&gt;
&lt;li&gt;Are frequently re-rendered, even when their props haven't changed.&lt;/li&gt;
&lt;li&gt;Have expensive rendering logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to use React.memo
&lt;/h2&gt;

&lt;p&gt;To use React.memo, simply wrap your component in the React.memo() HOC. The React.memo() function takes a single argument, which is the component to be memoized. It returns a new memoized component, which can then be rendered in your application.&lt;/p&gt;

&lt;p&gt;For example, the following code shows how to use React.memo to memoize a pure component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;memo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;MyMemoizedComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;world&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyMemoizedComponent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, whenever the MyMemoizedComponent component is rendered, React will check if the props have changed. If the props haven't changed, React will reuse the memoized output from the previous render. Otherwise, React will re-render the component and generate a new memoized output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example usage
&lt;/h2&gt;

&lt;p&gt;The following example shows how to use React.memo to optimize a list of items that is frequently re-rendered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;memo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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;MyList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;items&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;/ul&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setItems&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Item 3&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyList&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the MyList component is memoized, so it will only re-render if the items prop changes. This can lead to significant performance improvements, especially if the MyList component is rendered frequently.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for using React.memo
&lt;/h2&gt;

&lt;p&gt;Here are a few tips for using React.memo effectively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only use React.memo for pure components.&lt;/li&gt;
&lt;li&gt;Be careful when memoizing components that use props as callbacks. Make sure that the same callback function instance is provided between renders.&lt;/li&gt;
&lt;li&gt;Use profiling to measure the performance gains of memoizing a component.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>ReactJS + Docker : Getting started</title>
      <dc:creator>Chintan Soni</dc:creator>
      <pubDate>Thu, 02 Nov 2023 11:33:44 +0000</pubDate>
      <link>https://dev.to/ichintansoni/reactjs-docker-getting-started-4306</link>
      <guid>https://dev.to/ichintansoni/reactjs-docker-getting-started-4306</guid>
      <description>&lt;p&gt;ReactJS is a popular JavaScript library for building user interfaces. Docker is a containerization platform that allows you to package and deploy your applications in a consistent and portable way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use Docker with ReactJS?
&lt;/h2&gt;

&lt;p&gt;There are several benefits to using Docker with ReactJS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Docker ensures that your ReactJS application is run in the same environment on every machine. This can help to reduce errors and make it easier to deploy your application to production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portability:&lt;/strong&gt; Docker images can be run on any platform that has Docker installed. This makes it easy to deploy your ReactJS application to different environments, such as your local machine, a development server, or a production server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Docker makes it easy to scale your ReactJS application by running multiple instances of the application in containers. This can be useful for handling high traffic loads or for running different versions of your application in parallel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;First, let's create a React App. To do this, open terminal and hit command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app my-app --template typescript
cd my-app
code .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will open your React project in vscode. You can run and check your project using command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a build of your react project using command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see a build folder getting generated in project root directory that we are going to use later.&lt;/p&gt;

&lt;p&gt;Next, let's install &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; on your machine. Once you have installed Docker, you can create a Dockerfile for your ReactJS application.&lt;/p&gt;

&lt;p&gt;A Dockerfile is a text file that contains instructions for building a Docker image. The Dockerfile for a ReactJS application will typically include the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;From:&lt;/strong&gt; Specify the base image to use for your image. For a ReactJS application, you will typically use the node base image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workdir:&lt;/strong&gt; Set the working directory for your container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy:&lt;/strong&gt; Copy the files from your ReactJS application directory into the container.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run:&lt;/strong&gt; Run the &lt;code&gt;npm install&lt;/code&gt; commands to install the dependencies and build your ReactJS application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expose:&lt;/strong&gt; Expose the port that your ReactJS application is running on.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CMD:&lt;/strong&gt; Specifies the instruction to be executed when Docker container starts.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you have created a Dockerfile for your ReactJS application, you can build a Docker image using the docker build command.&lt;/p&gt;

&lt;p&gt;To run the Docker image, you can use the docker run command. The docker run command will start a new container from the Docker image.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Let's create a file named &lt;code&gt;Dockerfile&lt;/code&gt; (yes, without file extension) and paste the below code in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:20-alpine

WORKDIR /app

COPY build/ .

RUN npm install -g serve

EXPOSE 3000

CMD ["serve", "-s"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To build a Docker image from this Dockerfile, you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t my-app .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: For the above command to execute properly, make sure Docker Desktop is running, else it would throw an error like: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To run the Docker image, you can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 3000:3000 my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!!! You should be able to access your react app using &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus Tips:
&lt;/h2&gt;

&lt;p&gt;For deflating Docker Image size:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always use alpine as base image (node:20-alpine), as it is very small in size&lt;/li&gt;
&lt;li&gt;Always build frontend applications outside of Docker environment and then package the output build folder into Docker instead of copying all the files into Docker and then running npm &lt;code&gt;run install&lt;/code&gt; and &lt;code&gt;npm run build&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>typescript</category>
      <category>react</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
